[docs]defis_conservative(field):""" Checks if a field is conservative. Paramaters ========== 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 Vectoriffield==Vector(0):returnTrueframe=list(field.separate())[0]returncurl(field,frame).simplify()==Vector(0)

[docs]defis_solenoidal(field):""" Checks if a field is solenoidal. Paramaters ========== 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 Vectoriffield==Vector(0):returnTrueframe=list(field.separate())[0]returndivergence(field,frame).simplify()==S(0)

[docs]defscalar_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 conservativeifnotis_conservative(field):raiseValueError("Field is not conservative")iffield==Vector(0):returnS(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 framedimensions=[xforxinframe]#Calculate scalar potential functiontemp_function=integrate(field.dot(dimensions[0]),frame[0])fori,diminenumerate(dimensions[1:]):partial_diff=diff(temp_function,frame[i+1])partial_diff=field.dot(dim)-partial_difftemp_function+=integrate(partial_diff,frame[i+1])returntemp_function

[docs]defscalar_potential_difference(field,frame,point1,point2,origin):""" Returns the scalar potential difference between two points in a certain frame, wrt a given field. If a scalar field is provided, its values at the two points are considered. If a conservative vector field is provided, the values of its scalar potential function at the two points are used. Returns (potential at position 2) - (potential at position 1) Parameters ========== field : Vector/sympyfiable The field to calculate wrt frame : ReferenceFrame The frame to do the calculations in point1 : Point The initial Point in given frame position2 : Point The second Point in the given frame origin : Point The Point to use as reference point for position vector calculation Examples ======== >>> from sympy.physics.vector import ReferenceFrame, Point >>> from sympy.physics.vector import scalar_potential_difference >>> R = ReferenceFrame('R') >>> O = Point('O') >>> P = O.locatenew('P', R[0]*R.x + R[1]*R.y + R[2]*R.z) >>> vectfield = 4*R[0]*R[1]*R.x + 2*R[0]**2*R.y >>> scalar_potential_difference(vectfield, R, O, P, O) 2*R_x**2*R_y >>> Q = O.locatenew('O', 3*R.x + R.y + 2*R.z) >>> scalar_potential_difference(vectfield, R, P, Q, O) -2*R_x**2*R_y + 18 """_check_frame(frame)ifisinstance(field,Vector):#Get the scalar potential functionscalar_fn=scalar_potential(field,frame)else:#Field is a scalarscalar_fn=field#Express positions in required frameposition1=express(point1.pos_from(origin),frame,variables=True)position2=express(point2.pos_from(origin),frame,variables=True)#Get the two positions as substitution dicts for coordinate variablessubs_dict1={}subs_dict2={}fori,xinenumerate(frame):subs_dict1[frame[i]]=x.dot(position1)subs_dict2[frame[i]]=x.dot(position2)returnscalar_fn.subs(subs_dict2)-scalar_fn.subs(subs_dict1)