def _integrateOrbit_dxdv(vxvv, dxdv, pot, t, method, rectIn, rectOut):
    """
    NAME:
       _integrateOrbit_dxdv
    PURPOSE:
       integrate an orbit and area of phase space 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!
       dxdv - difference to integrate [dR,dvR,dvT,dphi]
       pot - Potential instance
       t - list of times at which to output (0 has to be in this!)
       method - 'odeint' or 'leapfrog'
       rectIn= (False) if True, input dxdv is in rectangular coordinates
       rectOut= (False) if True, output dxdv (that in orbit_dxdv) is in rectangular coordinates
    OUTPUT:
       [:,8] array of [R,vR,vT,phi,dR,dvR,dvT,dphi] at each t
       error message from integrator
    HISTORY:
       2010-10-17 - Written - Bovy (IAS)
    """
    #First check that the potential has C
    if '_c' in method:
        allHasC = _check_c(pot) and _check_c(pot, dxdv=True)
        if not allHasC and not 'leapfrog' in method and not 'symplec' in method:
            method = 'odeint'
            warnings.warn(
                "Using odeint because not all used potential have adequate C implementations to integrate phase-space volumes",
                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])
    ])
    if not rectIn:
        this_dxdv = nu.array([
            nu.cos(vxvv[3]) * dxdv[0] - vxvv[0] * nu.sin(vxvv[3]) * dxdv[3],
            nu.sin(vxvv[3]) * dxdv[0] + vxvv[0] * nu.cos(vxvv[3]) * dxdv[3],
            -(vxvv[1] * nu.sin(vxvv[3]) + vxvv[2] * nu.cos(vxvv[3])) * dxdv[3]
            + nu.cos(vxvv[3]) * dxdv[1] - nu.sin(vxvv[3]) * dxdv[2],
            (vxvv[1] * nu.cos(vxvv[3]) - vxvv[2] * nu.sin(vxvv[3])) * dxdv[3] +
            nu.sin(vxvv[3]) * dxdv[1] + nu.cos(vxvv[3]) * dxdv[2]
        ])
    else:
        this_dxdv = dxdv
    if 'leapfrog' in method.lower() or 'symplec' in method.lower():
        raise TypeError(
            'Symplectic integration for phase-space volume is not possible')
    elif method.lower() == 'rk4_c' or method.lower() == 'rk6_c' \
            or method.lower() == 'dopr54_c':
        warnings.warn("Using C implementation to integrate orbits",
                      galpyWarningVerbose)
        #integrate
        tmp_out, msg = integratePlanarOrbit_dxdv_c(pot, this_vxvv, this_dxdv,
                                                   t, method)
    elif method.lower() == 'odeint':
        init = [
            this_vxvv[0], this_vxvv[1], this_vxvv[2], this_vxvv[3],
            this_dxdv[0], this_dxdv[1], this_dxdv[2], this_dxdv[3]
        ]
        #integrate
        tmp_out = integrate.odeint(_EOM_dxdv,
                                   init,
                                   t,
                                   args=(pot, ),
                                   rtol=10.**-8.)  #,mxstep=100000000)
        msg = 0
    else:
        raise NotImplementedError(
            "requested integration method does not exist")
    #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)
    cp = nu.cos(phi)
    sp = nu.sin(phi)
    dR = cp * tmp_out[:, 4] + sp * tmp_out[:, 5]
    dphi = (cp * tmp_out[:, 5] - sp * tmp_out[:, 4]) / R
    dvR = cp * tmp_out[:, 6] + sp * tmp_out[:, 7] + vT * dphi
    dvT = cp * tmp_out[:, 7] - sp * tmp_out[:, 6] - vR * dphi
    out = nu.zeros((len(t), 8))
    out[:, 0] = R
    out[:, 1] = vR
    out[:, 2] = vT
    out[:, 3] = phi
    if rectOut:
        out[:, 4:] = tmp_out[:, 4:]
    else:
        out[:, 4] = dR
        out[:, 7] = dphi
        out[:, 5] = dvR
        out[:, 6] = dvT
    _parse_warnmessage(msg)
    return (out, msg)
