Exemple #1
0
def generate_symbolic_model(T, U, tt, F, simplify=True, constraints=None, dissipation_function=0, **kwargs):
    """
    T:             kinetic energy
    U:             potential energy
    tt:            sequence of independent deflection variables ("theta")
    F:             external forces
    simplify:      determines whether the equations of motion should be simplified
                   (default=True)
    constraints:   None (default) or sequence of constraints (will introduce lagrange multipliers)

    dissipation_function:
                    Rayleigh dissipation function. Its Differential w.r.t. tthetadot is added to the systems equation

    kwargs: optional assumptions like 'real=True'

    :returns SymbolicModel instance mod. The equations are contained in mod.eqns
    """
    n = len(tt)

    for theta_i in tt:
        assert isinstance(theta_i, sp.Symbol)

    if constraints is None:
        constraints_flag = False
        # ensure well define calculations (jacobian of empty matrix would not be possible)
        constraints = [0]
    else:
        constraints_flag = True
    assert len(constraints) > 0
    constraints = sp.Matrix(constraints)
    assert constraints.shape[1] == 1
    nC = constraints.shape[0]
    jac_constraints = constraints.jacobian(tt)

    dissipation_function = sp.sympify(dissipation_function)
    assert isinstance(dissipation_function, sp.Expr)

    llmd = st.symb_vector("lambda_1:{}".format(nC + 1))

    F = sp.Matrix(F)

    if F.shape[0] == 1:
        # convert to column vector
        F = F.T
    if not F.shape == (n, 1):
        msg = "Vector of external forces has the wrong length. Should be " + \
              str(n) + " but is %i!" % F.shape[0]
        raise ValueError(msg)

    # introducing symbols for the derivatives
    tt = sp.Matrix(tt)
    ttd = st.time_deriv(tt, tt, **kwargs)
    ttdd = st.time_deriv(tt, tt, order=2, **kwargs)

    # Lagrange function
    L = T - U

    if not T.atoms().intersection(ttd) == set(ttd):
        raise ValueError('Not all velocity symbols do occur in T')

    # partial derivatives of L
    L_diff_tt = st.jac(L, tt)
    L_diff_ttd = st.jac(L, ttd)

    # prov_deriv_symbols = [ttd, ttdd]

    # time-depended_symbols
    tds = list(tt) + list(ttd)
    L_diff_ttd_dt = st.time_deriv(L_diff_ttd, tds, **kwargs)

    # constraints

    constraint_terms = list(llmd.T * jac_constraints)

    # lagrange equation 1st kind (which include 2nd kind as special case if constraints are empty)

    model_eq = sp.zeros(n, 1)
    for i in range(n):
        model_eq[i] = L_diff_ttd_dt[i] - L_diff_tt[i] - F[i] - constraint_terms[i]

    model_eq += st.gradient(dissipation_function, ttd).T
    # create object of model
    mod = SymbolicModel()  # model_eq, qs, f, D)
    mod.eqns = model_eq

    mod.extforce_list = F
    reduced_F = sp.Matrix([s for s in F if st.is_symbol(s)])
    mod.F = reduced_F
    mod.tau = reduced_F
    if constraints_flag:
        mod.llmd = llmd
        mod.constraints = constraints
    else:
        # omit fake constraint [0]
        mod.constraints = None
        mod.llmd = None

    # coordinates velocities and accelerations
    mod.tt = tt
    mod.ttd = ttd
    mod.ttdd = ttdd

    mod.qs = tt
    mod.qds = ttd
    mod.qdds = ttdd

    # also store kinetic and potential energy
    mod.T = T
    mod.U = U

    if simplify:
        mod.eqns.simplify()

    return mod
