def setUp(self): L = 1. # box size self.n = 50 # number of points self.dx = L / self.n self.domain = DomainLimits(dim=3, xmin=0, xmax=1.) self.bound = Reflect3d(self.domain) q = np.arange(self.n, dtype=np.float64) * self.dx + 0.5 * self.dx Nq = q.size N = Nq * Nq * Nq # generate the grid of particle positions x = np.zeros(N) y = np.zeros(N) z = np.zeros(N) part = 0 for i in xrange(Nq): for j in xrange(Nq): for k in xrange(Nq): x[part] = q[i] y[part] = q[j] z[part] = q[k] part += 1 # # put particles in hilbert order # order = 21 # fac = 1 << order # pos = np.array([x, y, z])*fac # keys = np.array([py_hilbert_key_3d(vec.astype(np.int32), order) for vec in pos.T], dtype=np.int64) # indices = np.argsort(keys) # # x[:] = x[indices] # y[:] = y[indices] # z[:] = z[indices] # store particles self.particles = ParticleContainer(N) self.particles.register_property(N, 'position-z', 'double') self.particles.register_property(N, 'velocity-z', 'double') self.particles.register_property(N, 'com-z', 'double') xp = self.particles["position-x"] yp = self.particles["position-y"] zp = self.particles["position-z"] xp[:] = x yp[:] = y zp[:] = z
def test_extract_particles(self): """ Tests the extract particles function. """ pc = ParticleContainer(10) pc['position-x'][:] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] pc['position-y'][:] = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] pc['tag'][:] = [0, 0, 1, 1, 1, 0, 4, 0, 1, 5] indices = np.array([5, 1, 7, 3, 9]) pc2 = pc.extract_items(indices) self.assertEqual(check_array(pc2['position-x'], [6, 2, 8, 4, 10]), True) self.assertEqual(check_array(pc2['position-y'], [5, 9, 3, 7, 1]), True) self.assertEqual(check_array(pc2['tag'], [0, 0, 0, 1, 5]), True)
def test_constructor(self): """Test the constructor.""" pc = ParticleContainer(10) self.assertEqual(pc.get_number_of_particles(), 10) expected = [ 'position-x', 'position-y', 'mass', 'momentum-x', 'momentum-y', 'energy', 'density', 'velocity-x', 'velocity-y', 'pressure', 'key', 'tag', 'type', 'process', 'com-x', 'com-y', 'volume' ] self.assertItemsEqual(pc.properties.keys(), expected) for field_name in pc.properties.keys(): self.assertEqual(pc[field_name].size, 10)
def test_remove_tagged_particles(self): """ Tests the remove_tagged_particles function. """ pc = ParticleContainer(4) pc['position-x'][:] = [1., 2., 3., 4.] pc['position-y'][:] = [0., 1., 2., 3.] pc['mass'][:] = [1., 1., 1., 1.] pc['tag'][:] = [1, 0, 1, 1] pc.remove_tagged_particles(0) self.assertEqual(pc.get_number_of_particles(), 3) self.assertEqual(check_array(pc['position-x'], [1., 4., 3.]), True) self.assertEqual(check_array(pc['position-y'], [0., 3., 2.]), True) self.assertEqual(check_array(pc['mass'], [1., 1., 1.]), True) self.assertEqual(check_array(pc['tag'], [1, 1, 1]), True)
def setUp(self): L = 1. # box size n = 50 # number of points self.dx = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries x = (np.arange(n + 6, dtype=np.float64) - 3) * self.dx + 0.5 * self.dx # generate the grid of particle positions X, Y = np.meshgrid(x, x) Y = np.flipud(Y) x = X.flatten() y = Y.flatten() # find all particles inside the unit box indices = (((0. <= x) & (x <= 1.)) & ((0. <= y) & (y <= 1.))) x_in = x[indices] y_in = y[indices] self.num_real = x_in.size self.particles = ParticleContainer(x_in.size) # store ghost particles xp = self.particles["position-x"] yp = self.particles["position-y"] xp[:] = x_in yp[:] = y_in # store ghost particles x_out = x[~indices] y_out = y[~indices] self.num_ghost = x_out.size self.particles.extend(x_out.size) tag = self.particles["tag"] xp = self.particles["position-x"] yp = self.particles["position-y"] xp[self.num_real:] = x_out yp[self.num_real:] = y_out tag[self.num_real:] = ParticleTAGS.Ghost
def test_align_particles(self): """ Tests the align particles function. """ pc = ParticleContainer(10) pc['position-x'][:] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] pc['position-y'][:] = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] pc['tag'][:] = [0, 0, 1, 1, 1, 0, 4, 0, 1, 5] pc.align_particles() self.assertEqual( check_array(pc['position-x'], [1, 2, 6, 8, 5, 3, 7, 4, 9, 10]), True) self.assertEqual( check_array(pc['position-y'], [10, 9, 5, 3, 6, 8, 4, 7, 2, 1]), True) # should do nothing pc['tag'][:] = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1] pc.align_particles() self.assertEqual( check_array(pc['position-x'], [1, 2, 6, 8, 5, 3, 7, 4, 9, 10]), True) self.assertEqual( check_array(pc['position-y'], [10, 9, 5, 3, 6, 8, 4, 7, 2, 1]), True)
def test_append_container(self): """ Tests the append parray function. """ pc1 = ParticleContainer(5) pc1['position-x'][:] = [1, 2, 3, 4, 5] pc1['position-y'][:] = [10, 9, 8, 7, 6] pc1['tag'][:] = [0, 0, 0, 0, 0] pc2 = ParticleContainer(5) pc2['position-x'][:] = [6, 7, 8, 9, 10] pc2['position-y'][:] = [5, 4, 3, 2, 1] pc2['tag'][:] = [1, 1, 1, 1, 1] pc1.append_container(pc2) self.assertEqual( check_array(pc1['position-x'], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), True) self.assertEqual( check_array(pc1['position-y'], [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]), True) self.assertEqual( check_array(pc1['tag'], [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]), True)
def test_remove_items(self): """"Test the discard ghost and export particles function""" pc = ParticleContainer(4) pc['position-x'][:] = [5.0, 2.0, 1.0, 4.0] pc['position-y'][:] = [2.0, 6.0, 3.0, 1.0] pc['mass'][:] = [1.0, 2.0, 3.0, 4.0] pc['momentum-x'][:] = [0.0, 1.0, 2.0, 3.0] pc['momentum-y'][:] = [1.0, 1.0, 1.0, 1.0] pc['energy'][:] = [1.0, 1.0, 1.0, 1.0] # remove items with indicies 0 and 1 remove_arr = np.array([0, 1], dtype=np.int) pc.remove_items(remove_arr) self.assertEqual(pc.get_number_of_particles(), 2) self.assertEqual(check_array(pc['position-x'], [1.0, 4.0]), True) self.assertEqual(check_array(pc['position-y'], [3.0, 1.0]), True) self.assertEqual(check_array(pc['mass'], [3.0, 4.0]), True) self.assertEqual(check_array(pc['momentum-x'], [2.0, 3.0]), True) self.assertEqual(check_array(pc['momentum-y'], [1.0, 1.0]), True) self.assertEqual(check_array(pc['energy'], [1.0, 1.0]), True) # now try invalid operations to make sure errors are raised remove = np.arange(10, dtype=np.int) self.assertRaises(ValueError, pc.remove_items, remove) remove = np.array([2], dtype=np.int) pc.remove_items(remove) # make sure no change has occured self.assertEqual(pc.get_number_of_particles(), 2) self.assertEqual(check_array(pc['position-x'], [1.0, 4.0]), True) self.assertEqual(check_array(pc['position-y'], [3.0, 1.0]), True) self.assertEqual(check_array(pc['mass'], [3.0, 4.0]), True) self.assertEqual(check_array(pc['momentum-x'], [2.0, 3.0]), True) self.assertEqual(check_array(pc['momentum-y'], [1.0, 1.0]), True) self.assertEqual(check_array(pc['energy'], [1.0, 1.0]), True)
class TestVoronoiMesh3dBox(unittest.TestCase): def setUp(self): L = 1. # box size self.n = 50 # number of points self.dx = L/self.n self.domain = DomainLimits(dim=3, xmin=0, xmax=1.) self.bound = Reflect3d(self.domain) q = np.arange(self.n, dtype=np.float64)*self.dx + 0.5*self.dx Nq = q.size N = Nq*Nq*Nq # generate the grid of particle positions x = np.zeros(N) y = np.zeros(N) z = np.zeros(N) part = 0 for i in xrange(Nq): for j in xrange(Nq): for k in xrange(Nq): x[part] = q[i] y[part] = q[j] z[part] = q[k] part += 1 # # put particles in hilbert order # order = 21 # fac = 1 << order # pos = np.array([x, y, z])*fac # keys = np.array([py_hilbert_key_3d(vec.astype(np.int32), order) for vec in pos.T], dtype=np.int64) # indices = np.argsort(keys) # # x[:] = x[indices] # y[:] = y[indices] # z[:] = z[indices] # store particles self.particles = ParticleContainer(N) self.particles.register_carray(N, 'position-z', 'double') self.particles.register_carray(N, 'velocity-z', 'double') self.particles.register_carray(N, 'com-z', 'double') xp = self.particles["position-x"] yp = self.particles["position-y"] zp = self.particles["position-z"] xp[:] = x; yp[:] = y; zp[:] = z def test_volume_3d(self): """Test particle volumes in square created correctly. Create grid of particles in a unit box, total volume is 1.0. Create tessellation and sum all particle volumes. """ # generate voronoi mesh mesh = Mesh3d(self.particles, self.bound) print "building mesh..." mesh.build_geometry() print "mesh complete" # calculate voronoi volumes of all real particles real_indices = self.particles["tag"] == ParticleTAGS.Real tot_vol = np.sum(self.particles["volume"][real_indices]) self.assertAlmostEqual(tot_vol, 1.0)
L = 1. # domain size n = 51 # number of points per dimension # generate the domain particles dx = L / n xs = np.arange(n, dtype=np.float64) * dx + 0.5 * dx ys = np.arange(n, dtype=np.float64) * dx + 0.5 * dx X, Y = np.meshgrid(xs, ys) Y = np.flipud(Y) xs = X.flatten() ys = Y.flatten() # let root processor create the data pc_root = ParticleContainer(xs.size) pc_root['position-x'][:] = xs pc_root['position-y'][:] = ys pc_root['ids'][:] = np.arange(xs.size) create_initial_state(pc_root, dx, 1.4) x = np.arange(xs.size, dtype=np.int32) lengths = np.array_split(x, size) lengths = [sub.size for sub in lengths] send = np.copy(lengths) disp = np.zeros(size, dtype=np.int32) for i in range(1, size): disp[i] = lengths[i - 1] + disp[i - 1]
def test_get_number_of_particles(self): """ Tests the get_number_of_particles of particles. """ pc = ParticleContainer(4) self.assertEqual(pc.get_number_of_particles(), 4)
class TestVoronoiMesh2dBox(unittest.TestCase): def setUp(self): L = 1. # box size n = 50 # number of points self.dx = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries x = (np.arange(n + 6, dtype=np.float64) - 3) * self.dx + 0.5 * self.dx # generate the grid of particle positions X, Y = np.meshgrid(x, x) Y = np.flipud(Y) x = X.flatten() y = Y.flatten() # find all particles inside the unit box indices = (((0. <= x) & (x <= 1.)) & ((0. <= y) & (y <= 1.))) x_in = x[indices] y_in = y[indices] self.num_real = x_in.size self.particles = ParticleContainer(x_in.size) # store ghost particles xp = self.particles["position-x"] yp = self.particles["position-y"] xp[:] = x_in yp[:] = y_in # store ghost particles x_out = x[~indices] y_out = y[~indices] self.num_ghost = x_out.size self.particles.extend(x_out.size) tag = self.particles["tag"] xp = self.particles["position-x"] yp = self.particles["position-y"] xp[self.num_real:] = x_out yp[self.num_real:] = y_out tag[self.num_real:] = ParticleTAGS.Ghost # put real particles in front of the arrays # type = self.particles["tag"] # type[:] = ParticleTAGS.Ghost # self.particles.align_particles() # vol = self.particles["volume"] # vol[:] = 0.0 def test_volume_2D(self): """Test particle volumes in square created correctly. Create grid of particles in a unit box, total volume is 1.0. Create tessellation and sum all particle volumes. """ pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real tot_vol = np.sum(self.particles["volume"][real_indices]) self.assertAlmostEqual(tot_vol, 1.0) def test_volume_perturb_2D(self): """Test particle volumes in a perturb sub-square are created correctly. Create grid of particles in a unit box, and perturb the positions in a sub-square. Total volume is 1.0. Create tessellation and sum all particle volumes. """ # find particles in the interior box x_in = self.particles["position-x"] y_in = self.particles["position-y"] k = ((0.25 < x_in) & (x_in < 0.5)) & ((0.25 < y_in) & (y_in < 0.5)) # randomly perturb their positions num_points = k.sum() x_in[k] += 0.2 * self.dx * (2.0 * np.random.random(num_points) - 1.0) y_in[k] += 0.2 * self.dx * (2.0 * np.random.random(num_points) - 1.0) pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real tot_vol = np.sum(self.particles["volume"][real_indices]) self.assertAlmostEqual(tot_vol, 1.0) def test_center_of_mass_2D(self): """Test if particle center of mass positions are created correctly. Particles or in a uniform unit box. So com is just the particle positions. """ pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real xcom = self.particles["com-x"][real_indices] ycom = self.particles["com-y"][real_indices] xp = self.particles["position-x"][real_indices] yp = self.particles["position-y"][real_indices] for i in range(xp.size): self.assertAlmostEqual(xcom[i], xp[i]) self.assertAlmostEqual(ycom[i], yp[i])
def setUp(self): xvals = -2 * np.random.random(2) + 1 self.xmin = np.min(xvals) self.xmax = np.max(xvals) L = (self.xmax - self.xmin) # size in x n = 50 # number of points along dimension self.dx = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries x = self.xmin + (np.arange(n + 6, dtype=np.float64) - 3) * self.dx + 0.5 * self.dx yvals = -2 * np.random.random(2) + 1 self.ymin = np.min(yvals) self.ymax = np.max(yvals) L = (self.ymax - self.ymin) # size in x n = 50 # number of points along dimension self.dy = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries y = self.ymin + (np.arange(n + 6, dtype=np.float64) - 3) * self.dy + 0.5 * self.dy # generate the grid of particle positions X, Y = np.meshgrid(x, y) Y = np.flipud(Y) x = X.flatten() y = Y.flatten() # find all particles inside the unit box indices = (((self.xmin <= x) & (x <= self.xmax)) & ((self.ymin <= y) & (y <= self.ymax))) x_in = x[indices] y_in = y[indices] self.num_real = x_in.size self.particles = ParticleContainer(x_in.size) # store ghost particles xp = self.particles["position-x"] yp = self.particles["position-y"] xp[:] = x_in yp[:] = y_in # store ghost particles x_out = x[~indices] y_out = y[~indices] self.num_ghost = x_out.size self.particles.extend(x_out.size) tag = self.particles["tag"] xp = self.particles["position-x"] yp = self.particles["position-y"] xp[self.num_real:] = x_out yp[self.num_real:] = y_out tag[self.num_real:] = ParticleTAGS.Ghost
class TestVoronoiMesh2dRectangle(unittest.TestCase): def setUp(self): xvals = -2 * np.random.random(2) + 1 self.xmin = np.min(xvals) self.xmax = np.max(xvals) L = (self.xmax - self.xmin) # size in x n = 50 # number of points along dimension self.dx = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries x = self.xmin + (np.arange(n + 6, dtype=np.float64) - 3) * self.dx + 0.5 * self.dx yvals = -2 * np.random.random(2) + 1 self.ymin = np.min(yvals) self.ymax = np.max(yvals) L = (self.ymax - self.ymin) # size in x n = 50 # number of points along dimension self.dy = L / n # add ghost 3 ghost particles to the sides for the tesselation # wont suffer from edge boundaries y = self.ymin + (np.arange(n + 6, dtype=np.float64) - 3) * self.dy + 0.5 * self.dy # generate the grid of particle positions X, Y = np.meshgrid(x, y) Y = np.flipud(Y) x = X.flatten() y = Y.flatten() # find all particles inside the unit box indices = (((self.xmin <= x) & (x <= self.xmax)) & ((self.ymin <= y) & (y <= self.ymax))) x_in = x[indices] y_in = y[indices] self.num_real = x_in.size self.particles = ParticleContainer(x_in.size) # store ghost particles xp = self.particles["position-x"] yp = self.particles["position-y"] xp[:] = x_in yp[:] = y_in # store ghost particles x_out = x[~indices] y_out = y[~indices] self.num_ghost = x_out.size self.particles.extend(x_out.size) tag = self.particles["tag"] xp = self.particles["position-x"] yp = self.particles["position-y"] xp[self.num_real:] = x_out yp[self.num_real:] = y_out tag[self.num_real:] = ParticleTAGS.Ghost # put real particles in front of the arrays # type = self.particles["tag"] # type[:] = ParticleTAGS.Ghost # self.particles.align_particles() # vol = self.particles["volume"] # vol[:] = 0.0 def test_volume_2D(self): """Test particle volumes in random rectangle are created correctly. Create grid of particles in a random size rectangle. Create tessellation and sum all particle volumes. """ pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real tot_vol = np.sum(self.particles["volume"][real_indices]) self.assertAlmostEqual(tot_vol, ((self.xmax - self.xmin) * (self.ymax - self.ymin))) def test_volume_perturb_2D(self): """Test if random particle volumes are created correctly. First create a grid of particles in a unit box. So the total volume is 1.0. Then perturb the particles in a box of unit lenght 0.5. Create the tessellation and compare the sum of all the particle volumes and the total volume. """ Lx = self.xmax - self.xmin Ly = self.ymax - self.ymin xlo = self.xmin + 0.25 * Lx xhi = self.xmin + 0.75 * Lx ylo = self.ymin + 0.25 * Ly yhi = self.ymin + 0.75 * Ly # find particles in the interior box x_in = self.particles["position-x"] y_in = self.particles["position-y"] k = ((xlo < x_in) & (x_in < xhi)) & ((ylo < y_in) & (y_in < yhi)) # randomly perturb their positions num_points = k.sum() x_in[k] += 0.2 * self.dx * (2.0 * np.random.random(num_points) - 1.0) y_in[k] += 0.2 * self.dy * (2.0 * np.random.random(num_points) - 1.0) pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real tot_vol = np.sum(self.particles["volume"][real_indices]) self.assertAlmostEqual(tot_vol, Lx * Ly) def test_center_of_mass_2D(self): """Test if particle center of mass positions are created correctly. Particles are placed equally spaced in each direction. So com is just the particle positions. """ pos = np.array( [self.particles["position-x"], self.particles["position-y"]]) # generate voronoi mesh mesh = VoronoiMesh2D() mesh.tessellate(pos) # calculate voronoi volumes of all real particles mesh.compute_cell_info(self.particles) real_indices = self.particles["tag"] == ParticleTAGS.Real xcom = self.particles["com-x"][real_indices] ycom = self.particles["com-y"][real_indices] xp = self.particles["position-x"][real_indices] yp = self.particles["position-y"][real_indices] for i in range(xp.size): self.assertAlmostEqual(xcom[i], xp[i]) self.assertAlmostEqual(ycom[i], yp[i])