示例#2
0
文件: planarOrbit.py 项目: smoh/galpy
def _integrateOrbit_dxdv(vxvv,dxdv,pot,t,method,rectIn,rectOut):
    """
    NAME:
       _integrateOrbit_dxdv
    PURPOSE:
       integrate an orbit and area of phase space 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!
       dxdv - difference to integrate [dR,dvR,dvT,dphi]
       pot - Potential instance
       t - list of times at which to output (0 has to be in this!)
       method - 'odeint' or 'leapfrog'
       rectIn= (False) if True, input dxdv is in rectangular coordinates
       rectOut= (False) if True, output dxdv (that in orbit_dxdv) is in rectangular coordinates
    OUTPUT:
       [:,8] array of [R,vR,vT,phi,dR,dvR,dvT,dphi] at each t
       error message from integrator
    HISTORY:
       2010-10-17 - Written - Bovy (IAS)
    """
    #First check that the potential has C
    if '_c' in method:
        allHasC= _check_c(pot) and _check_c(pot,dxdv=True)
        if not allHasC and not 'leapfrog' in method and not 'symplec' in method:
            method= 'odeint'
            warnings.warn("Using odeint because not all used potential have adequate C implementations to integrate phase-space volumes",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])])
    if not rectIn:
        this_dxdv= nu.array([nu.cos(vxvv[3])*dxdv[0]
                             -vxvv[0]*nu.sin(vxvv[3])*dxdv[3],
                             nu.sin(vxvv[3])*dxdv[0]
                             +vxvv[0]*nu.cos(vxvv[3])*dxdv[3],
                             -(vxvv[1]*nu.sin(vxvv[3])
                               +vxvv[2]*nu.cos(vxvv[3]))*dxdv[3]
                             +nu.cos(vxvv[3])*dxdv[1]-nu.sin(vxvv[3])*dxdv[2],
                             (vxvv[1]*nu.cos(vxvv[3])
                              -vxvv[2]*nu.sin(vxvv[3]))*dxdv[3]
                             +nu.sin(vxvv[3])*dxdv[1]+nu.cos(vxvv[3])*dxdv[2]])
    else:
        this_dxdv= dxdv
    if 'leapfrog' in method.lower() or 'symplec' in method.lower():
        raise TypeError('Symplectic integration for phase-space volume is not possible')
    elif method.lower() == 'rk4_c' or method.lower() == 'rk6_c' \
            or method.lower() == 'dopr54_c':
        warnings.warn("Using C implementation to integrate orbits",galpyWarning)
        #integrate
        tmp_out, msg= integratePlanarOrbit_dxdv_c(pot,this_vxvv,this_dxdv,
                                                  t,method)
    elif method.lower() == 'odeint':
        init= [this_vxvv[0],this_vxvv[1],this_vxvv[2],this_vxvv[3],
               this_dxdv[0],this_dxdv[1],this_dxdv[2],this_dxdv[3]]
        #integrate
        tmp_out= integrate.odeint(_EOM_dxdv,init,t,args=(pot,),
                                  rtol=10.**-8.)#,mxstep=100000000)
        msg= 0
    else:
        raise NotImplementedError("requested integration method does not exist")
    #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)
    cp= nu.cos(phi)
    sp= nu.sin(phi)
    dR= cp*tmp_out[:,4]+sp*tmp_out[:,5]
    dphi= (cp*tmp_out[:,5]-sp*tmp_out[:,4])/R
    dvR= cp*tmp_out[:,6]+sp*tmp_out[:,7]+vT*dphi
    dvT= cp*tmp_out[:,7]-sp*tmp_out[:,6]-vR*dphi
    out= nu.zeros((len(t),8))
    out[:,0]= R
    out[:,1]= vR
    out[:,2]= vT
    out[:,3]= phi
    if rectOut:
        out[:,4:]= tmp_out[:,4:]
    else:
        out[:,4]= dR
        out[:,7]= dphi
        out[:,5]= dvR
        out[:,6]= dvT
    _parse_warnmessage(msg)
    return (out,msg)
