def test_creation_of_stateepocharray(): ''' Test the creation of an array of combined CartStateEpoch structures ''' # Create a single CartStateEpoch as in "test_creation_of_stateepoch" above x,y,z,xd,yd,zd,JD = (4.545057765534996E-01, 2.439514137005412E+00, 1.057797885511556E+00, -1.040167152290219E-02, 1.561713370620346E-04, 2.191573748133731E-03, 2457933.5) CSE = Classes.CartStateEpoch( Classes.CartState(x,y,z,xd,yd,zd), JD ) # Create a CartStateEpochArray of length 3 and populate it using the single CartStateEpoch, CSE N = 3 SEA = (Classes.CartStateEpoch * N)() for n in range(N): SEA[n]=CSE # Checking StateEpochArray has the expected properties assert( len(SEA) == N) assert( isinstance(SEA[0], Classes.CartStateEpoch ) ) assert( np.allclose( [SE.epoch for SE in SEA] , [ JD for n in range(N)] ) ) ### <<<--- WHY WOULD THIS WORK: JD != 2457933.5 ??? for n in range(N): assert( np.all( np.array((SEA[n].CartState.x , SEA[n].CartState.y , SEA[n].CartState.z , SEA[n].CartState.xd , SEA[n].CartState.yd , SEA[n].CartState.zd , SEA[n].epoch )) == np.array((x,y,z,xd,yd,zd,JD)) ) )
def universal_step(GM, dt, inputCartState, evalPartial): """ Take a kepler step in universal variables For evolution of a SINGLE body's cartesian state by a SINGLE timestep *** USES A CALL TO C-CODE*** Parameters ---------- GM : float, Constant dt : float Time step (days?) inputCartState : "CartState" Object-type as defined in MPCFormat. Probably assumes HELIOCENTRIC ECLIPTIC CARTESIAN initial conditions evalPartial : Boolean Whether or not to evaluate partial-derivative matrix Returns ------- finalCartState : "CartState" Object-type as defined in ... Cartesian state at time dt (evolved from input cartState) finalCartPartial: "CartPartial" Object-type as defined in ... Partial derivatives of finalCartState w.r.t. components of input cartState *** AM PASSING THIS BACK AS ZEROES IF PARTIALS ARE NOT EVALUATED *** Examples -------- >>> ... """ finalCartState = Classes.CartState(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) cartPartial = Classes.CartPartial(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) _universal_step = lib.universal_step _universal_step.argtypes = (c_double, c_double, inputCartState, POINTER(Classes.CartState), c_int, POINTER(Classes.CartPartial)) _universal_step.restype = None return_value = _universal_step( GM, dt, inputCartState, byref(finalCartState), evalPartial, byref(cartPartial), ) return finalCartState, cartPartial
def test_creation_of_cartstate(): ''' Create a single cartesian state ''' # Define example cartesian coordinates x,y,z,xd,yd,zd = (4.545057765534996E-01 , 2.658978295316225E+00 , 1.275899778527264E-04, -1.040167152290219E-02 , 1.015042372911457E-03 , 1.948608211319801E-03) # Test that a state is being generated S = Classes.CartState(x,y,z,xd,yd,zd) assert( isinstance(S, Classes.CartState ) ) assert( np.all( np.array((S.x,S.y,S.z,S.xd,S.yd,S.zd))==np.array((x,y,z,xd,yd,zd))))
def test_creation_of_stateepoch(): ''' Test the creation of a combined CartStateEpoch structure to carry both the cartesian state & the epoch of validity ''' # Create a single CartStateEpoch x,y,z,xd,yd,zd,JD = (4.545057765534996E-01, 2.439514137005412E+00, 1.057797885511556E+00, -1.040167152290219E-02, 1.561713370620346E-04, 2.191573748133731E-03, 2457933.5) CSE = Classes.CartStateEpoch( Classes.CartState(x,y,z,xd,yd,zd), JD ) # Check that the created CartStateEpoch, CSE, has the expected properties assert( isinstance(CSE, Classes.CartStateEpoch ) ) assert( isinstance(CSE.CartState, Classes.CartState ) )
def test_standard_methods_cartstate(): ''' Test attributes / methods of CartState ''' # Create a single cartesian state (as per "test_creation_of_cartstate()" above) x,y,z,xd,yd,zd = (4.545057765534996E-01 , 2.658978295316225E+00 , 1.275899778527264E-04, -1.040167152290219E-02 , 1.015042372911457E-03 , 1.948608211319801E-03) S = Classes.CartState(x,y,z,xd,yd,zd) # Posn (xyz) method assert( np.all( np.array( [S.get_xyz()] ) == np.array( [x,y,z] ) ) ) # Vel (uvw) method assert( np.all( np.array( [S.get_uvw()] ) == np.array( [xd,yd,zd] ) ) ) # Rotation method R = Classes.CartState(x,y,z,xd,yd,zd) R.ec_to_eq() assert( S.x == R.x ) assert( S.y != R.y ) assert( S.z != R.z ) assert( np.all( np.array((R.x,R.y,R.z)) == np.array(np.dot(PHYS.rot_mat_ec_to_eq , [S.x,S.y,S.z] )) ) )
def kep2cartState(GM, a, e, incl, longnode, argperi, meananom): """ Converts keplerian coordinates to a cartesian state Keplerians elements are: (a, e, incl, longnode, argperi, meananom) Assumes HELIOCENTRIC ECLIPTIC KEPLERIAN initial conditions ***CONVERSION USES A CALL TO C-CODE*** Parameters ---------- GM : float Gravity a : float Semi-major axis e : float Eccentricity incl : float Inclination longnode : float Longitude of ascending node argperi : float Argument of pericenter meananom : float Mean anomaly Returns ------- cartState : "CartState" Object-type as defined in MPCFormat. Assumes HELIOCENTRIC ECLIPTIC CARTESIAN Examples -------- >>> ... """ _kep2cartState = lib.kep2cartState _kep2cartState.argtypes = (c_double, c_double, c_double, c_double, c_double, c_double, c_double, POINTER(Classes.CartState)) _kep2cartState.restype = None cartState = Classes.CartState(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) return_value = _kep2cartState(GM, a, e, incl, longnode, argperi, meananom, byref(cartState)) return cartState
def test_keplerian(): ''' keplerian should be exactly the same as "cart2kep" - test that it is (Provided for backward compatibility with Holman's legacy code) ''' # Sample data for Ceres from JPL S = Classes.CartState(4.54505776553499E-01, 2.65897829531622E+00, 1.27589977852726E-04, -1.04016715229021E-02, 1.01504237291145E-03, 1.94860821131980E-03) # Use cart2kep to calculate the elements elsC2K = kc.cart2kep(PHYS.GMsun , S) # Use keplerian to calculate the elements elsKEP = kc.keplerian(PHYS.GMsun , S) # Test that the results are the same assert np.allclose( elsC2K , elsKEP )
def test_keplerians(): ''' keplerians should be exactly the same as "cart2kep_array" - test that it is (Provided for backward compatibility with Holman's legacy code) ''' # Create array of CartStates of length 2 # Sample data for Ceres from JPL N = 2 SA = (Classes.CartState * N)() x,y,z,xd,yd,zd = (4.54505776553499E-01, 2.65897829531622E+00, 1.27589977852726E-04, -1.04016715229021E-02, 1.01504237291145E-03, 1.94860821131980E-03) SA[0] = Classes.CartState(x,y,z,xd,yd,zd) SA[1] = Classes.CartState(2.*x,2.*y,2.*z, 0.5*xd, 0.5*yd, 0.5*zd) # Use cart2kep_array to calculate the elements arrays_C2K = kc.cart2kep_array(PHYS.GMsun , SA) # Use keplerians to calculate the elements arrays_KEP = kc.keplerians(PHYS.GMsun , SA) # Test that the results are the same assert np.allclose( arrays_C2K, arrays_KEP) # Just double-checking the test-comparison ... a_C2K,e_C2K,i_C2K,O_C2K,o_C2K,M_C2K = arrays_C2K a_KEP,e_KEP,i_KEP,O_KEP,o_KEP,M_KEP = arrays_KEP assert( np.allclose( (a_C2K,e_C2K,i_C2K,O_C2K,o_C2K,M_C2K) , (a_KEP,e_KEP,i_KEP,O_KEP,o_KEP,M_KEP) ))
def test_cart2kep_array(): ''' Test the accuracy of the cart2kep_array function: - This converts an array of CartStates to arrays of individual Keplerian elements ''' # Create array of CartStates of length 2 # Sample data for Ceres from JPL N = 2 SA = (Classes.CartState * N)() x,y,z,xd,yd,zd = (4.54505776553499E-01, 2.65897829531622E+00, 1.27589977852726E-04, -1.04016715229021E-02, 1.01504237291145E-03, 1.94860821131980E-03) aeiOoM = (2.781870259390299, 0.07692192514945771, 0.18480538653567896, 1.4012469961929193, 1.237855673926063, -1.0950384781408455) SA[0] = Classes.CartState(x,y,z,xd,yd,zd) SA[1] = Classes.CartState(2.*x,2.*y,2.*z, 0.5*xd, 0.5*yd, 0.5*zd) # Use cart2kep_array to calculate the elements arrays_ = kc.cart2kep_array(PHYS.GMsun , SA) # Test datatype & accuracy of returned elements assert( isinstance(arrays_, tuple) ) assert( len(arrays_) == 6) a_,e_,i_,O_,o_,M_ = arrays_ assert( isinstance(a_, np.ndarray) ) assert( len(a_) == N) assert( np.allclose( (a_[0],e_[0],i_[0],O_[0],o_[0],M_[0]) , aeiOoM ))
def test_cart2kep(): ''' Test the accuracy of the cart2kep function - This converts a CartState to individual Keplerian elements ''' # Sample data for Ceres from JPL S = Classes.CartState(4.54505776553499E-01, 2.65897829531622E+00, 1.27589977852726E-04, -1.04016715229021E-02, 1.01504237291145E-03, 1.94860821131980E-03) aeiOoM = (2.781870259390299, 0.07692192514945771, 0.18480538653567896, 1.4012469961929193, 1.237855673926063, -1.0950384781408455) # Use cart2kep to calculate the elements els = kc.cart2kep(PHYS.GMsun , S) # Test datatype & accuracy of returned elements assert( isinstance( els, tuple ) ) assert( len(els) == 6) assert( np.allclose( els , aeiOoM ))
def test_creation_of_cartstatearray(): ''' Test creation of an array of cartesian states ''' # Create a single cartesian state (as per "test_creation_of_cartstate()" above) x,y,z,xd,yd,zd = (4.545057765534996E-01 , 2.658978295316225E+00 , 1.275899778527264E-04, -1.040167152290219E-02 , 1.015042372911457E-03 , 1.948608211319801E-03) S = Classes.CartState(x,y,z,xd,yd,zd) # Now make an array of cartesian states of length 2 N = 2 StateArray = Classes.CartState * N SA = (Classes.CartState * N)() # CartStateArray() SA[0] = S assert( isinstance(SA[0], Classes.CartState ) ) assert( len(SA) == N) assert( np.all( np.array((SA[0].x,SA[0].y,SA[0].z,SA[0].xd,SA[0].yd,SA[0].zd))==np.array((x,y,z,xd,yd,zd))))
def cartesian(GM, a, e, incl, longnode, argperi, meananom): """ Identical to kep2cartState Converts keplerian coordinates to a cartesian state Provided so that Holman's legacy code will always work """ _cartesian = lib.cartesian _cartesian.argtypes = (c_double, c_double, c_double, c_double, c_double, c_double, c_double, POINTER(Classes.CartState)) _cartesian.restype = None cartState = Classes.CartState(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) return_value = _cartesian(GM, a, e, incl, longnode, argperi, meananom, byref(cartState)) return cartState
def test_universal_step_call(): ''' Test the method of calling universal_step ''' # Specify input cartesian state S = Classes.CartState(4.54505776553499E-01, 2.65897829531622E+00, 1.27589977852726E-04, -1.04016715229021E-02, 1.01504237291145E-03, 1.94860821131980E-03) # Specify timestep dt = 1.0 # [days] # Simple (nominal) evolution (no evaluation of Partials) finalCartState, cartPartial = MPCU.universal_step(PHYS.GMsun , dt, S, False) # Test returned quantities from simple advance assert False, "Doomed to fail ... " # Evolution of Nominal & Partials finalCartState, cartPartial = MPCU.universal_step(PHYS.GMsun , dt, S, True) # Test returned quantities from advance of partials assert False, "Doomed to fail ... "