Ejemplo n.º 1
0
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.)
Ejemplo n.º 2
0
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.)
Ejemplo n.º 3
0
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.)
Ejemplo n.º 4
0
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.)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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)