示例#3
0
def _integrateOrbit_dxdv(vxvv,dxdv,pot,t,method):
    """
    NAME:
       _integrateOrbit_dxdv
    PURPOSE:
       integrate an orbit and area of phase space 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!
       dxdv - difference to integrate [dR,dvR,dvT,dphi]
       pot - Potential instance
       t - list of times at which to output (0 has to be in this!)
       method - 'odeint' or 'leapfrog'
    OUTPUT:
       [:,8] array of [R,vR,vT,phi,dR,dvR,dvT,dphi] at each t
       error message from integrator
    HISTORY:
       2010-10-17 - Written - Bovy (IAS)
    """
    #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])])
    this_dxdv= nu.array([nu.cos(vxvv[3])*dxdv[0]-vxvv[0]*nu.sin(vxvv[3])*dxdv[3],
                         nu.sin(vxvv[3])*dxdv[0]+vxvv[0]*nu.cos(vxvv[3])*dxdv[3],
                         -(vxvv[1]*nu.sin(vxvv[3])+vxvv[2]*nu.cos(vxvv[3]))*dxdv[3]
                         +nu.cos(vxvv[3])*dxdv[1]-nu.sin(vxvv[3])*dxdv[2],
                         (vxvv[1]*nu.cos(vxvv[3])-vxvv[2]*nu.sin(vxvv[3]))*dxdv[3]
                         +nu.sin(vxvv[3])*dxdv[1]+nu.cos(vxvv[3])*dxdv[2]])
    if 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':
        #raise NotImplementedError("C implementation of phase space integration not implemented yet")
        warnings.warn("Using C implementation to integrate orbits",galpyWarning)
        #integrate
        tmp_out, msg= integratePlanarOrbit_dxdv_c(pot,this_vxvv,this_dxdv,
                                                  t,method)
    elif method.lower() == 'odeint':
        init= [this_vxvv[0],this_vxvv[1],this_vxvv[2],this_vxvv[3],
               this_dxdv[0],this_dxdv[1],this_dxdv[2],this_dxdv[3]]
        #integrate
        tmp_out= integrate.odeint(_EOM_dxdv,init,t,args=(pot,),
                                  rtol=10.**-8.)#,mxstep=100000000)
        msg= 0
    else:
        raise NotImplementedError("requested integration method does not exist")
    #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)
    cp= nu.cos(phi)
    sp= nu.sin(phi)
    dR= cp*tmp_out[:,4]+sp*tmp_out[:,5]
    dphi= (cp*tmp_out[:,5]-sp*tmp_out[:,4])/R
    dvR= cp*tmp_out[:,6]+sp*tmp_out[:,7]+vT*dphi
    dvT= cp*tmp_out[:,7]-sp*tmp_out[:,6]-vR*dphi
    out= nu.zeros((len(t),8))
    out[:,0]= R
    out[:,1]= vR
    out[:,2]= vT
    out[:,3]= phi
    out[:,4]= dR
    out[:,7]= dphi
    out[:,5]= dvR
    out[:,6]= dvT
    _parse_warnmessage(msg)
    return (out,msg)
示例#4
0
def _integrateOrbit_dxdv(vxvv, dxdv, pot, t, method):
    """
    NAME:
       _integrateOrbit_dxdv
    PURPOSE:
       integrate an orbit and area of phase space 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!
       dxdv - difference to integrate [dR,dvR,dvT,dphi]
       pot - Potential instance
       t - list of times at which to output (0 has to be in this!)
       method - 'odeint' or 'leapfrog'
    OUTPUT:
       [:,8] array of [R,vR,vT,phi,dR,dvR,dvT,dphi] at each t
       error message from integrator
    HISTORY:
       2010-10-17 - Written - Bovy (IAS)
    """
    #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])
    ])
    this_dxdv = nu.array([
        nu.cos(vxvv[3]) * dxdv[0] - vxvv[0] * nu.sin(vxvv[3]) * dxdv[3],
        nu.sin(vxvv[3]) * dxdv[0] + vxvv[0] * nu.cos(vxvv[3]) * dxdv[3],
        -(vxvv[1] * nu.sin(vxvv[3]) + vxvv[2] * nu.cos(vxvv[3])) * dxdv[3] +
        nu.cos(vxvv[3]) * dxdv[1] - nu.sin(vxvv[3]) * dxdv[2],
        (vxvv[1] * nu.cos(vxvv[3]) - vxvv[2] * nu.sin(vxvv[3])) * dxdv[3] +
        nu.sin(vxvv[3]) * dxdv[1] + nu.cos(vxvv[3]) * dxdv[2]
    ])
    if 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':
        #raise NotImplementedError("C implementation of phase space integration not implemented yet")
        warnings.warn("Using C implementation to integrate orbits")
        #integrate
        tmp_out, msg = integratePlanarOrbit_dxdv_c(pot, this_vxvv, this_dxdv,
                                                   t, method)
    elif method.lower() == 'odeint':
        init = [
            this_vxvv[0], this_vxvv[1], this_vxvv[2], this_vxvv[3],
            this_dxdv[0], this_dxdv[1], this_dxdv[2], this_dxdv[3]
        ]
        #integrate
        tmp_out = integrate.odeint(_EOM_dxdv,
                                   init,
                                   t,
                                   args=(pot, ),
                                   rtol=10.**-8.)  #,mxstep=100000000)
        msg = 0
    else:
        raise NotImplementedError(
            "requested integration method does not exist")
    #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)
    cp = nu.cos(phi)
    sp = nu.sin(phi)
    dR = cp * tmp_out[:, 4] + sp * tmp_out[:, 5]
    dphi = (cp * tmp_out[:, 5] - sp * tmp_out[:, 4]) / R
    dvR = cp * tmp_out[:, 6] + sp * tmp_out[:, 7] + vT * dphi
    dvT = cp * tmp_out[:, 7] - sp * tmp_out[:, 6] - vR * dphi
    out = nu.zeros((len(t), 8))
    out[:, 0] = R
    out[:, 1] = vR
    out[:, 2] = vT
    out[:, 3] = phi
    out[:, 4] = dR
    out[:, 7] = dphi
    out[:, 5] = dvR
    out[:, 6] = dvT
    _parse_warnmessage(msg)
    return (out, msg)