def is_conservative(field): """ Checks if a field is conservative. Parameters ========== field : Vector The field to check for conservative property Examples ======== >>> from sympy.physics.vector import ReferenceFrame >>> from sympy.physics.vector import is_conservative >>> R = ReferenceFrame('R') >>> is_conservative(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z) True >>> is_conservative(R[2] * R.y) False """ #Field is conservative irrespective of frame #Take the first frame in the result of the #separate method of Vector if field == Vector(0): return True frame = list(field.separate())[0] return curl(field, frame).simplify() == Vector(0)
def test_pinjoint(): P = Body('P') C = Body('C') l, m = symbols('l m') theta, omega = dynamicsymbols('theta_J, omega_J') Pj = PinJoint('J', P, C) assert Pj.name == 'J' assert Pj.parent == P assert Pj.child == C assert Pj.coordinates == [theta] assert Pj.speeds == [omega] assert Pj.kdes == [omega - theta.diff(t)] assert Pj.parent_axis == P.frame.x assert Pj.child_point.pos_from(C.masscenter) == Vector(0) assert Pj.parent_point.pos_from(P.masscenter) == Vector(0) assert Pj.parent_point.pos_from(Pj._child_point) == Vector(0) assert C.masscenter.pos_from(P.masscenter) == Vector(0) assert Pj.__str__() == 'PinJoint: J parent: P child: C' P1 = Body('P1') C1 = Body('C1') J1 = PinJoint('J1', P1, C1, parent_joint_pos=l*P1.frame.x, child_joint_pos=m*C1.frame.y, parent_axis=P1.frame.z) assert J1._parent_axis == P1.frame.z assert J1._child_point.pos_from(C1.masscenter) == m * C1.frame.y assert J1._parent_point.pos_from(P1.masscenter) == l * P1.frame.x assert J1._parent_point.pos_from(J1._child_point) == Vector(0) assert (P1.masscenter.pos_from(C1.masscenter) == -l*P1.frame.x + m*C1.frame.y)
def test_slidingjoint(): _, _, P, C = _generate_body() x, v = dynamicsymbols('x_S, v_S') S = PrismaticJoint('S', P, C) assert S.name == 'S' assert S.parent == P assert S.child == C assert S.coordinates == [x] assert S.speeds == [v] assert S.kdes == [v - x.diff(t)] assert S.parent_axis == P.frame.x assert S.child_axis == C.frame.x assert S.child_point.pos_from(C.masscenter) == Vector(0) assert S.parent_point.pos_from(P.masscenter) == Vector(0) assert S.parent_point.pos_from(S.child_point) == -x * P.frame.x assert P.masscenter.pos_from(C.masscenter) == -x * P.frame.x assert C.masscenter.vel(P.frame) == v * P.frame.x assert P.ang_vel_in(C) == 0 assert C.ang_vel_in(P) == 0 assert S.__str__() == 'PrismaticJoint: S parent: P child: C' N, A, P, C = _generate_body() l, m = symbols('l m') S = PrismaticJoint('S', P, C, parent_joint_pos=l * P.frame.x, child_joint_pos=m * C.frame.y, parent_axis=P.frame.z) assert S.parent_axis == P.frame.z assert S.child_point.pos_from(C.masscenter) == m * C.frame.y assert S.parent_point.pos_from(P.masscenter) == l * P.frame.x assert S.parent_point.pos_from(S.child_point) == -x * P.frame.z assert P.masscenter.pos_from(C.masscenter) == -l * N.x - x * N.z + m * A.y assert C.masscenter.vel(P.frame) == v * P.frame.z assert C.ang_vel_in(P) == 0 assert P.ang_vel_in(C) == 0 _, _, P, C = _generate_body() S = PrismaticJoint('S', P, C, parent_joint_pos=l * P.frame.z, child_joint_pos=m * C.frame.x, parent_axis=P.frame.z) assert S.parent_axis == P.frame.z assert S.child_point.pos_from(C.masscenter) == m * C.frame.x assert S.parent_point.pos_from(P.masscenter) == l * P.frame.z assert S.parent_point.pos_from(S.child_point) == -x * P.frame.z assert P.masscenter.pos_from( C.masscenter) == (-l - x) * P.frame.z + m * C.frame.x assert C.masscenter.vel(P.frame) == v * P.frame.z assert C.ang_vel_in(P) == 0 assert P.ang_vel_in(C) == 0
def _locate_joint_pos(self, body, joint_pos): if joint_pos is None: joint_pos = Vector(0) if not isinstance(joint_pos, Vector): raise ValueError('Joint Position must be supplied as Vector.') if not joint_pos.dt(body.frame) == 0: msg = ('Position Vector cannot be time-varying when viewed from ' 'the associated body.') raise ValueError(msg) point_name = self._name + '_' + body.name + '_joint' return body.masscenter.locatenew(point_name, joint_pos)
def test_curl(): assert curl(Vector(0), R) == Vector(0) assert curl(R.x, R) == Vector(0) assert curl(2*R[1]**2*R.y, R) == Vector(0) assert curl(R[0]*R[1]*R.z, R) == R[0]*R.x - R[1]*R.y assert curl(R[0]*R[1]*R[2] * (R.x+R.y+R.z), R) == \ (-R[0]*R[1] + R[0]*R[2])*R.x + (R[0]*R[1] - R[1]*R[2])*R.y + \ (-R[0]*R[2] + R[1]*R[2])*R.z assert curl(2*R[0]**2*R.y, R) == 4*R[0]*R.z assert curl(P[0]**2*R.x + P.y, R) == \ - 2*(R[0]*cos(q) + R[1]*sin(q))*sin(q)*R.z assert curl(P[0]*R.y, P) == cos(q)*P.z
def test_reference_frame(): raises(TypeError, lambda: ReferenceFrame(0)) raises(TypeError, lambda: ReferenceFrame("N", 0)) raises(ValueError, lambda: ReferenceFrame("N", [0, 1])) raises(TypeError, lambda: ReferenceFrame("N", [0, 1, 2])) raises(TypeError, lambda: ReferenceFrame("N", ["a", "b", "c"], 0)) raises(ValueError, lambda: ReferenceFrame("N", ["a", "b", "c"], [0, 1])) raises(TypeError, lambda: ReferenceFrame("N", ["a", "b", "c"], [0, 1, 2])) raises(TypeError, lambda: ReferenceFrame("N", ["a", "b", "c"], ["a", "b", "c"], 0)) raises( ValueError, lambda: ReferenceFrame("N", ["a", "b", "c"], ["a", "b", "c"], [0, 1]), ) raises( TypeError, lambda: ReferenceFrame("N", ["a", "b", "c"], ["a", "b", "c"], [0, 1, 2]), ) N = ReferenceFrame("N") assert N[0] == CoordinateSym("N_x", N, 0) assert N[1] == CoordinateSym("N_y", N, 1) assert N[2] == CoordinateSym("N_z", N, 2) raises(ValueError, lambda: N[3]) N = ReferenceFrame("N", ["a", "b", "c"]) assert N["a"] == N.x assert N["b"] == N.y assert N["c"] == N.z raises(ValueError, lambda: N["d"]) assert str(N) == "N" A = ReferenceFrame("A") B = ReferenceFrame("B") q0, q1, q2, q3 = symbols("q0 q1 q2 q3") raises(TypeError, lambda: A.orient(B, "DCM", 0)) raises(TypeError, lambda: B.orient(N, "Space", [q1, q2, q3], "222")) raises(TypeError, lambda: B.orient(N, "Axis", [q1, N.x + 2 * N.y], "222")) raises(TypeError, lambda: B.orient(N, "Axis", q1)) raises(TypeError, lambda: B.orient(N, "Axis", [q1])) raises(TypeError, lambda: B.orient(N, "Quaternion", [q0, q1, q2, q3], "222")) raises(TypeError, lambda: B.orient(N, "Quaternion", q0)) raises(TypeError, lambda: B.orient(N, "Quaternion", [q0, q1, q2])) raises(NotImplementedError, lambda: B.orient(N, "Foo", [q0, q1, q2])) raises(TypeError, lambda: B.orient(N, "Body", [q1, q2], "232")) raises(TypeError, lambda: B.orient(N, "Space", [q1, q2], "232")) N.set_ang_acc(B, 0) assert N.ang_acc_in(B) == Vector(0) N.set_ang_vel(B, 0) assert N.ang_vel_in(B) == Vector(0)
def test_reference_frame(): raises(TypeError, lambda: ReferenceFrame(0)) raises(TypeError, lambda: ReferenceFrame('N', 0)) raises(ValueError, lambda: ReferenceFrame('N', [0, 1])) raises(TypeError, lambda: ReferenceFrame('N', [0, 1, 2])) raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], 0)) raises(ValueError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], [0, 1])) raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], [0, 1, 2])) raises(TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], ['a', 'b', 'c'], 0)) raises( ValueError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], ['a', 'b', 'c'], [0, 1])) raises( TypeError, lambda: ReferenceFrame('N', ['a', 'b', 'c'], ['a', 'b', 'c'], [0, 1, 2])) N = ReferenceFrame('N') assert N[0] == CoordinateSym('N_x', N, 0) assert N[1] == CoordinateSym('N_y', N, 1) assert N[2] == CoordinateSym('N_z', N, 2) raises(ValueError, lambda: N[3]) N = ReferenceFrame('N', ['a', 'b', 'c']) assert N['a'] == N.x assert N['b'] == N.y assert N['c'] == N.z raises(ValueError, lambda: N['d']) assert str(N) == 'N' A = ReferenceFrame('A') B = ReferenceFrame('B') q0, q1, q2, q3 = symbols('q0 q1 q2 q3') raises(TypeError, lambda: A.orient(B, 'DCM', 0)) raises(TypeError, lambda: B.orient(N, 'Space', [q1, q2, q3], '222')) raises(TypeError, lambda: B.orient(N, 'Axis', [q1, N.x + 2 * N.y], '222')) raises(TypeError, lambda: B.orient(N, 'Axis', q1)) raises(IndexError, lambda: B.orient(N, 'Axis', [q1])) raises(TypeError, lambda: B.orient(N, 'Quaternion', [q0, q1, q2, q3], '222')) raises(TypeError, lambda: B.orient(N, 'Quaternion', q0)) raises(TypeError, lambda: B.orient(N, 'Quaternion', [q0, q1, q2])) raises(NotImplementedError, lambda: B.orient(N, 'Foo', [q0, q1, q2])) raises(TypeError, lambda: B.orient(N, 'Body', [q1, q2], '232')) raises(TypeError, lambda: B.orient(N, 'Space', [q1, q2], '232')) N.set_ang_acc(B, 0) assert N.ang_acc_in(B) == Vector(0) N.set_ang_vel(B, 0) assert N.ang_vel_in(B) == Vector(0)
def is_solenoidal(field): """ Checks if a field is solenoidal. Parameters ========== field : Vector The field to check for solenoidal property Examples ======== >>> from sympy.physics.vector import ReferenceFrame >>> from sympy.physics.vector import is_solenoidal >>> R = ReferenceFrame('R') >>> is_solenoidal(R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z) True >>> is_solenoidal(R[1] * R.y) False """ #Field is solenoidal irrespective of frame #Take the first frame in the result of the #separate method in Vector if field == Vector(0): return True frame = list(field.separate())[0] return divergence(field, frame).simplify() == S(0)
def gradient(scalar, frame): """ Returns the vector gradient of a scalar field computed wrt the coordinate symbols of the given frame. Parameters ========== scalar : sympifiable The scalar field to take the gradient of frame : ReferenceFrame The frame to calculate the gradient in Examples ======== >>> from sympy.physics.vector import ReferenceFrame >>> from sympy.physics.vector import gradient >>> R = ReferenceFrame('R') >>> s1 = R[0]*R[1]*R[2] >>> gradient(s1, R) R_y*R_z*R.x + R_x*R_z*R.y + R_x*R_y*R.z >>> s2 = 5*R[0]**2*R[2] >>> gradient(s2, R) 10*R_x*R_z*R.x + 5*R_x**2*R.z """ _check_frame(frame) outvec = Vector(0) scalar = express(scalar, frame, variables=True) for i, x in enumerate(frame): outvec += diff(scalar, frame[i]) * x return outvec
def _orient_frames(self): self.child.frame.orient_axis(self.parent.frame, self.parent_axis, 0) angle, axis = self._alignment_rotation(self.parent_axis, self.child_axis) odd_multiple_pi = False if angle % pi == 0: if (angle / pi).is_odd: odd_multiple_pi = True with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) if axis != Vector(0) or odd_multiple_pi: if odd_multiple_pi: axis = cross(self.parent_axis, self._generate_vector()) int_frame = ReferenceFrame('int_frame') int_frame.orient_axis(self.child.frame, self.child_axis, 0) int_frame.orient_axis(self.parent.frame, axis, angle) self.child.frame.orient_axis(int_frame, self.parent_axis, self.coordinates[0]) else: self.child.frame.orient_axis(self.parent.frame, self.parent_axis, self.coordinates[0])
def eval_vec(vec): from sympy.physics.vector import Vector v = Vector(0) for frame_vectors in vec.args: for coeff, uv in zip(list(frame_vectors[0]), frame_vectors[1]): v += coeff.n() * uv return v
def angular_momentum(point, frame, *body): """Angular momentum of a system. Explanation =========== This function returns the angular momentum of a system of Particle's and/or RigidBody's. The angular momentum of such a system is equal to the vector sum of the angular momentum of its constituents. Consider a system, S, comprised of a rigid body, A, and a particle, P. The angular momentum of the system, H, is equal to the vector sum of the angular momentum of the particle, H1, and the angular momentum of the rigid body, H2, i.e. H = H1 + H2 Parameters ========== point : Point The point about which angular momentum of the system is desired. frame : ReferenceFrame The frame in which angular momentum is desired. body1, body2, body3... : Particle and/or RigidBody The body (or bodies) whose angular momentum is required. Examples ======== >>> from sympy.physics.mechanics import Point, Particle, ReferenceFrame >>> from sympy.physics.mechanics import RigidBody, outer, angular_momentum >>> N = ReferenceFrame('N') >>> O = Point('O') >>> O.set_vel(N, 0 * N.x) >>> P = O.locatenew('P', 1 * N.x) >>> P.set_vel(N, 10 * N.x) >>> Pa = Particle('Pa', P, 1) >>> Ac = O.locatenew('Ac', 2 * N.y) >>> Ac.set_vel(N, 5 * N.y) >>> a = ReferenceFrame('a') >>> a.set_ang_vel(N, 10 * N.z) >>> I = outer(N.z, N.z) >>> A = RigidBody('A', Ac, a, 20, (I, Ac)) >>> angular_momentum(O, N, Pa, A) 10*N.z """ if not isinstance(frame, ReferenceFrame): raise TypeError('Please enter a valid ReferenceFrame') if not isinstance(point, Point): raise TypeError('Please specify a valid Point') else: angular_momentum_sys = Vector(0) for e in body: if isinstance(e, (RigidBody, Particle)): angular_momentum_sys += e.angular_momentum(point, frame) else: raise TypeError('*body must have only Particle or RigidBody') return angular_momentum_sys
def curl(vect, frame): """ Returns the curl of a vector field computed wrt the coordinate symbols of the given frame. Parameters ========== vect : Vector The vector operand frame : ReferenceFrame The reference frame to calculate the curl in Examples ======== >>> from sympy.physics.vector import ReferenceFrame >>> from sympy.physics.vector import curl >>> R = ReferenceFrame('R') >>> v1 = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z >>> curl(v1, R) 0 >>> v2 = R[0]*R[1]*R[2]*R.x >>> curl(v2, R) R_x*R_y*R.y - R_x*R_z*R.z """ _check_vector(vect) if vect == 0: return Vector(0) vect = express(vect, frame, variables=True) #A mechanical approach to avoid looping overheads vectx = vect.dot(frame.x) vecty = vect.dot(frame.y) vectz = vect.dot(frame.z) outvec = Vector(0) outvec += (diff(vectz, frame[1]) - diff(vecty, frame[2])) * frame.x outvec += (diff(vectx, frame[2]) - diff(vectz, frame[0])) * frame.y outvec += (diff(vecty, frame[0]) - diff(vectx, frame[1])) * frame.z return outvec
def test_Vector(): assert A.x != A.y assert A.y != A.z assert A.z != A.x assert A.x + 0 == A.x v1 = x*A.x + y*A.y + z*A.z v2 = x**2*A.x + y**2*A.y + z**2*A.z v3 = v1 + v2 v4 = v1 - v2 assert isinstance(v1, Vector) assert dot(v1, A.x) == x assert dot(v1, A.y) == y assert dot(v1, A.z) == z assert isinstance(v2, Vector) assert dot(v2, A.x) == x**2 assert dot(v2, A.y) == y**2 assert dot(v2, A.z) == z**2 assert isinstance(v3, Vector) # We probably shouldn't be using simplify in dot... assert dot(v3, A.x) == x**2 + x assert dot(v3, A.y) == y**2 + y assert dot(v3, A.z) == z**2 + z assert isinstance(v4, Vector) # We probably shouldn't be using simplify in dot... assert dot(v4, A.x) == x - x**2 assert dot(v4, A.y) == y - y**2 assert dot(v4, A.z) == z - z**2 assert v1.to_matrix(A) == Matrix([[x], [y], [z]]) q = symbols('q') B = A.orientnew('B', 'Axis', (q, A.x)) assert v1.to_matrix(B) == Matrix([[x], [ y * cos(q) + z * sin(q)], [-y * sin(q) + z * cos(q)]]) #Test the separate method B = ReferenceFrame('B') v5 = x*A.x + y*A.y + z*B.z assert Vector(0).separate() == {} assert v1.separate() == {A: v1} assert v5.separate() == {A: x*A.x + y*A.y, B: z*B.z} #Test the free_symbols property v6 = x*A.x + y*A.y + z*A.z assert v6.free_symbols(A) == {x,y,z} raises(TypeError, lambda: v3.applyfunc(v1))
def test_gradient(): a = Symbol('a') assert gradient(0, R) == Vector(0) assert gradient(R[0], R) == R.x assert gradient(R[0]*R[1]*R[2], R) == \ R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z assert gradient(2*R[0]**2, R) == 4*R[0]*R.x assert gradient(a*sin(R[1])/R[0], R) == \ - a*sin(R[1])/R[0]**2*R.x + a*cos(R[1])/R[0]*R.y assert gradient(P[0]*P[1], R) == \ (-R[0]*sin(2*q) + R[1]*cos(2*q))*R.x + \ (R[0]*cos(2*q) + R[1]*sin(2*q))*R.y assert gradient(P[0]*R[2], P) == P[2]*P.x + P[0]*P.z
def test_divergence(): assert divergence(Vector(0), R) == S(0) assert divergence(R.x, R) == S(0) assert divergence(R[0]**2*R.x, R) == 2*R[0] assert divergence(R[0]*R[1]*R[2] * (R.x+R.y+R.z), R) == \ R[0]*R[1] + R[0]*R[2] + R[1]*R[2] assert divergence((1/(R[0]*R[1]*R[2])) * (R.x+R.y+R.z), R) == \ -1/(R[0]*R[1]*R[2]**2) - 1/(R[0]*R[1]**2*R[2]) - \ 1/(R[0]**2*R[1]*R[2]) v = P[0]*P.x + P[1]*P.y + P[2]*P.z assert divergence(v, P) == 3 assert divergence(v, R).simplify() == 3 assert divergence(P[0]*R.x + R[0]*P.x, R) == 2*cos(q)
def linear_momentum(frame, *body): """Linear momentum of the system. Explanation =========== This function returns the linear momentum of a system of Particle's and/or RigidBody's. The linear momentum of a system is equal to the vector sum of the linear momentum of its constituents. Consider a system, S, comprised of a rigid body, A, and a particle, P. The linear momentum of the system, L, is equal to the vector sum of the linear momentum of the particle, L1, and the linear momentum of the rigid body, L2, i.e. L = L1 + L2 Parameters ========== frame : ReferenceFrame The frame in which linear momentum is desired. body1, body2, body3... : Particle and/or RigidBody The body (or bodies) whose linear momentum is required. Examples ======== >>> from sympy.physics.mechanics import Point, Particle, ReferenceFrame >>> from sympy.physics.mechanics import RigidBody, outer, linear_momentum >>> N = ReferenceFrame('N') >>> P = Point('P') >>> P.set_vel(N, 10 * N.x) >>> Pa = Particle('Pa', P, 1) >>> Ac = Point('Ac') >>> Ac.set_vel(N, 25 * N.y) >>> I = outer(N.x, N.x) >>> A = RigidBody('A', Ac, N, 20, (I, Ac)) >>> linear_momentum(N, A, Pa) 10*N.x + 500*N.y """ if not isinstance(frame, ReferenceFrame): raise TypeError('Please specify a valid ReferenceFrame') else: linear_momentum_sys = Vector(0) for e in body: if isinstance(e, (RigidBody, Particle)): linear_momentum_sys += e.linear_momentum(frame) else: raise TypeError('*body must have only Particle or RigidBody') return linear_momentum_sys
def scalar_potential(field, frame): """ Returns the scalar potential function of a field in a given frame (without the added integration constant). Parameters ========== field : Vector The vector field whose scalar potential function is to be calculated frame : ReferenceFrame The frame to do the calculation in Examples ======== >>> from sympy.physics.vector import ReferenceFrame >>> from sympy.physics.vector import scalar_potential, gradient >>> R = ReferenceFrame('R') >>> scalar_potential(R.z, R) == R[2] True >>> scalar_field = 2*R[0]**2*R[1]*R[2] >>> grad_field = gradient(scalar_field, R) >>> scalar_potential(grad_field, R) 2*R_x**2*R_y*R_z """ #Check whether field is conservative if not is_conservative(field): raise ValueError("Field is not conservative") if field == Vector(0): return S(0) #Express the field exntirely in frame #Subsitute coordinate variables also _check_frame(frame) field = express(field, frame, variables=True) #Make a list of dimensions of the frame dimensions = [x for x in frame] #Calculate scalar potential function temp_function = integrate(field.dot(dimensions[0]), frame[0]) for i, dim in enumerate(dimensions[1:]): partial_diff = diff(temp_function, frame[i + 1]) partial_diff = field.dot(dim) - partial_diff temp_function += integrate(partial_diff, frame[i + 1]) return temp_function
def test_gradient(): a = Symbol("a") assert gradient(0, R) == Vector(0) assert gradient(R[0], R) == R.x assert (gradient(R[0] * R[1] * R[2], R) == R[1] * R[2] * R.x + R[0] * R[2] * R.y + R[0] * R[1] * R.z) assert gradient(2 * R[0]**2, R) == 4 * R[0] * R.x assert (gradient(a * sin(R[1]) / R[0], R) == -a * sin(R[1]) / R[0]**2 * R.x + a * cos(R[1]) / R[0] * R.y) assert (gradient(P[0] * P[1], R) == ((-R[0] * sin(q) + R[1] * cos(q)) * cos(q) - (R[0] * cos(q) + R[1] * sin(q)) * sin(q)) * R.x + ((-R[0] * sin(q) + R[1] * cos(q)) * sin(q) + (R[0] * cos(q) + R[1] * sin(q)) * cos(q)) * R.y) assert gradient(P[0] * R[2], P) == P[2] * P.x + P[0] * P.z
def center_of_mass(point, *bodies): """ Returns the position vector from the given point to the center of mass of the given bodies(particles or rigidbodies). Example ======= >>> from sympy import symbols, S >>> from sympy.physics.vector import Point >>> from sympy.physics.mechanics import Particle, ReferenceFrame, RigidBody, outer >>> from sympy.physics.mechanics.functions import center_of_mass >>> a = ReferenceFrame('a') >>> m = symbols('m', real=True) >>> p1 = Particle('p1', Point('p1_pt'), S(1)) >>> p2 = Particle('p2', Point('p2_pt'), S(2)) >>> p3 = Particle('p3', Point('p3_pt'), S(3)) >>> p4 = Particle('p4', Point('p4_pt'), m) >>> b_f = ReferenceFrame('b_f') >>> b_cm = Point('b_cm') >>> mb = symbols('mb') >>> b = RigidBody('b', b_cm, b_f, mb, (outer(b_f.x, b_f.x), b_cm)) >>> p2.point.set_pos(p1.point, a.x) >>> p3.point.set_pos(p1.point, a.x + a.y) >>> p4.point.set_pos(p1.point, a.y) >>> b.masscenter.set_pos(p1.point, a.y + a.z) >>> point_o=Point('o') >>> point_o.set_pos(p1.point, center_of_mass(p1.point, p1, p2, p3, p4, b)) >>> expr = 5/(m + mb + 6)*a.x + (m + mb + 3)/(m + mb + 6)*a.y + mb/(m + mb + 6)*a.z >>> point_o.pos_from(p1.point) 5/(m + mb + 6)*a.x + (m + mb + 3)/(m + mb + 6)*a.y + mb/(m + mb + 6)*a.z """ if not bodies: raise TypeError( "No bodies(instances of Particle or Rigidbody) were passed.") total_mass = 0 vec = Vector(0) for i in bodies: total_mass += i.mass masscenter = getattr(i, 'masscenter', None) if masscenter is None: masscenter = i.point vec += i.mass * masscenter.pos_from(point) return vec / total_mass
def center_of_mass(point, *bodies): """ Returns the position vector from the given point to the center of mass of the given bodies(particles or rigidbodies). Example ======= >>> from sympy import symbols, S >>> from sympy.physics.vector import Point >>> from sympy.physics.mechanics import Particle, ReferenceFrame >>> from sympy.physics.mechanics.functions import center_of_mass >>> frame_a=ReferenceFrame('a') >>> mu=symbols('mu', real=True) >>> p1=Particle('p1', Point('p1_pt'), S(1)) >>> p2=Particle('p2', Point('p2_pt'), S(2)) >>> p3=Particle('p3', Point('p3_pt'), S(3)) >>> p4=Particle('p4', Point('p4_pt'), S(4)) >>> p5=Particle('p5', Point('p5_pt'), S(5)) >>> p6=Particle('p6', Point('p6_pt'), S(6)) >>> p7=Particle('p7', Point('p7_pt'), S(7)) >>> p8=Particle('p8', Point('p8_pt'), mu) >>> p2.point.set_pos(p1.point, frame_a.x) >>> p3.point.set_pos(p1.point, frame_a.x+frame_a.y) >>> p4.point.set_pos(p1.point, frame_a.y) >>> p5.point.set_pos(p1.point, frame_a.z) >>> p6.point.set_pos(p1.point, frame_a.x+frame_a.z) >>> p7.point.set_pos(p1.point, frame_a.x+frame_a.y+frame_a.z) >>> p8.point.set_pos(p1.point, frame_a.y+frame_a.z) >>> point_so=Point('so') >>> point_so.set_pos(p1.point, center_of_mass(p1.point, p1, p2, p3, p4, p5, p6, p7, p8)) >>> point_so.pos_from(p1.point) 18/(mu + 28)*a.x + (mu + 14)/(mu + 28)*a.y + (mu + 18)/(mu + 28)*a.z """ if not bodies: raise TypeError("No bodies(instances of Particle or Rigidbody) were passed.") total_mass = 0 vec = Vector(0) for i in bodies: total_mass += i.mass try: vec += i.mass*i.masscenter.pos_from(point) except AttributeError: vec += i.mass*i.point.pos_from(point) return vec/total_mass
def _set_orientation(self): #Helper method for `orient_axis()` self.child.frame.orient_axis(self.parent.frame, self.parent_axis, 0) angle, axis = self._alignment_rotation(self.parent_axis, self.child_axis) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) if axis != Vector(0) or angle == pi: if angle == pi: axis = self._generate_vector() int_frame = ReferenceFrame('int_frame') int_frame.orient_axis(self.child.frame, self.child_axis, 0) int_frame.orient_axis(self.parent.frame, axis, angle) return int_frame return self.parent.frame
def _orient_frames(self): self.child.frame.orient_axis(self.parent.frame, self.parent_axis, 0) angle, axis = self._alignment_rotation(self.parent_axis, self.child_axis) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) if axis != Vector(0) or angle == pi: if angle == pi: axis = cross(self.parent_axis, self._generate_vector()) int_frame = ReferenceFrame('int_frame') int_frame.orient_axis(self.child.frame, self.child_axis, 0) int_frame.orient_axis(self.parent.frame, axis, angle) self.child.frame.orient_axis(int_frame, self.parent_axis, self.coordinates[0]) else: self.child.frame.orient_axis(self.parent.frame, self.parent_axis, self.coordinates[0])
THETA_1, THETA_2 = dynamicsymbols('theta_1 theta_2') L_1, L_2 = symbols('l_1 l_2', positive=True) # Referenciais # Referencial Parado B0 = ReferenceFrame('B0') B1 = ReferenceFrame('B1') # Referencial móvel: theta_1 em relação a B0.z B1.orient(B0, 'Axis', [THETA_1, B0.z]) B2 = ReferenceFrame('B2') # Referencial móvel: theta_2 em relação a B1.z B2.orient(B1, 'Axis', [THETA_2, B1.z]) # Vetores Posição entre os Pontos # Vetor Nulo B0_R_OA = Vector(0) # Vetor que liga os pontos A e B expresso no referencial móvel B1 B1_R_AB = L_1 * B1.x # Vetor que liga os pontos B e C expresso no referencial móvel B2 B2_R_BC = L_2 * B2.x # Cinemática do ponto A em relação ao referencial B0 R_A = B0_R_OA V_A = time_derivative(R_A, B0) A_A = time_derivative(V_A, B0) # Cinemática do ponto B em relação ao referencial B0 R_B = R_A + B1_R_AB.express(B0) V_B = time_derivative(R_B, B0) A_B = time_derivative(V_B, B0)
def test_operator_match(): """Test that the output of dot, cross, outer functions match operator behavior. """ A = ReferenceFrame('A') v = A.x + A.y d = v | v zerov = Vector(0) zerod = Dyadic(0) # dot products assert d & d == dot(d, d) assert d & zerod == dot(d, zerod) assert zerod & d == dot(zerod, d) assert d & v == dot(d, v) assert v & d == dot(v, d) assert d & zerov == dot(d, zerov) assert zerov & d == dot(zerov, d) raises(TypeError, lambda: dot(d, S.Zero)) raises(TypeError, lambda: dot(S.Zero, d)) raises(TypeError, lambda: dot(d, 0)) raises(TypeError, lambda: dot(0, d)) assert v & v == dot(v, v) assert v & zerov == dot(v, zerov) assert zerov & v == dot(zerov, v) raises(TypeError, lambda: dot(v, S.Zero)) raises(TypeError, lambda: dot(S.Zero, v)) raises(TypeError, lambda: dot(v, 0)) raises(TypeError, lambda: dot(0, v)) # cross products raises(TypeError, lambda: cross(d, d)) raises(TypeError, lambda: cross(d, zerod)) raises(TypeError, lambda: cross(zerod, d)) assert d ^ v == cross(d, v) assert v ^ d == cross(v, d) assert d ^ zerov == cross(d, zerov) assert zerov ^ d == cross(zerov, d) assert zerov ^ d == cross(zerov, d) raises(TypeError, lambda: cross(d, S.Zero)) raises(TypeError, lambda: cross(S.Zero, d)) raises(TypeError, lambda: cross(d, 0)) raises(TypeError, lambda: cross(0, d)) assert v ^ v == cross(v, v) assert v ^ zerov == cross(v, zerov) assert zerov ^ v == cross(zerov, v) raises(TypeError, lambda: cross(v, S.Zero)) raises(TypeError, lambda: cross(S.Zero, v)) raises(TypeError, lambda: cross(v, 0)) raises(TypeError, lambda: cross(0, v)) # outer products raises(TypeError, lambda: outer(d, d)) raises(TypeError, lambda: outer(d, zerod)) raises(TypeError, lambda: outer(zerod, d)) raises(TypeError, lambda: outer(d, v)) raises(TypeError, lambda: outer(v, d)) raises(TypeError, lambda: outer(d, zerov)) raises(TypeError, lambda: outer(zerov, d)) raises(TypeError, lambda: outer(zerov, d)) raises(TypeError, lambda: outer(d, S.Zero)) raises(TypeError, lambda: outer(S.Zero, d)) raises(TypeError, lambda: outer(d, 0)) raises(TypeError, lambda: outer(0, d)) assert v | v == outer(v, v) assert v | zerov == outer(v, zerov) assert zerov | v == outer(zerov, v) raises(TypeError, lambda: outer(v, S.Zero)) raises(TypeError, lambda: outer(S.Zero, v)) raises(TypeError, lambda: outer(v, 0)) raises(TypeError, lambda: outer(0, v))
def test_express(): assert express(Vector(0), N) == Vector(0) assert express(S.Zero, N) is S.Zero assert express(A.x, C) == cos(q3) * C.x + sin(q3) * C.z assert express(A.y, C) == sin(q2)*sin(q3)*C.x + cos(q2)*C.y - \ sin(q2)*cos(q3)*C.z assert express(A.z, C) == -sin(q3)*cos(q2)*C.x + sin(q2)*C.y + \ cos(q2)*cos(q3)*C.z assert express(A.x, N) == cos(q1) * N.x + sin(q1) * N.y assert express(A.y, N) == -sin(q1) * N.x + cos(q1) * N.y assert express(A.z, N) == N.z assert express(A.x, A) == A.x assert express(A.y, A) == A.y assert express(A.z, A) == A.z assert express(A.x, B) == B.x assert express(A.y, B) == cos(q2) * B.y - sin(q2) * B.z assert express(A.z, B) == sin(q2) * B.y + cos(q2) * B.z assert express(A.x, C) == cos(q3) * C.x + sin(q3) * C.z assert express(A.y, C) == sin(q2)*sin(q3)*C.x + cos(q2)*C.y - \ sin(q2)*cos(q3)*C.z assert express(A.z, C) == -sin(q3)*cos(q2)*C.x + sin(q2)*C.y + \ cos(q2)*cos(q3)*C.z # Check to make sure UnitVectors get converted properly assert express(N.x, N) == N.x assert express(N.y, N) == N.y assert express(N.z, N) == N.z assert express(N.x, A) == (cos(q1) * A.x - sin(q1) * A.y) assert express(N.y, A) == (sin(q1) * A.x + cos(q1) * A.y) assert express(N.z, A) == A.z assert express(N.x, B) == (cos(q1) * B.x - sin(q1) * cos(q2) * B.y + sin(q1) * sin(q2) * B.z) assert express(N.y, B) == (sin(q1) * B.x + cos(q1) * cos(q2) * B.y - sin(q2) * cos(q1) * B.z) assert express(N.z, B) == (sin(q2) * B.y + cos(q2) * B.z) assert express( N.x, C) == ((cos(q1) * cos(q3) - sin(q1) * sin(q2) * sin(q3)) * C.x - sin(q1) * cos(q2) * C.y + (sin(q3) * cos(q1) + sin(q1) * sin(q2) * cos(q3)) * C.z) assert express( N.y, C) == ((sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1)) * C.x + cos(q1) * cos(q2) * C.y + (sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)) * C.z) assert express(N.z, C) == (-sin(q3) * cos(q2) * C.x + sin(q2) * C.y + cos(q2) * cos(q3) * C.z) assert express(A.x, N) == (cos(q1) * N.x + sin(q1) * N.y) assert express(A.y, N) == (-sin(q1) * N.x + cos(q1) * N.y) assert express(A.z, N) == N.z assert express(A.x, A) == A.x assert express(A.y, A) == A.y assert express(A.z, A) == A.z assert express(A.x, B) == B.x assert express(A.y, B) == (cos(q2) * B.y - sin(q2) * B.z) assert express(A.z, B) == (sin(q2) * B.y + cos(q2) * B.z) assert express(A.x, C) == (cos(q3) * C.x + sin(q3) * C.z) assert express(A.y, C) == (sin(q2) * sin(q3) * C.x + cos(q2) * C.y - sin(q2) * cos(q3) * C.z) assert express(A.z, C) == (-sin(q3) * cos(q2) * C.x + sin(q2) * C.y + cos(q2) * cos(q3) * C.z) assert express(B.x, N) == (cos(q1) * N.x + sin(q1) * N.y) assert express(B.y, N) == (-sin(q1) * cos(q2) * N.x + cos(q1) * cos(q2) * N.y + sin(q2) * N.z) assert express(B.z, N) == (sin(q1) * sin(q2) * N.x - sin(q2) * cos(q1) * N.y + cos(q2) * N.z) assert express(B.x, A) == A.x assert express(B.y, A) == (cos(q2) * A.y + sin(q2) * A.z) assert express(B.z, A) == (-sin(q2) * A.y + cos(q2) * A.z) assert express(B.x, B) == B.x assert express(B.y, B) == B.y assert express(B.z, B) == B.z assert express(B.x, C) == (cos(q3) * C.x + sin(q3) * C.z) assert express(B.y, C) == C.y assert express(B.z, C) == (-sin(q3) * C.x + cos(q3) * C.z) assert express( C.x, N) == ((cos(q1) * cos(q3) - sin(q1) * sin(q2) * sin(q3)) * N.x + (sin(q1) * cos(q3) + sin(q2) * sin(q3) * cos(q1)) * N.y - sin(q3) * cos(q2) * N.z) assert express(C.y, N) == (-sin(q1) * cos(q2) * N.x + cos(q1) * cos(q2) * N.y + sin(q2) * N.z) assert express( C.z, N) == ((sin(q3) * cos(q1) + sin(q1) * sin(q2) * cos(q3)) * N.x + (sin(q1) * sin(q3) - sin(q2) * cos(q1) * cos(q3)) * N.y + cos(q2) * cos(q3) * N.z) assert express(C.x, A) == (cos(q3) * A.x + sin(q2) * sin(q3) * A.y - sin(q3) * cos(q2) * A.z) assert express(C.y, A) == (cos(q2) * A.y + sin(q2) * A.z) assert express(C.z, A) == (sin(q3) * A.x - sin(q2) * cos(q3) * A.y + cos(q2) * cos(q3) * A.z) assert express(C.x, B) == (cos(q3) * B.x - sin(q3) * B.z) assert express(C.y, B) == B.y assert express(C.z, B) == (sin(q3) * B.x + cos(q3) * B.z) assert express(C.x, C) == C.x assert express(C.y, C) == C.y assert express(C.z, C) == C.z == (C.z) # Check to make sure Vectors get converted back to UnitVectors assert N.x == express((cos(q1) * A.x - sin(q1) * A.y), N) assert N.y == express((sin(q1) * A.x + cos(q1) * A.y), N) assert N.x == express( (cos(q1) * B.x - sin(q1) * cos(q2) * B.y + sin(q1) * sin(q2) * B.z), N) assert N.y == express( (sin(q1) * B.x + cos(q1) * cos(q2) * B.y - sin(q2) * cos(q1) * B.z), N) assert N.z == express((sin(q2) * B.y + cos(q2) * B.z), N) """ These don't really test our code, they instead test the auto simplification (or lack thereof) of SymPy. assert N.x == express(( (cos(q1)*cos(q3)-sin(q1)*sin(q2)*sin(q3))*C.x - sin(q1)*cos(q2)*C.y + (sin(q3)*cos(q1)+sin(q1)*sin(q2)*cos(q3))*C.z), N) assert N.y == express(( (sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1))*C.x + cos(q1)*cos(q2)*C.y + (sin(q1)*sin(q3) - sin(q2)*cos(q1)*cos(q3))*C.z), N) assert N.z == express((-sin(q3)*cos(q2)*C.x + sin(q2)*C.y + cos(q2)*cos(q3)*C.z), N) """ assert A.x == express((cos(q1) * N.x + sin(q1) * N.y), A) assert A.y == express((-sin(q1) * N.x + cos(q1) * N.y), A) assert A.y == express((cos(q2) * B.y - sin(q2) * B.z), A) assert A.z == express((sin(q2) * B.y + cos(q2) * B.z), A) assert A.x == express((cos(q3) * C.x + sin(q3) * C.z), A) # Tripsimp messes up here too. #print express((sin(q2)*sin(q3)*C.x + cos(q2)*C.y - # sin(q2)*cos(q3)*C.z), A) assert A.y == express( (sin(q2) * sin(q3) * C.x + cos(q2) * C.y - sin(q2) * cos(q3) * C.z), A) assert A.z == express( (-sin(q3) * cos(q2) * C.x + sin(q2) * C.y + cos(q2) * cos(q3) * C.z), A) assert B.x == express((cos(q1) * N.x + sin(q1) * N.y), B) assert B.y == express( (-sin(q1) * cos(q2) * N.x + cos(q1) * cos(q2) * N.y + sin(q2) * N.z), B) assert B.z == express( (sin(q1) * sin(q2) * N.x - sin(q2) * cos(q1) * N.y + cos(q2) * N.z), B) assert B.y == express((cos(q2) * A.y + sin(q2) * A.z), B) assert B.z == express((-sin(q2) * A.y + cos(q2) * A.z), B) assert B.x == express((cos(q3) * C.x + sin(q3) * C.z), B) assert B.z == express((-sin(q3) * C.x + cos(q3) * C.z), B) """ assert C.x == express(( (cos(q1)*cos(q3)-sin(q1)*sin(q2)*sin(q3))*N.x + (sin(q1)*cos(q3)+sin(q2)*sin(q3)*cos(q1))*N.y - sin(q3)*cos(q2)*N.z), C) assert C.y == express(( -sin(q1)*cos(q2)*N.x + cos(q1)*cos(q2)*N.y + sin(q2)*N.z), C) assert C.z == express(( (sin(q3)*cos(q1)+sin(q1)*sin(q2)*cos(q3))*N.x + (sin(q1)*sin(q3)-sin(q2)*cos(q1)*cos(q3))*N.y + cos(q2)*cos(q3)*N.z), C) """ assert C.x == express( (cos(q3) * A.x + sin(q2) * sin(q3) * A.y - sin(q3) * cos(q2) * A.z), C) assert C.y == express((cos(q2) * A.y + sin(q2) * A.z), C) assert C.z == express( (sin(q3) * A.x - sin(q2) * cos(q3) * A.y + cos(q2) * cos(q3) * A.z), C) assert C.x == express((cos(q3) * B.x - sin(q3) * B.z), C) assert C.z == express((sin(q3) * B.x + cos(q3) * B.z), C)
from sympy import solve # define euler angle symbols and reference frames ea = dynamicsymbols('α β γ') A = ReferenceFrame('A') A_1 = A.orientnew('A_1', 'axis', [ea[0], A.x]) A_2 = A_1.orientnew('A_2', 'axis', [ea[1], A_1.y]) B = A_2.orientnew('B', 'axis', [ea[2], A_2.z]) # display the rotation matrix C from frame A to frame B print('Rotation matrix C:') mprint(B.dcm(A)) # define angular velocity vector w = dynamicsymbols('ω_x ω_y ω_z') omega_A = sum((a * uv for a, uv in zip(w, A)), Vector(0)) omega_B = sum((a * uv for a, uv in zip(w, B)), Vector(0)) # display angular velocity vector omega print('\nangular velocity:') omega = B.ang_vel_in(A) print('ω = {}'.format(msprint(omega))) print('ω_A = {}'.format(msprint(omega.express(A)))) print('ω_B = {}'.format(msprint(omega.express(B)))) # solve for alpha, beta, gamma in terms of angular velocity components dea = [a.diff() for a in ea] for omega_fr, frame in [(omega_A, A), (omega_B, B)]: eqs = [dot(omega - omega_fr, uv) for uv in frame] soln = solve(eqs, dea) print('\nif angular velocity components are taken to be in frame '
def test_output_type(): A = ReferenceFrame('A') v = A.x + A.y d = v | v zerov = Vector(0) zerod = Dyadic(0) # dot products assert isinstance(d & d, Dyadic) assert isinstance(d & zerod, Dyadic) assert isinstance(zerod & d, Dyadic) assert isinstance(d & v, Vector) assert isinstance(v & d, Vector) assert isinstance(d & zerov, Vector) assert isinstance(zerov & d, Vector) raises(TypeError, lambda: d & S.Zero) raises(TypeError, lambda: S.Zero & d) raises(TypeError, lambda: d & 0) raises(TypeError, lambda: 0 & d) assert not isinstance(v & v, (Vector, Dyadic)) assert not isinstance(v & zerov, (Vector, Dyadic)) assert not isinstance(zerov & v, (Vector, Dyadic)) raises(TypeError, lambda: v & S.Zero) raises(TypeError, lambda: S.Zero & v) raises(TypeError, lambda: v & 0) raises(TypeError, lambda: 0 & v) # cross products raises(TypeError, lambda: d ^ d) raises(TypeError, lambda: d ^ zerod) raises(TypeError, lambda: zerod ^ d) assert isinstance(d ^ v, Dyadic) assert isinstance(v ^ d, Dyadic) assert isinstance(d ^ zerov, Dyadic) assert isinstance(zerov ^ d, Dyadic) assert isinstance(zerov ^ d, Dyadic) raises(TypeError, lambda: d ^ S.Zero) raises(TypeError, lambda: S.Zero ^ d) raises(TypeError, lambda: d ^ 0) raises(TypeError, lambda: 0 ^ d) assert isinstance(v ^ v, Vector) assert isinstance(v ^ zerov, Vector) assert isinstance(zerov ^ v, Vector) raises(TypeError, lambda: v ^ S.Zero) raises(TypeError, lambda: S.Zero ^ v) raises(TypeError, lambda: v ^ 0) raises(TypeError, lambda: 0 ^ v) # outer products raises(TypeError, lambda: d | d) raises(TypeError, lambda: d | zerod) raises(TypeError, lambda: zerod | d) raises(TypeError, lambda: d | v) raises(TypeError, lambda: v | d) raises(TypeError, lambda: d | zerov) raises(TypeError, lambda: zerov | d) raises(TypeError, lambda: zerov | d) raises(TypeError, lambda: d | S.Zero) raises(TypeError, lambda: S.Zero | d) raises(TypeError, lambda: d | 0) raises(TypeError, lambda: 0 | d) assert isinstance(v | v, Dyadic) assert isinstance(v | zerov, Dyadic) assert isinstance(zerov | v, Dyadic) raises(TypeError, lambda: v | S.Zero) raises(TypeError, lambda: S.Zero | v) raises(TypeError, lambda: v | 0) raises(TypeError, lambda: 0 | v)
l_1, l_2 = symbols('l_1 l_2', positive=True) # Referenciais B0 = ReferenceFrame('B0') # Referencial Parado B1 = ReferenceFrame('B1') B1.orient(B0, 'Axis', [theta_1, B0.y]) # Referencial móvel: theta_1 em relação a B0.y B2 = ReferenceFrame('B2') B2.orient(B1, 'Axis', [theta_2, B1.z]) # Referencial móvel: theta_2 em relação a B1.z B3 = ReferenceFrame('B3') B3.orient(B2, 'Axis', [theta_3, B2.z]) # Referencial móvel: theta_3 em relação a B2.z # Vetores Posição entre os Pontos B0_r_OA = Vector(0) # Vetor Nulo B2_r_AB = l_1 * B2.x # Vetor que liga os pontos A e B expresso no referencial móvel B2 B3_r_BC = l_2 * B3.x # Vetor que liga os pontos B e C expresso no referencial móvel B3 # Cinemática do ponto A em relação ao referencial B0 r_A = B0_r_OA v_A = time_derivative(r_A, B0) a_A = time_derivative(v_A, B0) # Cinemática do ponto B em relação ao referencial B0 r_B = r_A + B2_r_AB.express(B0) v_B = time_derivative(r_B, B0) a_B = time_derivative(v_B, B0) # Cinemática do ponto C em relação ao referencial B0 r_C = B3_r_BC.express(B0)