123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- from sympy.core.backend import symbols, Matrix, atan, zeros
- from sympy.simplify.simplify import simplify
- from sympy.physics.mechanics import (dynamicsymbols, Particle, Point,
- ReferenceFrame, SymbolicSystem)
- from sympy.testing.pytest import raises
- # This class is going to be tested using a simple pendulum set up in x and y
- # coordinates
- x, y, u, v, lam = dynamicsymbols('x y u v lambda')
- m, l, g = symbols('m l g')
- # Set up the different forms the equations can take
- # [1] Explicit form where the kinematics and dynamics are combined
- # x' = F(x, t, r, p)
- #
- # [2] Implicit form where the kinematics and dynamics are combined
- # M(x, p) x' = F(x, t, r, p)
- #
- # [3] Implicit form where the kinematics and dynamics are separate
- # M(q, p) u' = F(q, u, t, r, p)
- # q' = G(q, u, t, r, p)
- dyn_implicit_mat = Matrix([[1, 0, -x/m],
- [0, 1, -y/m],
- [0, 0, l**2/m]])
- dyn_implicit_rhs = Matrix([0, 0, u**2 + v**2 - g*y])
- comb_implicit_mat = Matrix([[1, 0, 0, 0, 0],
- [0, 1, 0, 0, 0],
- [0, 0, 1, 0, -x/m],
- [0, 0, 0, 1, -y/m],
- [0, 0, 0, 0, l**2/m]])
- comb_implicit_rhs = Matrix([u, v, 0, 0, u**2 + v**2 - g*y])
- kin_explicit_rhs = Matrix([u, v])
- comb_explicit_rhs = comb_implicit_mat.LUsolve(comb_implicit_rhs)
- # Set up a body and load to pass into the system
- theta = atan(x/y)
- N = ReferenceFrame('N')
- A = N.orientnew('A', 'Axis', [theta, N.z])
- O = Point('O')
- P = O.locatenew('P', l * A.x)
- Pa = Particle('Pa', P, m)
- bodies = [Pa]
- loads = [(P, g * m * N.x)]
- # Set up some output equations to be given to SymbolicSystem
- # Change to make these fit the pendulum
- PE = symbols("PE")
- out_eqns = {PE: m*g*(l+y)}
- # Set up remaining arguments that can be passed to SymbolicSystem
- alg_con = [2]
- alg_con_full = [4]
- coordinates = (x, y, lam)
- speeds = (u, v)
- states = (x, y, u, v, lam)
- coord_idxs = (0, 1)
- speed_idxs = (2, 3)
- def test_form_1():
- symsystem1 = SymbolicSystem(states, comb_explicit_rhs,
- alg_con=alg_con_full, output_eqns=out_eqns,
- coord_idxs=coord_idxs, speed_idxs=speed_idxs,
- bodies=bodies, loads=loads)
- assert symsystem1.coordinates == Matrix([x, y])
- assert symsystem1.speeds == Matrix([u, v])
- assert symsystem1.states == Matrix([x, y, u, v, lam])
- assert symsystem1.alg_con == [4]
- inter = comb_explicit_rhs
- assert simplify(symsystem1.comb_explicit_rhs - inter) == zeros(5, 1)
- assert set(symsystem1.dynamic_symbols()) == {y, v, lam, u, x}
- assert type(symsystem1.dynamic_symbols()) == tuple
- assert set(symsystem1.constant_symbols()) == {l, g, m}
- assert type(symsystem1.constant_symbols()) == tuple
- assert symsystem1.output_eqns == out_eqns
- assert symsystem1.bodies == (Pa,)
- assert symsystem1.loads == ((P, g * m * N.x),)
- def test_form_2():
- symsystem2 = SymbolicSystem(coordinates, comb_implicit_rhs, speeds=speeds,
- mass_matrix=comb_implicit_mat,
- alg_con=alg_con_full, output_eqns=out_eqns,
- bodies=bodies, loads=loads)
- assert symsystem2.coordinates == Matrix([x, y, lam])
- assert symsystem2.speeds == Matrix([u, v])
- assert symsystem2.states == Matrix([x, y, lam, u, v])
- assert symsystem2.alg_con == [4]
- inter = comb_implicit_rhs
- assert simplify(symsystem2.comb_implicit_rhs - inter) == zeros(5, 1)
- assert simplify(symsystem2.comb_implicit_mat-comb_implicit_mat) == zeros(5)
- assert set(symsystem2.dynamic_symbols()) == {y, v, lam, u, x}
- assert type(symsystem2.dynamic_symbols()) == tuple
- assert set(symsystem2.constant_symbols()) == {l, g, m}
- assert type(symsystem2.constant_symbols()) == tuple
- inter = comb_explicit_rhs
- symsystem2.compute_explicit_form()
- assert simplify(symsystem2.comb_explicit_rhs - inter) == zeros(5, 1)
- assert symsystem2.output_eqns == out_eqns
- assert symsystem2.bodies == (Pa,)
- assert symsystem2.loads == ((P, g * m * N.x),)
- def test_form_3():
- symsystem3 = SymbolicSystem(states, dyn_implicit_rhs,
- mass_matrix=dyn_implicit_mat,
- coordinate_derivatives=kin_explicit_rhs,
- alg_con=alg_con, coord_idxs=coord_idxs,
- speed_idxs=speed_idxs, bodies=bodies,
- loads=loads)
- assert symsystem3.coordinates == Matrix([x, y])
- assert symsystem3.speeds == Matrix([u, v])
- assert symsystem3.states == Matrix([x, y, u, v, lam])
- assert symsystem3.alg_con == [4]
- inter1 = kin_explicit_rhs
- inter2 = dyn_implicit_rhs
- assert simplify(symsystem3.kin_explicit_rhs - inter1) == zeros(2, 1)
- assert simplify(symsystem3.dyn_implicit_mat - dyn_implicit_mat) == zeros(3)
- assert simplify(symsystem3.dyn_implicit_rhs - inter2) == zeros(3, 1)
- inter = comb_implicit_rhs
- assert simplify(symsystem3.comb_implicit_rhs - inter) == zeros(5, 1)
- assert simplify(symsystem3.comb_implicit_mat-comb_implicit_mat) == zeros(5)
- inter = comb_explicit_rhs
- symsystem3.compute_explicit_form()
- assert simplify(symsystem3.comb_explicit_rhs - inter) == zeros(5, 1)
- assert set(symsystem3.dynamic_symbols()) == {y, v, lam, u, x}
- assert type(symsystem3.dynamic_symbols()) == tuple
- assert set(symsystem3.constant_symbols()) == {l, g, m}
- assert type(symsystem3.constant_symbols()) == tuple
- assert symsystem3.output_eqns == {}
- assert symsystem3.bodies == (Pa,)
- assert symsystem3.loads == ((P, g * m * N.x),)
- def test_property_attributes():
- symsystem = SymbolicSystem(states, comb_explicit_rhs,
- alg_con=alg_con_full, output_eqns=out_eqns,
- coord_idxs=coord_idxs, speed_idxs=speed_idxs,
- bodies=bodies, loads=loads)
- with raises(AttributeError):
- symsystem.bodies = 42
- with raises(AttributeError):
- symsystem.coordinates = 42
- with raises(AttributeError):
- symsystem.dyn_implicit_rhs = 42
- with raises(AttributeError):
- symsystem.comb_implicit_rhs = 42
- with raises(AttributeError):
- symsystem.loads = 42
- with raises(AttributeError):
- symsystem.dyn_implicit_mat = 42
- with raises(AttributeError):
- symsystem.comb_implicit_mat = 42
- with raises(AttributeError):
- symsystem.kin_explicit_rhs = 42
- with raises(AttributeError):
- symsystem.comb_explicit_rhs = 42
- with raises(AttributeError):
- symsystem.speeds = 42
- with raises(AttributeError):
- symsystem.states = 42
- with raises(AttributeError):
- symsystem.alg_con = 42
- def test_not_specified_errors():
- """This test will cover errors that arise from trying to access attributes
- that were not specified upon object creation or were specified on creation
- and the user tries to recalculate them."""
- # Trying to access form 2 when form 1 given
- # Trying to access form 3 when form 2 given
- symsystem1 = SymbolicSystem(states, comb_explicit_rhs)
- with raises(AttributeError):
- symsystem1.comb_implicit_mat
- with raises(AttributeError):
- symsystem1.comb_implicit_rhs
- with raises(AttributeError):
- symsystem1.dyn_implicit_mat
- with raises(AttributeError):
- symsystem1.dyn_implicit_rhs
- with raises(AttributeError):
- symsystem1.kin_explicit_rhs
- with raises(AttributeError):
- symsystem1.compute_explicit_form()
- symsystem2 = SymbolicSystem(coordinates, comb_implicit_rhs, speeds=speeds,
- mass_matrix=comb_implicit_mat)
- with raises(AttributeError):
- symsystem2.dyn_implicit_mat
- with raises(AttributeError):
- symsystem2.dyn_implicit_rhs
- with raises(AttributeError):
- symsystem2.kin_explicit_rhs
- # Attribute error when trying to access coordinates and speeds when only the
- # states were given.
- with raises(AttributeError):
- symsystem1.coordinates
- with raises(AttributeError):
- symsystem1.speeds
- # Attribute error when trying to access bodies and loads when they are not
- # given
- with raises(AttributeError):
- symsystem1.bodies
- with raises(AttributeError):
- symsystem1.loads
- # Attribute error when trying to access comb_explicit_rhs before it was
- # calculated
- with raises(AttributeError):
- symsystem2.comb_explicit_rhs
|