def __init__(self, orbit, amp=1., GM=.06, ro=None, vo=None, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass GM - 'mass' of the object (degenerate with amp, don't use both); can be a Quantity with units of mass or Gxmass Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional; can be Quantity) ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp * GM, ro=ro, vo=vo, amp_units='mass') if _APY_LOADED and isinstance(softening_length, units.Quantity): softening_length = softening_length.to(units.kpc).value / self._ro # Make sure we aren't getting physical outputs self._orb = copy.deepcopy(orbit) self._orb.turn_physical_off() if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening self.isNonAxi = True return None
def __init__(self, orbit, amp=1., GM=.06, normalize=False, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. (at t=0) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp) self._gm = GM self._orb = orbit if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening if normalize: self.normalize(normalize)
def __init__(self, orbit, amp=1., GM=.06, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp) self._gm = GM self._orb = orbit if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening self.isNonAxi = True return None
def __init__(self,orbit,amp=1.,GM=.06,normalize=False, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. (at t=0) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp) self._gm= GM self._orb= orbit if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) return None
def __init__(self,orbit,amp=1.,GM=.06, ro=None,vo=None, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass GM - 'mass' of the object (degenerate with amp, don't use both); can be a Quantity with units of mass or Gxmass Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional; can be Quantity) ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp*GM,ro=ro,vo=vo,amp_units='mass') if _APY_LOADED and isinstance(softening_length,units.Quantity): softening_length= softening_length.to(units.kpc).value/self._ro # Make sure we aren't getting physical outputs self._orb= copy.deepcopy(orbit) self._orb.turn_physical_off() if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening self.isNonAxi= True return None
def __init__(self,orbit,amp=1.,GM=.06, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp) self._gm= GM self._orb= orbit if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening self.isNonAxi= True return None
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object .. math:: \\Phi(R,z,\\phi,t) = -\\mathrm{amp}\\,GM\\,S(d) where :math:`d` is the distance between :math:`(R,z,\\phi)` and the moving object at time :math:`t` and :math:`S(\\cdot)` is a softening kernel. In the case of Plummer softening, this kernel is .. math:: S(d) = \\frac{1}{\\sqrt{d^2+\\mathrm{softening\_length}^2}} Plummer is currently the only implemented softening. """ def __init__(self,orbit,amp=1.,GM=.06, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp) self._gm= GM self._orb= orbit if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening self.isNonAxi= True return None def _evaluate(self,R,z,phi=0.,t=0.): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ #Calculate distance dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) #Evaluate potential return -self._gm*self._softening.potential(dist) def _Rforce(self,R,z,phi=0.,t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*(nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self,R,z,phi=0.,t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*zd/dist*self._softening(dist) def _phiforce(self,R,z,phi=0.,t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self,R,z,phi=0.,t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) return self._gm*self._softening.density(dist)
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object GM phi(R,z) = - --------------------------------- distance """ def __init__(self,orbit,amp=1.,GM=.06,normalize=False, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. (at t=0) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp) self._gm= GM self._orb= orbit if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening if normalize: self.normalize(normalize) def _evaluate(self,R,z,phi=0.,t=0.,dR=0,dphi=0): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ if dR == 0 and dphi == 0: #Calculate distance dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) #Evaluate potential return -self._gm*self._softening.potential(dist) elif dR == 1 and dphi == 0: return -self._Rforce(R,z,phi=phi,t=t) elif dR == 0 and dphi == 1: return -self._phiforce(R,z,phi=phi,t=t) def _Rforce(self,R,z,phi=0.,t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*(nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self,R,z,phi=0.,t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*zd/dist*self._softening(dist) def _phiforce(self,R,z,phi=0.,t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return self._gm*R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self,R,z,phi=0.,t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) return self._gm*self._softening.density(dist)
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object .. math:: \\Phi(R,z,\\phi,t) = -\\mathrm{amp}\\,GM\\,S(d) where :math:`d` is the distance between :math:`(R,z,\\phi)` and the moving object at time :math:`t` and :math:`S(\\cdot)` is a softening kernel. In the case of Plummer softening, this kernel is .. math:: S(d) = \\frac{1}{\\sqrt{d^2+\\mathrm{softening\_length}^2}} Plummer is currently the only implemented softening. """ def __init__(self, orbit, amp=1., GM=.06, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp) self._gm = GM self._orb = orbit if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening self.isNonAxi = True return None def _evaluate(self, R, z, phi=0., t=0.): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ #Calculate distance dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) #Evaluate potential return -self._gm * self._softening.potential(dist) def _Rforce(self, R, z, phi=0., t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm*(nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self, R, z, phi=0., t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm * zd / dist * self._softening(dist) def _phiforce(self, R, z, phi=0., t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm*R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self, R, z, phi=0., t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) return self._gm * self._softening.density(dist)
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object .. math:: \\Phi(R,z,\\phi,t) = -\\mathrm{amp}\\,GM\\,S(d) where :math:`d` is the distance between :math:`(R,z,\\phi)` and the moving object at time :math:`t` and :math:`S(\\cdot)` is a softening kernel. In the case of Plummer softening, this kernel is .. math:: S(d) = \\frac{1}{\\sqrt{d^2+\\mathrm{softening\_length}^2}} Plummer is currently the only implemented softening. """ def __init__(self,orbit,amp=1.,GM=.06, ro=None,vo=None, softening=None, softening_model='plummer',softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass GM - 'mass' of the object (degenerate with amp, don't use both); can be a Quantity with units of mass or Gxmass Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional; can be Quantity) ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self,amp=amp*GM,ro=ro,vo=vo,amp_units='mass') if _APY_LOADED and isinstance(softening_length,units.Quantity): softening_length= softening_length.to(units.kpc).value/self._ro # Make sure we aren't getting physical outputs self._orb= copy.deepcopy(orbit) self._orb.turn_physical_off() if softening is None: if softening_model.lower() == 'plummer': self._softening= PlummerSoftening(softening_length=softening_length) else: self._softening= softening self.isNonAxi= True return None def _evaluate(self,R,z,phi=0.,t=0.): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ #Calculate distance dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) #Evaluate potential return -self._softening.potential(dist) def _Rforce(self,R,z,phi=0.,t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return (nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self,R,z,phi=0.,t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return zd/dist*self._softening(dist) def _phiforce(self,R,z,phi=0.,t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd,yd,zd,dist)= _cyldiffdist(self._orb.R(t),self._orb.phi(t), self._orb.z(t), R,phi,z) #Evaluate force return R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self,R,z,phi=0.,t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist= _cyldist(R,phi,z, self._orb.R(t),self._orb.phi(t),self._orb.z(t)) return self._softening.density(dist)
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object .. math:: \\Phi(R,z,\\phi,t) = -\\mathrm{amp}\\,GM\\,S(d) where :math:`d` is the distance between :math:`(R,z,\\phi)` and the moving object at time :math:`t` and :math:`S(\\cdot)` is a softening kernel. In the case of Plummer softening, this kernel is .. math:: S(d) = \\frac{1}{\\sqrt{d^2+\\mathrm{softening\_length}^2}} Plummer is currently the only implemented softening. """ def __init__(self, orbit, amp=1., GM=.06, ro=None, vo=None, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass GM - 'mass' of the object (degenerate with amp, don't use both); can be a Quantity with units of mass or Gxmass Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional; can be Quantity) ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp * GM, ro=ro, vo=vo, amp_units='mass') if _APY_LOADED and isinstance(softening_length, units.Quantity): softening_length = softening_length.to(units.kpc).value / self._ro # Make sure we aren't getting physical outputs self._orb = copy.deepcopy(orbit) self._orb.turn_physical_off() if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening self.isNonAxi = True return None def _evaluate(self, R, z, phi=0., t=0.): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ #Calculate distance dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) #Evaluate potential return -self._softening.potential(dist) def _Rforce(self, R, z, phi=0., t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return (nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self, R, z, phi=0., t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return zd / dist * self._softening(dist) def _phiforce(self, R, z, phi=0., t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self, R, z, phi=0., t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) return self._softening.density(dist)
class MovingObjectPotential(Potential): """Class that implements the potential coming from a moving object GM phi(R,z) = - --------------------------------- distance """ def __init__(self, orbit, amp=1., GM=.06, normalize=False, softening=None, softening_model='plummer', softening_length=0.01): """ NAME: __init__ PURPOSE: initialize a MovingObjectPotential INPUT: orbit - the Orbit of the object (Orbit object) amp= - amplitude to be applied to the potential (default: 1) GM - 'mass' of the object (degenerate with amp) normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. (at t=0) Softening: either provide a) softening= with a ForceSoftening-type object b) softening_model= type of softening to use ('plummer') softening_length= (optional) OUTPUT: (none) HISTORY: 2011-04-10 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp) self._gm = GM self._orb = orbit if softening is None: if softening_model.lower() == 'plummer': self._softening = PlummerSoftening( softening_length=softening_length) else: self._softening = softening if normalize: self.normalize(normalize) def _evaluate(self, R, z, phi=0., t=0., dR=0, dphi=0): """ NAME: _evaluate PURPOSE: evaluate the potential at R,z, phi INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: Phi(R,z,phi) HISTORY: 2010104-10 - Started - Bovy (NYU) """ if dR == 0 and dphi == 0: #Calculate distance dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) #Evaluate potential return -self._gm * self._softening.potential(dist) elif dR == 1 and dphi == 0: return -self._Rforce(R, z, phi=phi, t=t) elif dR == 0 and dphi == 1: return -self._phiforce(R, z, phi=phi, t=t) def _Rforce(self, R, z, phi=0., t=0.): """ NAME: _Rforce PURPOSE: evaluate the radial force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the radial force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm*(nu.cos(phi)*xd+nu.sin(phi)*yd)/dist\ *self._softening(dist) def _zforce(self, R, z, phi=0., t=0.): """ NAME: _zforce PURPOSE: evaluate the vertical force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the vertical force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm * zd / dist * self._softening(dist) def _phiforce(self, R, z, phi=0., t=0.): """ NAME: _phiforce PURPOSE: evaluate the azimuthal force for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the azimuthal force HISTORY: 2011-04-10 - Written - Bovy (NYU) """ #Calculate distance and difference vector (xd, yd, zd, dist) = _cyldiffdist(self._orb.R(t), self._orb.phi(t), self._orb.z(t), R, phi, z) #Evaluate force return self._gm*R*(nu.cos(phi)*yd-nu.sin(phi)*xd)/dist\ *self._softening(dist) def _dens(self, R, z, phi=0., t=0.): """ NAME: _dens PURPOSE: evaluate the density for this potential INPUT: R - Galactocentric cylindrical radius z - vertical height phi - azimuth t - time OUTPUT: the density HISTORY: 2010-08-08 - Written - Bovy (NYU) """ dist = _cyldist(R, phi, z, self._orb.R(t), self._orb.phi(t), self._orb.z(t)) return self._gm * self._softening.density(dist)