def test_energy_conservation_unequalmasses_python(): # Test that energy is conserved for a simple problem, using Python method x= numpy.array([-1.1,0.1,1.3]) v= numpy.array([3.,2.,-5.]) m= numpy.array([1.,2.,3.]) g= wendy.nbody_python(x,v,m,0.05) E= wendy.energy(x,v,m) cnt= 0 while cnt < 100: tx,tv= next(g) assert numpy.fabs(wendy.energy(tx,tv,m)-E) < 10.**-10., "Energy not conserved during simple N-body integration" cnt+= 1 return None
def test_energy_conservation(): # Test that energy is conserved for a simple problem x = numpy.array([-1.1, 0.1, 1.3]) v = numpy.array([3., 2., -5.]) m = numpy.array([1., 1., 1.]) g = wendy.nbody(x, v, m, 0.05, approx=True, nleap=100000) E = wendy.energy(x, v, m) cnt = 0 while cnt < 100: tx, tv = next(g) assert numpy.fabs( wendy.energy(tx, tv, m) - E ) / E < 10.**-6., "Energy not conserved during approximate N-body integration" cnt += 1 return None
def test_energy_conservation_unequalmasses(): # Test that energy is conserved for a simple problem x = numpy.array([-1.1, 0.1, 1.3]) v = numpy.array([3., 2., -5.]) m = numpy.array([1., 2., 3.]) omega = 1.1 g = wendy.nbody(x, v, m, 0.05, omega=omega, approx=True, nleap=100000) E = wendy.energy(x, v, m, omega=omega) cnt = 0 while cnt < 100: tx, tv = next(g) assert numpy.fabs( wendy.energy(tx, tv, m, omega=omega) - E ) / E < 10.**-6., "Energy not conserved during approximate N-body integration with external harmonic potential" cnt += 1 return None
def test_energy_ratio(): # Test that energy ratio gives ratio of kinetic to potential energy x = numpy.array([-1.1, 0.1, 1.3]) v = numpy.array([3., 2., -5.]) m = numpy.array([1., 1., 1.]) g = wendy.nbody(x, v, m, 0.05) cnt = 0 while cnt < 10: tx, tv = next(g) Erat = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.RATIO) Epot = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.POTENTIAL) Ekin = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.KINETIC) assert Erat == Ekin / Epot, "Energy ratio should be kinetic divided potential energy" cnt += 1 return None
def test_total_energy(): # Test that total energy is sum of potential and kinetic energy x = numpy.array([-1.1, 0.1, 1.3]) v = numpy.array([3., 2., -5.]) m = numpy.array([1., 1., 1.]) g = wendy.nbody(x, v, m, 0.05) cnt = 0 while cnt < 10: tx, tv = next(g) Etot = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.TOTAL) Epot = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.POTENTIAL) Ekin = wendy.energy(tx, tv, m, energy_type=wendy.EnergyType.KINETIC) assert Etot == Epot + Ekin, "Total energy should be sum of kinetic and potential energies" cnt += 1 return None
def test_potential_energy(): # Test potential energy for a simple system x = numpy.array([-2., 0, 3.]) v = numpy.array([1, 2, 3]) m = numpy.array([.3, .3, .3]) assert (wendy.energy(x, v, m, energy_type=wendy.EnergyType.POTENTIAL) - 10.) < 1e-12, "Potential energy not correctly calculated"
def test_kinetic_energy(): # Test that kinetic energy is 0 for 0 velocities x = numpy.array([-1.1, 0.1, 1.3]) v = numpy.array([0, 0, 0]) m = numpy.array([1., 1., 1.]) assert wendy.energy( x, v, m, energy_type=wendy.EnergyType.KINETIC ) == 0, "Kinetic energy should be zero when v=0 for all particles." # Test that kinetic energy is given by 1/2 mv^2 x = numpy.array([-1, 0, 1]) v = numpy.array([1.2, 2.3, -4.2]) m = numpy.array([.3, .3, .3]) ke = numpy.sum(0.5 * m * v**2) assert ((wendy.energy(x, v, m, energy_type=wendy.EnergyType.KINETIC) - ke) < 1e-12), "Kinetic energy should be 1/2 mv^2."
def test_samex(): # Test that the code works if two particles are at the exact same position # middle ones setup such that they end up in the same place for the first # force evaluation x = numpy.array( [-1.1, -2. * 0.05 / 2. / 10000, 0.3 * 0.05 / 2. / 10000, 1.3]) v = numpy.array([3., 2., -.3, -5.]) m = numpy.array([1., 1., 1., 1.]) g = wendy.nbody(x, v, m, 0.05, approx=True, nleap=10000) E = wendy.energy(x, v, m) cnt = 0 while cnt < 1: tx, tv = next(g) assert numpy.fabs( wendy.energy(tx, tv, m) - E ) / E < 10.**-6., "Energy not conserved during approximate N-body integration" cnt += 1 return None
def test_energy_conservation_sech2disk_manyparticles(): # Test that energy is conserved for a self-gravitating disk N= 101 totmass= 1. sigma= 1. zh= 2.*sigma**2./totmass x= numpy.arctanh(2.*numpy.random.uniform(size=N)-1)*zh v= numpy.random.normal(size=N)*sigma v-= numpy.mean(v) # stabilize m= numpy.ones_like(x)/N*(1.+0.1*(2.*numpy.random.uniform(size=N)-1)) g= wendy.nbody(x,v,m,0.05) E= wendy.energy(x,v,m) cnt= 0 while cnt < 100: tx,tv= next(g) assert numpy.fabs(wendy.energy(tx,tv,m)-E) < 10.**-10., "Energy not conserved during simple N-body integration" cnt+= 1 return None
def test_energy_conservation_sech2disk_manyparticles(): # Test that energy is conserved for a self-gravitating disk N = 101 totmass = 1. sigma = 1. zh = 2. * sigma**2. / totmass x = numpy.arctanh(2. * numpy.random.uniform(size=N) - 1) * zh v = numpy.random.normal(size=N) * sigma v -= numpy.mean(v) # stabilize m = numpy.ones_like(x) / N * (1. + 0.1 * (2. * numpy.random.uniform(size=N) - 1)) omega = 1.1 g = wendy.nbody(x, v, m, 0.05, omega=omega, approx=True, nleap=1000) E = wendy.energy(x, v, m, omega=omega) cnt = 0 while cnt < 100: tx, tv = next(g) assert numpy.fabs( wendy.energy(tx, tv, m, omega=omega) - E ) / E < 10.**-6., "Energy not conserved during approximate N-body integration with external harmonic potential" cnt += 1 return None
def test_energy_individual(): # Simple test that the individual energies are calculated correctly x= numpy.array([-1.1,0.1,1.3]) v= numpy.array([3.,2.,-5.]) m= numpy.array([1.,2.,3.]) E= wendy.energy(x,v,m,individual=True) assert numpy.fabs(E[0]-m[0]*v[0]**2./2.-m[0]*(m[1]*numpy.fabs(x[0]-x[1]) +m[2]*numpy.fabs(x[0]-x[2]))) < 10.**-10 assert numpy.fabs(E[1]-m[1]*v[1]**2./2.-m[1]*(m[0]*numpy.fabs(x[0]-x[1]) +m[2]*numpy.fabs(x[2]-x[1]))) < 10.**-10 assert numpy.fabs(E[2]-m[2]*v[2]**2./2.-m[2]*(m[0]*numpy.fabs(x[0]-x[2]) +m[1]*numpy.fabs(x[2]-x[1]))) < 10.**-10 return None
def test_notracermasses(): # approx should work with tracer sheets # Test that energy is conserved for a self-gravitating disk N = 101 totmass = 1. sigma = 1. zh = 2. * sigma**2. / totmass x = numpy.arctanh(2. * numpy.random.uniform(size=N) - 1) * zh v = numpy.random.normal(size=N) * sigma v -= numpy.mean(v) # stabilize m = numpy.ones_like(x) / N * (1. + 0.1 * (2. * numpy.random.uniform(size=N) - 1)) m[N // 2:] = 0. m *= 2. g = wendy.nbody(x, v, m, 0.05, approx=True, nleap=1000) E = wendy.energy(x, v, m) cnt = 0 while cnt < 100: tx, tv = next(g) assert numpy.fabs( wendy.energy(tx, tv, m) - E ) / E < 10.**-6., "Energy not conserved during approximate N-body integration with some tracer particles" cnt += 1 return None