def _integrateLinearOrbit(vxvv,pot,t,method): """ NAME: integrateLinearOrbit PURPOSE: integrate a one-dimensional orbit INPUT: vxvv - initial condition [x,vx] pot - linearPotential or list of linearPotentials t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,2] array of [x,vx] at each t HISTORY: 2010-07-13- Written - Bovy (NYU) """ if '_c' in method: if 'leapfrog' in method or 'symplec' in method: method= 'leapfrog' else: method= 'odeint' if method.lower() == 'leapfrog': return symplecticode.leapfrog(lambda x,t=t: _evaluatelinearForces(pot,x, t=t), nu.array(vxvv), t,rtol=10.**-8) elif method.lower() == 'odeint': return integrate.odeint(_linearEOM,vxvv,t,args=(pot,),rtol=10.**-8.)
def _integrateLinearOrbit(vxvv,pot,t,method): """ NAME: integrateLinearOrbit PURPOSE: integrate a one-dimensional orbit INPUT: vxvv - initial condition [x,vx] pot - linearPotential or list of linearPotentials t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,2] array of [x,vx] at each t HISTORY: 2010-07-13- Written - Bovy (NYU) """ if '_c' in method: if 'leapfrog' in method or 'symplec' in method: method= 'leapfrog' else: method= 'odeint' if method.lower() == 'leapfrog': return symplecticode.leapfrog(evaluatelinearForces,nu.array(vxvv), t,args=(pot,),rtol=10.**-8) elif method.lower() == 'odeint': return integrate.odeint(_linearEOM,vxvv,t,args=(pot,),rtol=10.**-8.)
def _integrateLinearOrbit(vxvv, pot, t, method, dt): """ NAME: integrateLinearOrbit PURPOSE: integrate a one-dimensional orbit INPUT: vxvv - initial condition [x,vx] pot - linearPotential or list of linearPotentials t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,2] array of [x,vx] at each t HISTORY: 2010-07-13- Written - Bovy (NYU) 2018-10-05- Added support for C integration - Bovy (UofT) """ #First check that the potential has C if '_c' in method: if not ext_loaded or not _check_c(pot): if ('leapfrog' in method or 'symplec' in method): method = 'leapfrog' else: method = 'odeint' if not ext_loaded: # pragma: no cover warnings.warn( "Cannot use C integration because C extension not loaded (using %s instead)" % (method), galpyWarning) else: warnings.warn( "Cannot use C integration because some of the potentials are not implemented in C (using %s instead)" % (method), galpyWarning) if method.lower() == 'leapfrog': return symplecticode.leapfrog( lambda x, t=t: _evaluatelinearForces(pot, x, t=t), nu.array(vxvv), t, rtol=10.**-8) elif ext_loaded and \ (method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c'): warnings.warn("Using C implementation to integrate orbits", galpyWarningVerbose) out, msg = integrateLinearOrbit_c(pot, nu.array(vxvv), t, method, dt=dt) return out elif method.lower() == 'odeint' or not ext_loaded: return integrate.odeint(_linearEOM, vxvv, t, args=(pot, ), rtol=10.**-8.)
def _integrateLinearOrbit(vxvv,pot,t,method,dt): """ NAME: integrateLinearOrbit PURPOSE: integrate a one-dimensional orbit INPUT: vxvv - initial condition [x,vx] pot - linearPotential or list of linearPotentials t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,2] array of [x,vx] at each t HISTORY: 2010-07-13- Written - Bovy (NYU) 2018-10-05- Added support for C integration - Bovy (UofT) """ #First check that the potential has C if '_c' in method: if not ext_loaded or not _check_c(pot): if ('leapfrog' in method or 'symplec' in method): method= 'leapfrog' else: method= 'odeint' if not ext_loaded: # pragma: no cover warnings.warn("Cannot use C integration because C extension not loaded (using %s instead)" % (method), galpyWarning) else: warnings.warn("Cannot use C integration because some of the potentials are not implemented in C (using %s instead)" % (method), galpyWarning) if method.lower() == 'leapfrog': return symplecticode.leapfrog(lambda x,t=t: _evaluatelinearForces(pot,x, t=t), nu.array(vxvv), t,rtol=10.**-8) elif method.lower() == 'dop853': return dop853(func=_linearEOM, x=vxvv, t=t, args=(pot,)) elif ext_loaded and \ (method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c' \ or method.lower() == 'dop853_c'): warnings.warn("Using C implementation to integrate orbits", galpyWarningVerbose) out, msg= integrateLinearOrbit_c(pot,nu.array(vxvv),t,method,dt=dt) return out elif method.lower() == 'odeint' or not ext_loaded: return integrate.odeint(_linearEOM,vxvv,t,args=(pot,),rtol=10.**-8.)
def _integrateOrbit(vxvv, pot, t, method, dt): """ NAME: _integrateOrbit PURPOSE: integrate an orbit in a Phi(R) potential in the (R,phi)-plane INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' dt- if set, force the integrator to use this basic stepsize; must be an integer divisor of output stepsize OUTPUT: [:,4] array of [R,vR,vT,phi] at each t HISTORY: 2010-07-20 - Written - Bovy (NYU) """ #First check that the potential has C if '_c' in method: if not _check_c(pot): if ('leapfrog' in method or 'symplec' in method): method = 'leapfrog' else: method = 'odeint' warnings.warn( "Cannot use C integration because some of the potentials are not implemented in C (using %s instead)" % (method), galpyWarning) if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[3]), vxvv[0] * nu.sin(vxvv[3]), vxvv[1] * nu.cos(vxvv[3]) - vxvv[2] * nu.sin(vxvv[3]), vxvv[2] * nu.cos(vxvv[3]) + vxvv[1] * nu.sin(vxvv[3]) ]) #integrate tmp_out = symplecticode.leapfrog(_rectForce, this_vxvv, t, args=(pot, ), rtol=10.**-8) #go back to the cylindrical frame R = nu.sqrt(tmp_out[:, 0]**2. + tmp_out[:, 1]**2.) phi = nu.arccos(tmp_out[:, 0] / R) phi[(tmp_out[:, 1] < 0.)] = 2. * nu.pi - phi[(tmp_out[:, 1] < 0.)] vR = tmp_out[:, 2] * nu.cos(phi) + tmp_out[:, 3] * nu.sin(phi) vT = tmp_out[:, 3] * nu.cos(phi) - tmp_out[:, 2] * nu.sin(phi) out = nu.zeros((len(t), 4)) out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 3] = phi msg = 0 elif method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c': warnings.warn("Using C implementation to integrate orbits", galpyWarningVerbose) #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[3]), vxvv[0] * nu.sin(vxvv[3]), vxvv[1] * nu.cos(vxvv[3]) - vxvv[2] * nu.sin(vxvv[3]), vxvv[2] * nu.cos(vxvv[3]) + vxvv[1] * nu.sin(vxvv[3]) ]) #integrate tmp_out, msg = integratePlanarOrbit_c(pot, this_vxvv, t, method, dt=dt) #go back to the cylindrical frame R = nu.sqrt(tmp_out[:, 0]**2. + tmp_out[:, 1]**2.) phi = nu.arccos(tmp_out[:, 0] / R) phi[(tmp_out[:, 1] < 0.)] = 2. * nu.pi - phi[(tmp_out[:, 1] < 0.)] vR = tmp_out[:, 2] * nu.cos(phi) + tmp_out[:, 3] * nu.sin(phi) vT = tmp_out[:, 3] * nu.cos(phi) - tmp_out[:, 2] * nu.sin(phi) out = nu.zeros((len(t), 4)) out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 3] = phi elif method.lower() == 'odeint': vphi = vxvv[2] / vxvv[0] init = [vxvv[0], vxvv[1], vxvv[3], vphi] intOut = integrate.odeint(_EOM, init, t, args=(pot, ), rtol=10.**-8.) #,mxstep=100000000) out = nu.zeros((len(t), 4)) out[:, 0] = intOut[:, 0] out[:, 1] = intOut[:, 1] out[:, 3] = intOut[:, 2] out[:, 2] = out[:, 0] * intOut[:, 3] msg = 0 else: raise NotImplementedError( "requested integration method does not exist") #post-process to remove negative radii neg_radii = (out[:, 0] < 0.) out[neg_radii, 0] = -out[neg_radii, 0] out[neg_radii, 3] += m.pi _parse_warnmessage(msg) return (out, msg)
def _integrateFullOrbit(vxvv, pot, t, method, dt): """ NAME: _integrateFullOrbit PURPOSE: integrate an orbit in a Phi(R,z,phi) potential INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,z,vz,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' dt - if set, force the integrator to use this basic stepsize; must be an integer divisor of output stepsize OUTPUT: [:,5] array of [R,vR,vT,z,vz,phi] at each t HISTORY: 2010-08-01 - Written - Bovy (NYU) """ #First check that the potential has C if '_c' in method: if not ext_loaded or not _check_c(pot): if ('leapfrog' in method or 'symplec' in method): method = 'leapfrog' else: method = 'odeint' if not ext_loaded: # pragma: no cover warnings.warn( "Cannot use C integration because C extension not loaded (using %s instead)" % (method), galpyWarning) else: warnings.warn( "Cannot use C integration because some of the potentials are not implemented in C (using %s instead)" % (method), galpyWarning) # Now check that we aren't trying to integrate a dissipative force # with a symplectic integrator if _isDissipative(pot) and ('leapfrog' in method or 'symplec' in method): if '_c' in method: method = 'dopr54_c' else: method = 'odeint' warnings.warn( "Cannot use symplectic integration because some of the included forces are dissipative (using non-symplectic integrator %s instead)" % (method), galpyWarning) if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[5]), vxvv[0] * nu.sin(vxvv[5]), vxvv[3], vxvv[1] * nu.cos(vxvv[5]) - vxvv[2] * nu.sin(vxvv[5]), vxvv[2] * nu.cos(vxvv[5]) + vxvv[1] * nu.sin(vxvv[5]), vxvv[4] ]) #integrate out = symplecticode.leapfrog(_rectForce, this_vxvv, t, args=(pot, ), rtol=10.**-8) #go back to the cylindrical frame R = nu.sqrt(out[:, 0]**2. + out[:, 1]**2.) phi = nu.arccos(out[:, 0] / R) phi[(out[:, 1] < 0.)] = 2. * nu.pi - phi[(out[:, 1] < 0.)] vR = out[:, 3] * nu.cos(phi) + out[:, 4] * nu.sin(phi) vT = out[:, 4] * nu.cos(phi) - out[:, 3] * nu.sin(phi) out[:, 3] = out[:, 2] out[:, 4] = out[:, 5] out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 5] = phi elif ext_loaded and \ (method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c'): warnings.warn("Using C implementation to integrate orbits", galpyWarningVerbose) #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[5]), vxvv[0] * nu.sin(vxvv[5]), vxvv[3], vxvv[1] * nu.cos(vxvv[5]) - vxvv[2] * nu.sin(vxvv[5]), vxvv[2] * nu.cos(vxvv[5]) + vxvv[1] * nu.sin(vxvv[5]), vxvv[4] ]) #integrate tmp_out, msg = integrateFullOrbit_c(pot, this_vxvv, t, method, dt=dt) #go back to the cylindrical frame R = nu.sqrt(tmp_out[:, 0]**2. + tmp_out[:, 1]**2.) phi = nu.arccos(tmp_out[:, 0] / R) phi[(tmp_out[:, 1] < 0.)] = 2. * nu.pi - phi[(tmp_out[:, 1] < 0.)] vR = tmp_out[:, 3] * nu.cos(phi) + tmp_out[:, 4] * nu.sin(phi) vT = tmp_out[:, 4] * nu.cos(phi) - tmp_out[:, 3] * nu.sin(phi) out = nu.zeros((len(t), 6)) out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 5] = phi out[:, 3] = tmp_out[:, 2] out[:, 4] = tmp_out[:, 5] elif method.lower() == 'odeint' or not ext_loaded: vphi = vxvv[2] / vxvv[0] init = [vxvv[0], vxvv[1], vxvv[5], vphi, vxvv[3], vxvv[4]] intOut = integrate.odeint(_FullEOM, init, t, args=(pot, ), rtol=10.**-8.) #,mxstep=100000000) out = nu.zeros((len(t), 6)) out[:, 0] = intOut[:, 0] out[:, 1] = intOut[:, 1] out[:, 2] = out[:, 0] * intOut[:, 3] out[:, 3] = intOut[:, 4] out[:, 4] = intOut[:, 5] out[:, 5] = intOut[:, 2] #post-process to remove negative radii neg_radii = (out[:, 0] < 0.) out[neg_radii, 0] = -out[neg_radii, 0] out[neg_radii, 5] += m.pi return out
def _integrateFullOrbit(vxvv,pot,t,method): """ NAME: _integrateFullOrbit PURPOSE: integrate an orbit in a Phi(R,z,phi) potential INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,z,vz,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,5] array of [R,vR,vT,z,vz,phi] at each t HISTORY: 2010-08-01 - Written - Bovy (NYU) """ #First check that the potential has C if '_c' in method: if isinstance(pot,list): allHasC= nu.prod([p.hasC for p in pot]) else: allHasC= pot.hasC if not allHasC and ('leapfrog' in method or 'symplec' in method): method= 'leapfrog' elif not allHasC: method= 'odeint' if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[5]), vxvv[0]*nu.sin(vxvv[5]), vxvv[3], vxvv[1]*nu.cos(vxvv[5])-vxvv[2]*nu.sin(vxvv[5]), vxvv[2]*nu.cos(vxvv[5])+vxvv[1]*nu.sin(vxvv[5]), vxvv[4]]) #integrate out= symplecticode.leapfrog(_rectForce,this_vxvv, t,args=(pot,),rtol=10.**-8) #go back to the cylindrical frame R= nu.sqrt(out[:,0]**2.+out[:,1]**2.) phi= nu.arccos(out[:,0]/R) phi[(out[:,1] < 0.)]= 2.*nu.pi-phi[(out[:,1] < 0.)] vR= out[:,3]*nu.cos(phi)+out[:,4]*nu.sin(phi) vT= out[:,4]*nu.cos(phi)-out[:,3]*nu.sin(phi) out[:,3]= out[:,2] out[:,4]= out[:,5] out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,5]= phi elif ext_loaded and \ (method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c'): warnings.warn("Using C implementation to integrate orbits", galpyWarning) #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[5]), vxvv[0]*nu.sin(vxvv[5]), vxvv[3], vxvv[1]*nu.cos(vxvv[5])-vxvv[2]*nu.sin(vxvv[5]), vxvv[2]*nu.cos(vxvv[5])+vxvv[1]*nu.sin(vxvv[5]), vxvv[4]]) #integrate tmp_out, msg= integrateFullOrbit_c(pot,this_vxvv, t,method) #go back to the cylindrical frame R= nu.sqrt(tmp_out[:,0]**2.+tmp_out[:,1]**2.) phi= nu.arccos(tmp_out[:,0]/R) phi[(tmp_out[:,1] < 0.)]= 2.*nu.pi-phi[(tmp_out[:,1] < 0.)] vR= tmp_out[:,3]*nu.cos(phi)+tmp_out[:,4]*nu.sin(phi) vT= tmp_out[:,4]*nu.cos(phi)-tmp_out[:,3]*nu.sin(phi) out= nu.zeros((len(t),6)) out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,5]= phi out[:,3]= tmp_out[:,2] out[:,4]= tmp_out[:,5] elif method.lower() == 'odeint' or not ext_loaded: vphi= vxvv[2]/vxvv[0] init= [vxvv[0],vxvv[1],vxvv[5],vphi,vxvv[3],vxvv[4]] intOut= integrate.odeint(_FullEOM,init,t,args=(pot,), rtol=10.**-8.)#,mxstep=100000000) out= nu.zeros((len(t),6)) out[:,0]= intOut[:,0] out[:,1]= intOut[:,1] out[:,2]= out[:,0]*intOut[:,3] out[:,3]= intOut[:,4] out[:,4]= intOut[:,5] out[:,5]= intOut[:,2] #post-process to remove negative radii neg_radii= (out[:,0] < 0.) out[neg_radii,0]= -out[neg_radii,0] out[neg_radii,5]+= m.pi return out
def _integrateOrbit(vxvv,pot,t,method): """ NAME: _integrateOrbit PURPOSE: integrate an orbit in a Phi(R) potential in the (R,phi)-plane INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,4] array of [R,vR,vT,phi] at each t HISTORY: 2010-07-20 - Written - Bovy (NYU) """ if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[3]), vxvv[0]*nu.sin(vxvv[3]), vxvv[1]*nu.cos(vxvv[3])-vxvv[2]*nu.sin(vxvv[3]), vxvv[2]*nu.cos(vxvv[3])+vxvv[1]*nu.sin(vxvv[3])]) #integrate tmp_out= symplecticode.leapfrog(_rectForce,this_vxvv, t,args=(pot,),rtol=10.**-8) #go back to the cylindrical frame R= nu.sqrt(tmp_out[:,0]**2.+tmp_out[:,1]**2.) phi= nu.arccos(tmp_out[:,0]/R) phi[(tmp_out[:,1] < 0.)]= 2.*nu.pi-phi[(tmp_out[:,1] < 0.)] vR= tmp_out[:,2]*nu.cos(phi)+tmp_out[:,3]*nu.sin(phi) vT= tmp_out[:,3]*nu.cos(phi)-tmp_out[:,2]*nu.sin(phi) out= nu.zeros((len(t),4)) out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,3]= phi msg= 0 elif method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c': warnings.warn("Using C implementation to integrate orbits",galpyWarning) #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[3]), vxvv[0]*nu.sin(vxvv[3]), vxvv[1]*nu.cos(vxvv[3])-vxvv[2]*nu.sin(vxvv[3]), vxvv[2]*nu.cos(vxvv[3])+vxvv[1]*nu.sin(vxvv[3])]) #integrate tmp_out, msg= integratePlanarOrbit_c(pot,this_vxvv, t,method) #go back to the cylindrical frame R= nu.sqrt(tmp_out[:,0]**2.+tmp_out[:,1]**2.) phi= nu.arccos(tmp_out[:,0]/R) phi[(tmp_out[:,1] < 0.)]= 2.*nu.pi-phi[(tmp_out[:,1] < 0.)] vR= tmp_out[:,2]*nu.cos(phi)+tmp_out[:,3]*nu.sin(phi) vT= tmp_out[:,3]*nu.cos(phi)-tmp_out[:,2]*nu.sin(phi) out= nu.zeros((len(t),4)) out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,3]= phi elif method.lower() == 'odeint': vphi= vxvv[2]/vxvv[0] init= [vxvv[0],vxvv[1],vxvv[3],vphi] intOut= integrate.odeint(_EOM,init,t,args=(pot,), rtol=10.**-8.)#,mxstep=100000000) out= nu.zeros((len(t),4)) out[:,0]= intOut[:,0] out[:,1]= intOut[:,1] out[:,3]= intOut[:,2] out[:,2]= out[:,0]*intOut[:,3] msg= 0 else: raise NotImplementedError("requested integration method does not exist") #post-process to remove negative radii neg_radii= (out[:,0] < 0.) out[neg_radii,0]= -out[neg_radii,0] out[neg_radii,3]+= m.pi _parse_warnmessage(msg) return (out,msg)
def _integrateFullOrbit(vxvv, pot, t, method): """ NAME: _integrateFullOrbit PURPOSE: integrate an orbit in a Phi(R,z,phi) potential INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,z,vz,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' OUTPUT: [:,5] array of [R,vR,vT,z,vz,phi] at each t HISTORY: 2010-08-01 - Written - Bovy (NYU) """ if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[5]), vxvv[0] * nu.sin(vxvv[5]), vxvv[3], vxvv[1] * nu.cos(vxvv[5]) - vxvv[2] * nu.sin(vxvv[5]), vxvv[2] * nu.cos(vxvv[5]) + vxvv[1] * nu.sin(vxvv[5]), vxvv[4] ]) #integrate out = symplecticode.leapfrog(_rectForce, this_vxvv, t, args=(pot, ), rtol=10.**-8) #go back to the cylindrical frame R = nu.sqrt(out[:, 0]**2. + out[:, 1]**2.) phi = nu.arccos(out[:, 0] / R) phi[(out[:, 1] < 0.)] = 2. * nu.pi - phi[(out[:, 1] < 0.)] vR = out[:, 3] * nu.cos(phi) + out[:, 4] * nu.sin(phi) vT = out[:, 4] * nu.cos(phi) - out[:, 3] * nu.sin(phi) out[:, 3] = out[:, 2] out[:, 4] = out[:, 5] out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 5] = phi elif method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c': warnings.warn("Using C implementation to integrate orbits") #go to the rectangular frame this_vxvv = nu.array([ vxvv[0] * nu.cos(vxvv[5]), vxvv[0] * nu.sin(vxvv[5]), vxvv[3], vxvv[1] * nu.cos(vxvv[5]) - vxvv[2] * nu.sin(vxvv[5]), vxvv[2] * nu.cos(vxvv[5]) + vxvv[1] * nu.sin(vxvv[5]), vxvv[4] ]) #integrate tmp_out, msg = integrateFullOrbit_c(pot, this_vxvv, t, method) #go back to the cylindrical frame R = nu.sqrt(tmp_out[:, 0]**2. + tmp_out[:, 1]**2.) phi = nu.arccos(tmp_out[:, 0] / R) phi[(tmp_out[:, 1] < 0.)] = 2. * nu.pi - phi[(tmp_out[:, 1] < 0.)] vR = tmp_out[:, 3] * nu.cos(phi) + tmp_out[:, 4] * nu.sin(phi) vT = tmp_out[:, 4] * nu.cos(phi) - tmp_out[:, 3] * nu.sin(phi) out = nu.zeros((len(t), 6)) out[:, 0] = R out[:, 1] = vR out[:, 2] = vT out[:, 5] = phi out[:, 3] = tmp_out[:, 2] out[:, 4] = tmp_out[:, 5] elif method.lower() == 'odeint': vphi = vxvv[2] / vxvv[0] init = [vxvv[0], vxvv[1], vxvv[5], vphi, vxvv[3], vxvv[4]] intOut = integrate.odeint(_FullEOM, init, t, args=(pot, ), rtol=10.**-8.) #,mxstep=100000000) out = nu.zeros((len(t), 6)) out[:, 0] = intOut[:, 0] out[:, 1] = intOut[:, 1] out[:, 2] = out[:, 0] * intOut[:, 3] out[:, 3] = intOut[:, 4] out[:, 4] = intOut[:, 5] out[:, 5] = intOut[:, 2] #post-process to remove negative radii neg_radii = (out[:, 0] < 0.) out[neg_radii, 0] = -out[neg_radii, 0] out[neg_radii, 5] += m.pi return out
def _integrateOrbit(vxvv,pot,t,method,dt): """ NAME: _integrateOrbit PURPOSE: integrate an orbit in a Phi(R) potential in the (R,phi)-plane INPUT: vxvv - array with the initial conditions stacked like [R,vR,vT,phi]; vR outward! pot - Potential instance t - list of times at which to output (0 has to be in this!) method - 'odeint' or 'leapfrog' dt- if set, force the integrator to use this basic stepsize; must be an integer divisor of output stepsize OUTPUT: [:,4] array of [R,vR,vT,phi] at each t HISTORY: 2010-07-20 - Written - Bovy (NYU) """ #First check that the potential has C if '_c' in method: if not ext_loaded or not _check_c(pot): if ('leapfrog' in method or 'symplec' in method): method= 'leapfrog' else: method= 'odeint' if not ext_loaded: # pragma: no cover warnings.warn("Cannot use C integration because C extension not loaded (using %s instead)" % (method), galpyWarning) else: warnings.warn("Cannot use C integration because some of the potentials are not implemented in C (using %s instead)" % (method), galpyWarning) if method.lower() == 'leapfrog': #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[3]), vxvv[0]*nu.sin(vxvv[3]), vxvv[1]*nu.cos(vxvv[3])-vxvv[2]*nu.sin(vxvv[3]), vxvv[2]*nu.cos(vxvv[3])+vxvv[1]*nu.sin(vxvv[3])]) #integrate tmp_out= symplecticode.leapfrog(_rectForce,this_vxvv, t,args=(pot,),rtol=10.**-8) #go back to the cylindrical frame R= nu.sqrt(tmp_out[:,0]**2.+tmp_out[:,1]**2.) phi= nu.arccos(tmp_out[:,0]/R) phi[(tmp_out[:,1] < 0.)]= 2.*nu.pi-phi[(tmp_out[:,1] < 0.)] vR= tmp_out[:,2]*nu.cos(phi)+tmp_out[:,3]*nu.sin(phi) vT= tmp_out[:,3]*nu.cos(phi)-tmp_out[:,2]*nu.sin(phi) out= nu.zeros((len(t),4)) out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,3]= phi msg= 0 elif ext_loaded and \ (method.lower() == 'leapfrog_c' or method.lower() == 'rk4_c' \ or method.lower() == 'rk6_c' or method.lower() == 'symplec4_c' \ or method.lower() == 'symplec6_c' or method.lower() == 'dopr54_c' \ or method.lower() == 'dop853_c'): warnings.warn("Using C implementation to integrate orbits",galpyWarningVerbose) #go to the rectangular frame this_vxvv= nu.array([vxvv[0]*nu.cos(vxvv[3]), vxvv[0]*nu.sin(vxvv[3]), vxvv[1]*nu.cos(vxvv[3])-vxvv[2]*nu.sin(vxvv[3]), vxvv[2]*nu.cos(vxvv[3])+vxvv[1]*nu.sin(vxvv[3])]) #integrate tmp_out, msg= integratePlanarOrbit_c(pot,this_vxvv, t,method,dt=dt) #go back to the cylindrical frame R= nu.sqrt(tmp_out[:,0]**2.+tmp_out[:,1]**2.) phi= nu.arccos(tmp_out[:,0]/R) phi[(tmp_out[:,1] < 0.)]= 2.*nu.pi-phi[(tmp_out[:,1] < 0.)] vR= tmp_out[:,2]*nu.cos(phi)+tmp_out[:,3]*nu.sin(phi) vT= tmp_out[:,3]*nu.cos(phi)-tmp_out[:,2]*nu.sin(phi) out= nu.zeros((len(t),4)) out[:,0]= R out[:,1]= vR out[:,2]= vT out[:,3]= phi elif method.lower() == 'odeint' or method.lower() == 'dop853' or not ext_loaded: vphi= vxvv[2]/vxvv[0] init= [vxvv[0],vxvv[1],vxvv[3],vphi] if method == 'dop853': intOut = dop853(_EOM, init, t, args=(pot,)) else: intOut= integrate.odeint(_EOM,init,t,args=(pot,), rtol=10.**-8.)#,mxstep=100000000) out= nu.zeros((len(t),4)) out[:,0]= intOut[:,0] out[:,1]= intOut[:,1] out[:,3]= intOut[:,2] out[:,2]= out[:,0]*intOut[:,3] msg= 0 else: raise NotImplementedError("requested integration method does not exist") #post-process to remove negative radii neg_radii= (out[:,0] < 0.) out[neg_radii,0]= -out[neg_radii,0] out[neg_radii,3]+= m.pi _parse_warnmessage(msg) return (out,msg)