def test_distribute_scalar(self): a = self.Array(MeshGrid(1, 2)) a.distribute_at_positions(8, self.xp.full((1000, 3), 0.5)) assert_array_equal(a.data, np.full((2, 2, 2), 1000)) a.distribute_at_positions(8, self.xp.full((1000, 3), 0.5)) assert_array_equal(a.data, np.full((2, 2, 2), 2000)) a.reset() a.distribute_at_positions(1, self.xp.full((1000, 3), 0.1)) assert_array_almost_equal( a.data, np.array([[[729, 81], [81, 9]], [[81, 9], [9, 1]]])) a = self.Array(MeshGrid((2, 4, 8), (3, 3, 3))) a.distribute_at_positions(-2, [(1, 1, 3)]) assert_array_equal( a.data, [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[-0.25 / 8, -0.75 / 8, 0], [-0.25 / 8, -0.75 / 8, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]) a.reset() a.distribute_at_positions(-2, [(1, 1, 3), (1, 1, 3)]) assert_array_equal( a.data, [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[-0.25 / 4, -0.75 / 4, 0], [-0.25 / 4, -0.75 / 4, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]) a.reset() a.distribute_at_positions(-2, [(2, 4, 8)]) assert_array_equal(a.data, [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, -0.25]]]) a.reset()
def test_interpolate_scalar(self): a = self.Array(MeshGrid(1, 2), None, [[[0, 1], [0, -1]], [[0, 0], [0, 0]]]) positions = np.array([(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (0.5, 0.5, 0.5), (0.5, 0, 0.5), (0.5, 1, 0.5), (0, 0, 2)], dtype=float) assert_array_equal(a.interpolate_at_positions(positions), [0, 1, 0, -1, 0, 0, 0, 0, 0, 0.25, -0.25, 0]) assert_array_equal(a.interpolate_at_positions(positions[1:2]), [1.]) a = self.Array( MeshGrid((100, 20, 100), (101, 44, 101)), None, np.arange(101 * 44 * 101, dtype=float).reshape((101, 44, 101))) positions = np.linspace((0, 13, 100.1), (100.1, 0, 0), 314) o, s = np.zeros(3), np.array([100, 20, 100]) xyz = tuple( np.linspace(o[i], o[i] + s[i], a.n_nodes[i]) for i in (0, 1, 2)) interpolator = RegularGridInterpolator(xyz, a.data, bounds_error=False, fill_value=0) r1 = a.interpolate_at_positions(self.xp.asarray(positions)) assert_array_almost_equal(r1, interpolator(positions))
def test_init_rhs(self, backend): mesh = MeshGrid.from_step((4, 3, 3), 1) solver = FieldSolver(mesh, []) solver.init_rhs_vector_in_full_domain(ArrayOnGrid(mesh), ArrayOnGrid(mesh)) assert_array_equal(solver.rhs, np.zeros(3 * 2 * 2)) pot = ArrayOnGrid(mesh) pot.apply_boundary_values(BoundaryConditionsConf(-2)) solver.init_rhs_vector_in_full_domain(ArrayOnGrid(mesh), pot) assert_array_equal(solver.rhs, [6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6]) # what del solver mesh = MeshGrid.from_step((4, 4, 5), 1) pot = ArrayOnGrid(mesh) pot.apply_boundary_values(BoundaryConditionsConf(-2)) solver = FieldSolver(mesh, []) solver.init_rhs_vector_in_full_domain(ArrayOnGrid(mesh), pot) assert_array_equal(solver.rhs, [ 6, 4, 6, 4, 2, 4, 6, 4, 6, 4, 2, 4, 2, 0, 2, 4, 2, 4, 4, 2, 4, 2, 0, 2, 4, 2, 4, 6, 4, 6, 4, 2, 4, 6, 4, 6 ]) # what del solver mesh = MeshGrid.from_step((8, 12, 5), (2, 3, 1)) pot = ArrayOnGrid(mesh) pot.apply_boundary_values(BoundaryConditionsConf(-1)) solver = FieldSolver(mesh, []) solver.init_rhs_vector_in_full_domain(ArrayOnGrid(mesh), pot) assert_array_equal(solver.rhs, [ 49, 40, 49, 45, 36, 45, 49, 40, 49, 13, 4, 13, 9, 0, 9, 13, 4, 13, 13, 4, 13, 9, 0, 9, 13, 4, 13, 49, 40, 49, 45, 36, 45, 49, 40, 49 ]) del solver mesh = MeshGrid.from_step((4, 6, 9), (1, 2, 3)) charge = ArrayOnGrid(mesh) charge._data = np.array([[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 1, 2, 0], [0, -1, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 3, 4, 0], [0, 0, -1, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 5, 6, 0], [0, -1, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]) solver = FieldSolver(mesh, []) solver.init_rhs_vector_in_full_domain(charge, ArrayOnGrid(mesh)) assert_allclose( solver.rhs, -np.array([1, 3, 5, -1, 0, -1, 2, 4, 6, 0, -1, 0]) * np.pi * 4 * 36) solver = FieldSolver(mesh, []) nodep = solver.generate_nodes_in_regions( [InnerRegion('test', Box((1, 2, 3), (1, 2, 3)), 3)]) solver.nodes_in_regions, solver.potential_in_regions = nodep solver.init_rhs_vector(ArrayOnGrid(mesh), ArrayOnGrid(mesh)) assert_array_equal(solver.rhs, [3, 3, 0, 3, 3, 0, 3, 3, 0, 3, 3, 0])
def test_init(self): a = self.Array(MeshGrid(10, 11)) assert a.value_shape == () assert_array_equal(a.data, np.zeros([11] * 3)) assert type(a._data) == self.xp.ndarray data = self.xp.ones((5, 5, 5, 3)) a = self.Array(MeshGrid(1, 5), 3, data) assert a.value_shape == (3, ) assert_array_equal(a.data, np.ones((5, 5, 5, 3))) assert type(a._data) == self.xp.ndarray assert a._data is not data # data gets copied don't create ArrayOnGrid every cycle with raises(ValueError): self.Array(MeshGrid(1, 5), data=self.xp.ones((5, 5, 5, 3)))
def test_do_init_warnings(self, capsys, caplog): MeshGrid.from_step((12, 12, 12), (5, 5, 7)) out, err = capsys.readouterr() assert out == "" assert err == "" assert caplog.record_tuples == [ ('root', logging.WARNING, "X step on spatial grid was reduced to 4.000 from 5.000 to fit in a round number of cells." ), ('root', logging.WARNING, "Y step on spatial grid was reduced to 4.000 from 5.000 to fit in a round number of cells." ), ('root', logging.WARNING, "Z step on spatial grid was reduced to 6.000 from 7.000 to fit in a round number of cells." ), ]
def test_node_coordinates(self): coords = np.array([[[[0., 0., 0.], [0., 0., 3.]], [[0., 1., 0.], [0., 1., 3.]], [[0., 2., 0.], [0., 2., 3.]]], [[[2., 0., 0.], [2., 0., 3.]], [[2., 1., 0.], [2., 1., 3.]], [[2., 2., 0.], [2., 2., 3.]]], [[[4., 0., 0.], [4., 0., 3.]], [[4., 1., 0.], [4., 1., 3.]], [[4., 2., 0.], [4., 2., 3.]]]]) assert_array_equal( MeshGrid.from_step((4, 2, 3), (2, 1, 3)).node_coordinates, coords) assert_array_equal( MeshGrid.from_step((4, 2, 3), (2, 1, 3), (1, 2, 3.14)).node_coordinates, coords + [1, 2, 3.14])
def test_generate_nodes_in_regions(self, backend): mesh = MeshGrid.from_step((4, 6, 9), (1, 2, 3)) solver = FieldSolver(mesh, []) inner_regions = [InnerRegion('test', Box((1, 2, 3), (1, 2, 3)), 3)] nodes, potential = solver.generate_nodes_in_regions(inner_regions) assert_array_equal(nodes, [0, 1, 3, 4, 6, 7, 9, 10]) assert_array_equal(potential, [3, 3, 3, 3, 3, 3, 3, 3])
def test_zero_nondiag_inside_objects(self, backend): mesh = MeshGrid.from_step((4, 6, 9), (1, 2, 3)) solver = FieldSolver( mesh, [InnerRegion('test', Box((1, 2, 3), (1, 2, 3)), 3)]) a = scipy.sparse.coo_matrix(np.full((12, 12), 2)) assert_array_equal(a.toarray(), [[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]) result = solver.zero_nondiag_for_nodes_inside_objects(a) assert_array_equal(result.toarray(), [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]) a = scipy.sparse.coo_matrix( np.array([[4, 0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])) result = solver.zero_nondiag_for_nodes_inside_objects(a) assert_array_equal(result.toarray(), [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
def __init__(self, name, electric_or_magnetic, field_filename, xp=numpy, array_class=ArrayOnGrid): if not os.path.exists(field_filename): raise FileNotFoundError("Field file not found") raw = numpy.loadtxt(field_filename, skiprows=1) # assume X Y Z Fx Fy Fz columns # sort by column 0, then 1, then 2 # https://stackoverflow.com/a/38194077 ind = raw[:, 2].argsort() # First sort doesn't need to be stable. raw = raw[ind] ind = raw[:, 1].argsort(kind='mergesort') raw = raw[ind] ind = raw[:, 0].argsort(kind='mergesort') raw = raw[ind] size = (raw[-1, :3] - raw[0, :3]) origin = raw[0, :3] dist = raw[:, :3] - raw[0, :3] step = dist.min(axis=0, where=dist > 0, initial=dist.max()) grid = MeshGrid.from_step(size, step, origin) field = xp.asarray(raw[:, 3:].reshape((*grid.n_nodes, 3))) super().__init__(name, electric_or_magnetic, array_class(grid, 3, field)) self.field_filename = field_filename
def test_distribute_vector(self): a = self.Array(MeshGrid(1, 2)) with raises( ValueError, match="operands could not be broadcast together with shapes"): a.distribute_at_positions(self.xp.array([8, 8, 8]), self.xp.full((1000, 3), 0.5))
def test_all_config(self, backend): efconf = Config( TimeGridConf(200, 20, 2), SpatialMeshConf((5, 5, 5), (.1, .1, .1)), sources=[ ParticleSourceConf('a', Box()), ParticleSourceConf('c', Cylinder()), ParticleSourceConf('d', Tube(start=(0, 0, 0), end=(0, 0, 1))) ], inner_regions=[ InnerRegionConf('1', Box(), 1), InnerRegionConf('2', Sphere(), -2), InnerRegionConf('3', Cylinder(), 0), InnerRegionConf('4', Tube(), 4) ], output_file=OutputFileConf(), boundary_conditions=BoundaryConditionsConf(-2.7), particle_interaction_model=ParticleInteractionModelConf('binary'), external_fields=[ ExternalElectricFieldUniformConf('x', (-2, -2, 1)), ExternalMagneticFieldExpressionConf( 'y', ('0', '0', '3*x + sqrt(y) - z**2')) ]) parser = ConfigParser() parser.read_string(efconf.export_to_string()) conf = Config.from_configparser(parser) sim = conf.make() assert_dataclass_eq(sim.time_grid, TimeGrid(200, 2, 20)) assert_dataclass_eq(sim.mesh, MeshGrid(5, 51)) assert_dataclass_eq( sim.electric_field, FieldOnGrid('spatial_mesh', 'electric', self.Array(sim.mesh, 3))) assert_dataclass_eq(sim.charge_density, self.Array(sim.mesh)) expected = np.full((51, 51, 51), -2.7) expected[1:-1, 1:-1, 1:-1] = 0 assert_dataclass_eq(sim.potential, self.Array(sim.mesh, (), expected)) _assert_value_eq(sim.inner_regions, [ InnerRegion('1', Box(), 1), InnerRegion('2', Sphere(), -2), InnerRegion('3', Cylinder(), 0), InnerRegion('4', Tube(), 4) ]) _assert_value_eq(sim.particle_sources, [ ParticleSourceConf('a', Box()).make(), ParticleSourceConf('c', Cylinder()).make(), ParticleSourceConf('d', Tube(start=(0, 0, 0), end=(0, 0, 1))).make() ]) assert_dataclass_eq( sim.electric_fields, FieldUniform('x', 'electric', np.array((-2, -2, 1)))) assert_dataclass_eq( sim.magnetic_fields, FieldExpression('y', 'magnetic', '0', '0', '3*x + sqrt(y) - z**2')) assert sim.particle_interaction_model == Model.binary
def test_do_init(self): a = ArrayOnGrid(MeshGrid.from_step((12, 12, 12), (4, 4, 6))) a.apply_boundary_values(BoundaryConditionsConf(1, 2, 3, 4, 5, 6)) expected = np.array([[[5., 1., 6.], [5., 1., 6.], [5., 1., 6.], [5., 1., 6.]], [[5., 3., 6.], [5., 0., 6.], [5., 0., 6.], [5., 4., 6.]], [[5., 3., 6.], [5., 0., 6.], [5., 0., 6.], [5., 4., 6.]], [[5., 2., 6.], [5., 2., 6.], [5., 2., 6.], [5., 2., 6.]]]) assert_array_equal(a.data, expected)
def test_interpolate_vector(self): a = self.Array(MeshGrid((2, 4, 8), (3, 3, 3)), 3, self.xp.full((3, 3, 3, 3), 100)) a._data[1:2, 0:2, 0:2] = self.xp.array([[[2, 1, 0], [-3, 1, 0]], [[0, -1, 0], [-1, 0, 0]]]) assert_array_equal( a.interpolate_at_positions(np.array([(1, 1, 3)], dtype=float)), [(-1.25, 0.375, 0)]) assert_array_equal( a.interpolate_at_positions( self.xp.array([(1, 1, 3), (2, 1, 3), (1.5, 1, 3)], dtype=float)), [(-1.25, 0.375, 0), (100, 100, 100), (49.375, 50.1875, 50)])
def test_n_nodes(self): assert self.Array(MeshGrid(10, 11)).n_nodes == (11, 11, 11) assert self.Array(MeshGrid(10, 11), None).n_nodes == (11, 11, 11) assert self.Array(MeshGrid(10, 11), ()).n_nodes == (11, 11, 11) assert self.Array(MeshGrid(10, 11), 1).n_nodes == (11, 11, 11, 1) # Should this be true? assert self.Array(MeshGrid(10, 11), 3).n_nodes == (11, 11, 11, 3) assert self.Array(MeshGrid(10, 11), (2, 5)).n_nodes == (11, 11, 11, 2, 5)
def test_transfer_solution_to_spat_mesh(self): mesh = MeshGrid.from_step((4, 6, 9), (1, 2, 3)) solver = FieldSolver(mesh, []) solver.phi_vec = np.array(range(1, 3 * 2 * 2 + 1)) potential = ArrayOnGrid(mesh) solver.transfer_solution_to_spat_mesh(potential) assert_array_equal( potential.data[1:-1, 1:-1, 1:-1], [[[1, 7], [4, 10]], [[2, 8], [5, 11]], [[3, 9], [6, 12]]]) assert_array_equal( potential.data, [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 1, 7, 0], [0, 4, 10, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 2, 8, 0], [0, 5, 11, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 3, 9, 0], [0, 6, 12, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]])
def test_init_from_config(self, backend): efconf = Config() parser = ConfigParser() parser.read_string(efconf.export_to_string()) sim = Config.from_configparser(parser).make() assert_dataclass_eq(sim.time_grid, TimeGrid(100, 1, 10)) g = MeshGrid(10, 11) assert_dataclass_eq(sim.mesh, g) assert_dataclass_eq(sim.potential, self.Array(g)) assert_dataclass_eq(sim.charge_density, self.Array(g)) assert_dataclass_eq( sim.electric_field, FieldOnGrid('spatial_mesh', 'electric', self.Array(g, 3))) assert sim.inner_regions == [] assert sim.particle_sources == [] assert_dataclass_eq(sim.electric_fields, FieldZero('ZeroSum', 'electric')) assert_dataclass_eq(sim.magnetic_fields, FieldZero('ZeroSum', 'magnetic')) assert sim.particle_interaction_model == Model.PIC
def sim_full(): return Simulation( TimeGrid(200, 2, 20), MeshGrid(5, 51), particle_sources=[ ParticleSource('a', Box()), ParticleSource('c', Cylinder()), ParticleSource('d', Tube(start=(0, 0, 0), end=(0, 0, 1))) ], inner_regions=[ InnerRegion('1', Box(), 1), InnerRegion('2', Sphere(), -2), InnerRegion('3', Cylinder(), 0), InnerRegion('4', Tube(), 4) ], particle_interaction_model=Model.binary, electric_fields=[FieldUniform('x', 'electric', (-2, -2, 1))], magnetic_fields=[ FieldExpression('y', 'magnetic', '0', '0', '3*x + sqrt(y) - z**2') ])
def test_construct_equation_matrix(self): mesh = MeshGrid.from_step((4, 6, 9), (1, 2, 3)) solver = FieldSolver(mesh, []) solver.construct_equation_matrix() d = -2 * (2 * 2 * 3 * 3 + 3 * 3 + 2 * 2) x = 2 * 2 * 3 * 3 y = 3 * 3 z = 2 * 2 assert_array_equal(solver.A.toarray(), [[d, x, 0, y, 0, 0, z, 0, 0, 0, 0, 0], [x, d, x, 0, y, 0, 0, z, 0, 0, 0, 0], [0, x, d, 0, 0, y, 0, 0, z, 0, 0, 0], [y, 0, 0, d, x, 0, 0, 0, 0, z, 0, 0], [0, y, 0, x, d, x, 0, 0, 0, 0, z, 0], [0, 0, y, 0, x, d, 0, 0, 0, 0, 0, z], [z, 0, 0, 0, 0, 0, d, x, 0, y, 0, 0], [0, z, 0, 0, 0, 0, x, d, x, 0, y, 0], [0, 0, z, 0, 0, 0, 0, x, d, 0, 0, y], [0, 0, 0, z, 0, 0, y, 0, 0, d, x, 0], [0, 0, 0, 0, z, 0, 0, y, 0, x, d, x], [0, 0, 0, 0, 0, z, 0, 0, y, 0, x, d]])
def test_is_the_same_on_all_boundaries(self): mesh = MeshGrid(12, (4, 4, 3)) a = self.Array(mesh) assert a.is_the_same_on_all_boundaries for x, y, z in np.ndindex(4, 4, 3): a._data[x, y, z] = 2. if 0 < x < 3 and 0 < y < 3 and 0 < z < 2: assert a.is_the_same_on_all_boundaries else: assert not a.is_the_same_on_all_boundaries a.reset() assert a.is_the_same_on_all_boundaries a = self.Array(mesh, 3) assert a.is_the_same_on_all_boundaries for x, y, z, t in np.ndindex(4, 4, 3, 3): a._data[x, y, z, t] = 2. if 0 < x < 3 and 0 < y < 3 and 0 < z < 2: assert a.is_the_same_on_all_boundaries else: assert not a.is_the_same_on_all_boundaries a.reset() assert a.is_the_same_on_all_boundaries
def import_from_h5(h5file: h5py.File) -> Simulation: fields = [Field.import_h5(g) for g in h5file['ExternalFields'].values()] sources = [ParticleSource.import_h5(g) for g in h5file['ParticleSources'].values()] particles = [ParticleArray.import_h5(g) for g in h5file['ParticleSources'].values()] # cupy max has no `initial` argument max_id = int(max([(p.ids.get() if hasattr(p.ids, 'get') else p.ids).max(initial=-1) for p in particles], default=-1)) g = h5file['SpatialMesh'] mesh = MeshGrid.import_h5(g) charge = Reader.array_class(mesh, (), np.reshape(g['charge_density'], mesh.n_nodes)) potential = Reader.array_class(mesh, (), np.reshape(g['potential'], mesh.n_nodes)) field = FieldOnGrid('spatial_mesh', 'electric', Reader.array_class(mesh, 3, np.moveaxis( np.array([np.reshape(g[f'electric_field_{c}'], mesh.n_nodes) for c in 'xyz']), 0, -1))) return Simulation( time_grid=TimeGrid.import_h5(h5file['TimeGrid']), mesh=mesh, charge_density=charge, potential=potential, electric_field=field, inner_regions=[InnerRegion.import_h5(g) for g in h5file['InnerRegions'].values()], electric_fields=[f for f in fields if f.electric_or_magnetic == 'electric'], magnetic_fields=[f for f in fields if f.electric_or_magnetic == 'magnetic'], particle_interaction_model=Model[ h5file['ParticleInteractionModel'].attrs['particle_interaction_model'].decode('utf8') ], particle_sources=sources, particle_arrays=particles, particle_tracker=ParticleTracker(max_id) )
def test_gradient(self): m = MeshGrid((1.5, 2, 1), (4, 3, 2)) potential = self.Array(m) potential._data = self.xp.stack([ self.xp.array([[0., 0, 0], [1, 2, 3], [4, 3, 2], [4, 4, 4]]), self.xp.zeros((4, 3)) ], -1) expected = self.Array( m, 3, [[[[-2, 0, 0], [0, 0, 0]], [[-4, 0, 0], [0, 0, 0]], [[-6, 0, 0], [0, 0, 0]]], [[[-4, -1, 1], [0, 0, 1]], [[-3, -1, 2], [0, 0, 2]], [[-2, -1, 3], [0, 0, 3]]], [[[-3, 1, 4], [0, 0, 4]], [[-2, 1, 3], [0, 0, 3]], [[-1, 1, 2], [0, 0, 2]]], [[[0, 0, 4], [0, 0, 4]], [[-2, 0, 4], [0, 0, 4]], [[-4, 0, 4], [0, 0, 4]]]]) field = potential.gradient() assert_dataclass_eq(field, expected) with raises( ValueError, match= "Trying got compute gradient for a non-scalar field: ambiguous" ): field.gradient()
def test_on_grid(self, backend): f = FieldOnGrid('f1', 'electric', inject.instance(ArrayOnGrid)(MeshGrid(5, 6), 3, inject.instance(np).full((6, 6, 6, 3), -3.14))) assert_array_almost_equal(f.get_at_points([(-1, 0, 0), (1, 2, 3.5)], 1), [(0, 0, 0), (-3.14, -3.14, -3.14)]) with raises(ValueError): FieldOnGrid('f1', 'electric', inject.instance(ArrayOnGrid)(MeshGrid(5, 6)))
def test_init(self): m = MeshGrid(10, 11) assert_array_equal(m.size, (10, 10, 10)) assert_array_equal(m.n_nodes, (11, 11, 11)) assert_array_equal(m.origin, (0, 0, 0))
def test_from_step(self): assert_dataclass_eq(MeshGrid.from_step(10, 1, 7), MeshGrid(10, 11, 7)) assert_dataclass_eq(MeshGrid.from_step([10, 20, 5], [1, 4, 1]), MeshGrid([10, 20, 5], [11, 6, 6])) assert_dataclass_eq(MeshGrid.from_step(10, [1, 2, 4]), MeshGrid(10, [11, 6, 4]))
def test_cell(self): assert_array_equal(MeshGrid(10, 11, 7).cell, (1, 1, 1)) assert_array_equal( MeshGrid.from_step(10, [1, 2, 4]).cell, [1, 2, 10 / 3])
def test_do_init_ranges(self): with raises(ValueError): MeshGrid.from_step((10, 20), (2, 1, 3)) with raises(ValueError): MeshGrid.from_step(((1, 2), 3), (1, 1, 1)) with raises(ValueError): MeshGrid.from_step((10, 10, 10), [[2, 1, 3], [4, 5, 6], [7, 8, 9]], BoundaryConditionsConf(3.14)) with raises(ValueError): MeshGrid.from_step((10, 10, -30), (2, 1, 3)) with raises(ValueError): MeshGrid.from_step((10, 10, 10), (2, -2, 3)) mesh = MeshGrid.from_step((10, 10, 10), (17, 2, 3)) assert tuple(mesh.cell) == (10, 2, 2.5)
def test_zero(self): z = self.Array(MeshGrid(10, 5), (2, 5)).zero assert type(z) == self.xp.ndarray assert z.shape == (5, 5, 5, 2, 5) assert (z == 0).all()
def test_reset(self): a = self.Array(MeshGrid(1, 5), (), self.xp.ones((5, 5, 5))) assert_array_equal(a.data, np.ones((5, 5, 5))) a.reset() assert_array_equal(a.data, np.zeros((5, 5, 5)))