def test_isotropic_hernquist_incompatibleunits(): pot= potential.HernquistPotential(amp=2.,a=1.3,ro=9.,vo=210.) with pytest.raises(RuntimeError): dfh= isotropicHernquistdf(pot=pot,ro=8.,vo=210.) with pytest.raises(RuntimeError): dfh= isotropicHernquistdf(pot=pot,ro=9.,vo=230.) with pytest.raises(RuntimeError): dfh= isotropicHernquistdf(pot=pot,ro=8.,vo=230.) return None
def test_isotropic_hernquist_meanvr_directint(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) tol= 1e-8 check_meanvr_directint(dfh,pot,tol,beta=0.,rmin=pot._scale/10., rmax=pot._scale*10.,bins=31) return None
def test_isotropic_hernquist_singlerphi_is_atsinglephi(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(R=1.3,z=0.,phi=numpy.pi-0.3,n=100000) assert numpy.all(numpy.fabs(samp.phi()-numpy.pi+0.3) < 1e-8), 'Sampling a spherical distribution function at a single r and phi oes not produce orbits at a single phi' return None
def compare_dens_nbody_spherical(): N = int(1e6) Mh = 11. ah = 50. / 8. m = Mh / N factor = 1. nsamp = 10 Norder = 10 hern = potential.HernquistPotential(amp=2 * Mh, a=ah) hern.turn_physical_off() hdf = df.isotropicHernquistdf(hern) samples = [hdf.sample(n=N) for i in range(nsamp)] positions = numpy.array( [[samples[i].x(), samples[i].y(), samples[i].z() * factor] for i in range(nsamp)]) c = numpy.zeros((nsamp, Norder, 1, 1)) s = numpy.zeros((nsamp, Norder, 1, 1)) for i in range(nsamp): c[i], s[i] = potential.scf_compute_coeffs_spherical_nbody( m=m * numpy.ones(N), pos=positions[i], N=Norder, a=ah) cc, ss = potential.scf_compute_coeffs_spherical(N=Norder, a=ah, dens=hern.dens) # Check that the difference between the coefficients is within the standard deviation assert (cc - numpy.mean(c, axis=0) < numpy.std(c, axis=0)).all()
def test_isotropic_hernquist_unittransfer(): from galpy.util import conversion ro, vo= 9., 210. pot= potential.HernquistPotential(amp=2.,a=1.3,ro=ro,vo=vo) dfh= isotropicHernquistdf(pot=pot) phys= conversion.get_physical(dfh,include_set=True) assert phys['roSet'], "sphericaldf's ro not set when that of the underlying potential is set" assert phys['voSet'], "sphericaldf's vo not set when that of the underlying potential is set" assert numpy.fabs(phys['ro']-ro) < 1e-8, "Potential's unit system not correctly transfered to sphericaldf's" assert numpy.fabs(phys['vo']-vo) < 1e-8, "Potential's unit system not correctly transfered to sphericaldf's" # Following should not be on pot= potential.HernquistPotential(amp=2.,a=1.3) dfh= isotropicHernquistdf(pot=pot) phys= conversion.get_physical(dfh,include_set=True) assert not phys['roSet'], "sphericaldf's ro set when that of the underlying potential is not set" assert not phys['voSet'], "sphericaldf's vo set when that of the underlying potential is not set" return None
def test_isotropic_hernquist_unitsofsamples(): from galpy.util import conversion ro, vo= 9., 210. pot= potential.HernquistPotential(amp=2.,a=1.3,ro=ro,vo=vo) dfh= isotropicHernquistdf(pot=pot) samp= dfh.sample(n=100) assert conversion.get_physical(samp,include_set=True)['roSet'], 'Orbit samples from spherical DF with units on do not have units on' assert conversion.get_physical(samp,include_set=True)['voSet'], 'Orbit samples from spherical DF with units on do not have units on' assert numpy.fabs(conversion.get_physical(samp,include_set=True)['ro']-ro) < 1e-8, 'Orbit samples from spherical DF with units on do not have correct ro' assert numpy.fabs(conversion.get_physical(samp,include_set=True)['vo']-vo) < 1e-8, 'Orbit samples from spherical DF with units on do not have correct vo' # Also test a case where they should be off pot= potential.HernquistPotential(amp=2.,a=1.3) dfh= isotropicHernquistdf(pot=pot) samp= dfh.sample(n=100) assert not conversion.get_physical(samp,include_set=True)['roSet'], 'Orbit samples from spherical DF with units off do not have units off' assert not conversion.get_physical(samp,include_set=True)['voSet'], 'Orbit samples from spherical DF with units off do not have units off' return None
def test_isotropic_hernquist_sigmar_directint_forcevmoment(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) tol= 1e-5 check_sigmar_against_jeans_directint_forcevmoment(dfh,pot,tol,beta=0., rmin=pot._scale/10., rmax=pot._scale*10., bins=31) return None
def test_isotropic_hernquist_dens_directint(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) tol= 1e-8 check_dens_directint(dfh,pot,tol, lambda r: pot.dens(r,0)/(2.3/2.), # need to divide by mass rmin=pot._scale/10., rmax=pot._scale*10.,bins=31) return None
def test_isotropic_hernquist_beta(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(n=1000000) tol= 6*1e-2 check_beta(samp,pot,tol,beta=0., rmin=pot._scale/10.,rmax=pot._scale*10.,bins=31) return None
def test_isotropic_hernquist_sigmar(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(n=300000) tol= 0.05 check_sigmar_against_jeans(samp,pot,tol,beta=0., rmin=pot._scale/10.,rmax=pot._scale*10.,bins=31) return None
def test_isotropic_hernquist_singler_sigmar(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) for r in [0.3,1.3,2.3]: samp= dfh.sample(R=r,z=0.,n=100000) tol= 0.01 check_sigmar_against_jeans(samp,pot,tol,beta=0., rmin=r-0.1,rmax=r+0.1,bins=1) return None
def test_isotropic_hernquist_dens_massprofile(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(n=100000) tol= 5*1e-3 check_spherical_massprofile(samp, lambda r: pot.mass(r)\ /pot.mass(numpy.amax(samp.r()), ), tol,skip=1000) return None
def test_scf_compute_nbody_twopowertriaxial(): N = int(1e5) Mh = 11. ah = 50. / 8. m = Mh / N yfactor = 1.5 zfactor = 2.5 nsamp = 10 Norder = 10 Lorder = 10 hern = potential.HernquistPotential(amp=2 * Mh, a=ah) hern.turn_physical_off() hdf = df.isotropicHernquistdf(hern) numpy.random.seed(2) samp = [hdf.sample(n=N) for i in range(nsamp)] positions = numpy.array( [[samp[i].x(), samp[i].y() * yfactor, samp[i].z() * zfactor] for i in range(nsamp)]) # This is an triaxial Hernquist profile with the same mass as the above tptp = potential.TwoPowerTriaxialPotential(amp=2. * Mh / yfactor / zfactor, a=ah, alpha=1., beta=4., b=yfactor, c=zfactor) tptp.turn_physical_off() cc, ss = potential.scf_compute_coeffs(tptp.dens, Norder, Lorder, a=ah) c, s = numpy.zeros((2, nsamp, Norder, Lorder, Lorder)) for i, p in enumerate(positions): c[i], s[i] = potential.scf_compute_coeffs_nbody(p, Norder, Lorder, mass=m * numpy.ones(N), a=ah) # Check that the difference between the coefficients is within two standard deviations assert (cc - (numpy.mean(c, axis=0)) <= (2. * numpy.std(c, axis=0))).all() # Repeat test for single mass c, s = numpy.zeros((2, nsamp, Norder, Lorder, Lorder)) for i, p in enumerate(positions): c[i], s[i] = potential.scf_compute_coeffs_nbody(p, Norder, Lorder, mass=m, a=ah) assert (cc - (numpy.mean(c, axis=0)) <= (2. * numpy.std(c, axis=0))).all() return None
def test_isotropic_hernquist_givenr_are_atgivenr(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) r= numpy.linspace(0.1,10.,1001) theta= numpy.random.uniform(size=len(r))*numpy.pi # n should be ignored in the following samp= dfh.sample(R=r*numpy.sin(theta),z=r*numpy.cos(theta),n=100000) assert len(samp) == len(r), 'Length of sample with given r array is not equal to length of r' assert numpy.all(numpy.fabs(samp.r()-r) < 1e-8), 'Sampling a spherical distribution function at given r does not produce orbits at these given r' assert numpy.all(numpy.fabs(samp.R()-r*numpy.sin(theta)) < 1e-8), 'Sampling a spherical distribution function at given R does not produce orbits at these given R' assert numpy.all(numpy.fabs(samp.z()-r*numpy.cos(theta)) < 1e-8), 'Sampling a spherical distribution function at given z does not produce orbits at these given z' return None
def test_isotropic_hernquist_diffcalls(): from galpy.orbit import Orbit pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) # R,vR... vs. E R,vR,vT,z,vz,phi= 1.1,0.3,0.2,0.9,-0.2,2.4 # Calculate E directly assert numpy.fabs(dfh(R,vR,vT,z,vz,phi)-dfh((pot(R,z)+0.5*(vR**2.+vT**2.+vz**2.),))) < 1e-8, 'Calling the isotropic Hernquist DF with R,vR,... or E[R,vR,...] does not give the same answer' # Also L assert numpy.fabs(dfh(R,vR,vT,z,vz,phi)-dfh((pot(R,z)+0.5*(vR**2.+vT**2.+vz**2.),numpy.sqrt(numpy.sum(Orbit([R,vR,vT,z,vz,phi]).L()**2.))))) < 1e-8, 'Calling the isotropic Hernquist DF with R,vR,... or E[R,vR,...] does not give the same answer' # Also as orbit assert numpy.fabs(dfh(R,vR,vT,z,vz,phi)-dfh(Orbit([R,vR,vT,z,vz,phi]))) < 1e-8, 'Calling the isotropic Hernquist DF with R,vR,... or E[R,vR,...] does not give the same answer' return None
def test_isotropic_hernquist_singler_is_atrandomphi(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(R=1.3,z=0.,n=100000) tol= 1e-2 check_azimuthal_symmetry(samp,0,tol) check_azimuthal_symmetry(samp,1,tol) check_azimuthal_symmetry(samp,2,tol) check_azimuthal_symmetry(samp,3,tol) check_azimuthal_symmetry(samp,4,tol) check_azimuthal_symmetry(samp,5,tol) check_azimuthal_symmetry(samp,6,tol) return None
def setup_class(cls): """Setup fixtures for testing.""" super().setup_class() # make potential cls.mass = 1e12 * u.solMass hernquist_pot = HernquistPotential(amp=2 * cls.mass) hernquist_pot.turn_physical_on() # force units cls.potential = hernquist_pot cls.df = isotropicHernquistdf(hernquist_pot) cls.df.turn_physical_on() cls.inst = cls.obj(GalpyPotentialWrapper(cls.potential))
def test_isotropic_hernquist_phasespacesamples_vs_orbitsamples(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp_orbits= dfh.sample(n=1000) # Reset seed such that we should get the same numpy.random.seed(10) samp_RvR= dfh.sample(n=1000,return_orbit=False) assert numpy.all(numpy.fabs(samp_orbits.R()-samp_RvR[0]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' assert numpy.all(numpy.fabs(samp_orbits.vR()-samp_RvR[1]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' assert numpy.all(numpy.fabs(samp_orbits.vT()-samp_RvR[2]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' assert numpy.all(numpy.fabs(samp_orbits.z()-samp_RvR[3]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' assert numpy.all(numpy.fabs(samp_orbits.vz()-samp_RvR[4]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' assert numpy.all(numpy.fabs(samp_orbits.phi()-samp_RvR[5]) < 1e-8), 'Sampling R,vR,... from spherical DF does not give the same as sampling equivalent orbits' return None
def test_isotropic_hernquist_dens_spherically_symmetric(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) numpy.random.seed(10) samp= dfh.sample(n=100000) # Check spherical symmetry for different harmonics l,m tol= 1e-2 check_spherical_symmetry(samp,0,0,tol) check_spherical_symmetry(samp,1,0,tol) check_spherical_symmetry(samp,1,-1,tol) check_spherical_symmetry(samp,1,1,tol) check_spherical_symmetry(samp,2,0,tol) check_spherical_symmetry(samp,2,-1,tol) check_spherical_symmetry(samp,2,-2,tol) check_spherical_symmetry(samp,2,1,tol) check_spherical_symmetry(samp,2,2,tol) # and some higher order ones check_spherical_symmetry(samp,3,1,tol) check_spherical_symmetry(samp,9,-6,tol) return None
def compare_dens_nbody(): N = int(1e5) Mh = 11. ah = 50. / 8. m = Mh / N factor = 1. nsamp = 10 Norder = 10 Lorder = 10 hern = potential.HernquistPotential(amp=2 * Mh, a=ah) hern.turn_physical_off() hdf = df.isotropicHernquistdf(hern) samp = [hdf.sample(n=N) for i in range(nsamp)] positions = numpy.array([[samp[i].x(), samp[i].y(), samp[i].z() * factor] for i in range(nsamp)]) tptp = potential.TwoPowerTriaxialPotential(amp=2. * Mh, a=ah, alpha=1., beta=4., b=1., c=factor) tptp.turn_physical_off() cc, ss = potential.scf_compute_coeffs(tptp.dens, Norder, Lorder, a=ah) c, s = numpy.zeros((2, nsamp, Norder, Lorder, Lorder)) for i, p in enumerate(positions): c[i], s[i] = potential.scf_compute_coeffs_nbody(p, m * numpy.ones(N) * factor, Norder, Lorder, a=ah) # Check that the difference between the coefficients is within two standard deviations assert (cc - (numpy.mean(c, axis=0)) <= (2. * numpy.std(c, axis=0))).all()
def test_isotropic_hernquist_nopot(): with pytest.raises(AssertionError) as excinfo: dfh= isotropicHernquistdf() assert str(excinfo.value) == 'pot= must be potential.HernquistPotential', 'Error message when not supplying the potential is incorrect' return None
def test_isotropic_hernquist_energyoutofbounds(): pot= potential.HernquistPotential(amp=2.3,a=1.3) dfh= isotropicHernquistdf(pot=pot) assert numpy.all(numpy.fabs(dfh((numpy.arange(0.1,10.,0.1),))) < 1e-8), 'Evaluating the isotropic Hernquist DF at E > 0 does not give zero' assert numpy.all(numpy.fabs(dfh((pot(0,0)-1e-4,))) < 1e-8), 'Evaluating the isotropic Hernquist DF at E < -GM/a does not give zero' return None
def test_isotropic_hernquist_wrongpot(): pot= potential.JaffePotential(amp=2.,a=1.3) with pytest.raises(AssertionError) as excinfo: dfh= isotropicHernquistdf(pot=pot) assert str(excinfo.value) == 'pot= must be potential.HernquistPotential', 'Error message when not supplying the potential is incorrect' return None