Exemple #2
0
def generate_symbolic_model(T, U, tt, F, simplify=True, **kwargs):
    """
    T:          kinetic energy
    U:          potential energy
    tt:         sequence of independent deflection variables ("theta")
    F:          external forces
    simplify:   determines whether the equations of motion should be simplified
                (default=True)

    kwargs: optional assumptions like 'real=True'
    """
    n = len(tt)

    for theta_i in tt:
        assert isinstance(theta_i, sp.Symbol)

    F = sp.Matrix(F)

    if F.shape[0] == 1:
        # convert to column vector
        F = F.T
    if not F.shape == (n, 1):
        msg = "Vector of external forces has the wrong length. Should be " + \
        str(n) + " but is %i!"  % F.shape[0]
        raise ValueError(msg)

    # introducing symbols for the derivatives
    tt = sp.Matrix(tt)
    ttd = st.time_deriv(tt, tt, **kwargs)
    ttdd = st.time_deriv(tt, tt, order=2, **kwargs)

    #Lagrange function
    L = T - U

    if not T.atoms().intersection(ttd) == set(ttd):
        raise ValueError('Not all velocity symbols do occur in T')

    # partial derivatives of L
    L_diff_tt = st.jac(L, tt)
    L_diff_ttd = st.jac(L, ttd)

    #prov_deriv_symbols = [ttd, ttdd]

    # time-depended_symbols
    tds = list(tt) + list(ttd)
    L_diff_ttd_dt = st.time_deriv(L_diff_ttd, tds, **kwargs)

    #lagrange equation 2nd kind
    model_eq = sp.zeros(n, 1)
    for i in range(n):
        model_eq[i] = L_diff_ttd_dt[i] - L_diff_tt[i] - F[i]

    # create object of model
    mod = SymbolicModel()  # model_eq, qs, f, D)
    mod.eqns = model_eq

    mod.extforce_list = F
    reduced_F = sp.Matrix([s for s in F if st.is_symbol(s)])
    mod.F = reduced_F
    mod.tau = reduced_F

    # coordinates velocities and accelerations
    mod.tt = tt
    mod.ttd = ttd
    mod.ttdd = ttdd

    mod.qs = tt
    mod.qds = ttd
    mod.qdds = ttdd

    # also store kinetic and potential energy
    mod.T = T
    mod.U = U

    if simplify:
        mod.eqns.simplify()

    return mod
Exemple #3
0
def generate_symbolic_model(T, U, tt, F, simplify=True, **kwargs):
    """
    T:          kinetic energy
    U:          potential energy
    tt:         sequence of independent deflection variables ("theta")
    F:          external forces
    simplify:   determines whether the equations of motion should be simplified
                (default=True)

    kwargs: optional assumptions like 'real=True'
    """
    n = len(tt)

    for theta_i in tt:
        assert isinstance(theta_i, sp.Symbol)

    F = sp.Matrix(F)

    if F.shape[0] == 1:
        # convert to column vector
        F = F.T
    if not F.shape == (n, 1):
        msg = "Vector of external forces has the wrong length. Should be " + \
        str(n) + " but is %i!"  % F.shape[0]
        raise ValueError(msg)


    # introducing symbols for the derivatives
    tt = sp.Matrix(tt)
    ttd = st.time_deriv(tt, tt, **kwargs)
    ttdd = st.time_deriv(tt, tt, order=2, **kwargs)

    #Lagrange function
    L = T - U

    if not T.atoms().intersection(ttd) == set(ttd):
        raise ValueError('Not all velocity symbols do occur in T')

    # partial derivatives of L
    L_diff_tt = st.jac(L, tt)
    L_diff_ttd = st.jac(L, ttd)

    #prov_deriv_symbols = [ttd, ttdd]

    # time-depended_symbols
    tds = list(tt) + list(ttd)
    L_diff_ttd_dt = st.time_deriv(L_diff_ttd, tds, **kwargs)

    #lagrange equation 2nd kind
    model_eq = sp.zeros(n, 1)
    for i in range(n):
        model_eq[i] = L_diff_ttd_dt[i] - L_diff_tt[i] - F[i]

    # create object of model
    mod = SymbolicModel()  # model_eq, qs, f, D)
    mod.eqns = model_eq

    mod.extforce_list = F
    reduced_F = sp.Matrix([s for s in F if st.is_symbol(s)])
    mod.F = reduced_F
    mod.tau = reduced_F

    # coordinates velocities and accelerations
    mod.tt = tt
    mod.ttd = ttd
    mod.ttdd = ttdd

    mod.qs = tt
    mod.qds = ttd
    mod.qdds = ttdd

    # also store kinetic and potential energy
    mod.T = T
    mod.U = U

    if simplify:
        mod.eqns.simplify()

    return mod
Exemple #4
0
def generate_model(T, U, qq, F, **kwargs):
    raise DeprecationWarning('generate_symbolic_model should be used')
    """
    T kinetic energy
    U potential energy
    q independend deflection variables
    F external forces
    D dissipation function
    """

    n = len(qq)

    # time variable
    t = sp.symbols('t')

    # symbolic Variables (to prevent Functions where we not want them)
    qs = []
    qds = []
    qdds = []

    if not kwargs:
        # assumptions for the symbols (facilitating the postprocessing)
        kwargs = {"real": True}

    for qi in qq:
        # ensure that the same Symbol for t is used
        assert qi.is_Function and qi.args == (t, )
        s = str(qi.func)

        qs.append(sp.Symbol(s, **kwargs))
        qds.append(sp.Symbol(s + "_d", **kwargs))
        qdds.append(sp.Symbol(s + "_dd", **kwargs))

    qs, qds, qdds = sp.Matrix(qs), sp.Matrix(qds), sp.Matrix(qdds)

    #derivative of configuration variables
    qd = qq.diff(t)
    qdd = qd.diff(t)

    #lagrange function
    L = T - U

    #substitute functions with symbols for partial derivatives

    #highest derivative first
    subslist = lzip(qdd, qdds) + lzip(qd, qds) + lzip(qq, qs)
    L = L.subs(subslist)

    # partial derivatives of L
    Ldq = st.jac(L, qs)
    Ldqd = st.jac(L, qds)

    # generalised external force
    f = sp.Matrix(F)

    # substitute symbols with functions for time derivative
    subslistrev = st.rev_tuple(subslist)
    Ldq = Ldq.subs(subslistrev)
    Ldqd = Ldqd.subs(subslistrev)
    Ldqd = Ldqd.diff(t)

    #lagrange equation 2nd kind
    model_eq = qq * 0
    for i in range(n):
        model_eq[i] = Ldqd[i] - Ldq[i] - f[i]

    # model equations with symbols
    model_eq = model_eq.subs(subslist)

    # create object of model
    model1 = SymbolicModel()  # model_eq, qs, f, D)
    model1.eqns = model_eq
    model1.qs = qs
    model1.extforce_list = f
    model1.tau = f

    model1.qds = qds
    model1.qdds = qdds

    # also store kinetic and potential energy
    model1.T = T
    model1.U = U

    # analyse the model

    return model1
Exemple #5
0
def generate_model(T, U, qq, F, **kwargs):
    raise DeprecationWarning('generate_symbolic_model should be used')
    """
    T kinetic energy
    U potential energy
    q independend deflection variables
    F external forces
    D dissipation function
    """

    n = len(qq)

    # time variable
    t = sp.symbols('t')

    # symbolic Variables (to prevent Functions where we not want them)
    qs = []
    qds = []
    qdds = []

    if not kwargs:
        # assumptions for the symbols (facilitating the postprocessing)
        kwargs ={"real": True}

    for qi in qq:
        # ensure that the same Symbol for t is used
        assert qi.is_Function and qi.args == (t,)
        s = str(qi.func)

        qs.append(sp.Symbol(s, **kwargs))
        qds.append(sp.Symbol(s + "_d",  **kwargs))
        qdds.append(sp.Symbol(s + "_dd",  **kwargs))

    qs, qds, qdds = sp.Matrix(qs), sp.Matrix(qds), sp.Matrix(qdds)

    #derivative of configuration variables
    qd = qq.diff(t)
    qdd = qd.diff(t)

    #lagrange function
    L = T - U

    #substitute functions with symbols for partial derivatives

    #highest derivative first
    subslist = lzip(qdd, qdds) + lzip(qd, qds) + lzip(qq, qs)
    L = L.subs(subslist)

    # partial derivatives of L
    Ldq = st.jac(L, qs)
    Ldqd = st.jac(L, qds)

    # generalised external force
    f = sp.Matrix(F)

    # substitute symbols with functions for time derivative
    subslistrev = st.rev_tuple(subslist)
    Ldq = Ldq.subs(subslistrev)
    Ldqd = Ldqd.subs(subslistrev)
    Ldqd = Ldqd.diff(t)

    #lagrange equation 2nd kind
    model_eq = qq * 0
    for i in range(n):
        model_eq[i] = Ldqd[i] - Ldq[i] - f[i]

    # model equations with symbols
    model_eq = model_eq.subs(subslist)

    # create object of model
    model1 = SymbolicModel()  # model_eq, qs, f, D)
    model1.eqns = model_eq
    model1.qs = qs
    model1.extforce_list = f
    model1.tau = f

    model1.qds = qds
    model1.qdds = qdds


    # also store kinetic and potential energy
    model1.T = T
    model1.U = U

    # analyse the model

    return model1