def test_to_component(self): assert_dataclass_eq( TimeGrid(100, 1, 10).to_component(), time_grid.TimeGridConf(100, 10, 1)) assert_dataclass_eq( TimeGrid(123, 3, 13).to_component(), time_grid.TimeGridConf(123, 12, 3))
def test_init_h5(self, tmpdir): fname = tmpdir.join('test_timegrid_init.h5') grid1 = TimeGrid(100, 1, 10) with h5py.File(fname, mode="w") as h5file: grid1.save_h5(h5file.create_group("/gr")) with h5py.File(fname, mode="r") as h5file: grid2 = TimeGrid.load_h5(h5file["/gr"]) assert grid1 == grid2
def test_import_h5(self, tmpdir): bio = BytesIO() grid1 = TimeGrid(123, 3, 13, 111) with h5py.File(bio, mode="w") as h5file: grid1.export_h5(h5file.create_group("/gr")) with h5py.File(bio, mode="r") as h5file: grid2 = TimeGrid.import_h5(h5file["/gr"]) assert_dataclass_eq(grid1, grid2)
def test_all_config(self): efconf = Config(TimeGridConf(200, 20, 2), SpatialMeshConf((5, 5, 5), (.1, .1, .1)), sources=[ParticleSourceConf('a', Box()), ParticleSourceConf('c', Cylinder()), ParticleSourceConf('d', Tube())], 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=[ExternalFieldUniformConf('x', 'electric', (-2, -2, 1)), ExternalFieldExpressionConf('y', 'magnetic', ('0', '0', '3*x + sqrt(y) - z**2'))]) parser = ConfigParser() parser.read_string(efconf.export_to_string()) sim = Config.from_configparser(parser).make() assert sim.time_grid == TimeGrid(200, 2, 20) assert sim.spat_mesh == SpatialMesh.do_init((5, 5, 5), (.1, .1, .1), BoundaryConditionsConf(-2.7)) assert sim.inner_regions == [InnerRegion('1', Box(), 1), InnerRegion('2', Sphere(), -2), InnerRegion('3', Cylinder(), 0), InnerRegion('4', Tube(), 4)] assert type(sim._field_solver) == FieldSolver assert sim.particle_sources == [ParticleSourceConf('a', Box()).make(), ParticleSourceConf('c', Cylinder()).make(), ParticleSourceConf('d', Tube()).make()] assert sim.electric_fields == [ExternalFieldUniform('x', 'electric', np.array((-2, -2, 1)))] assert sim.magnetic_fields == [ExternalFieldExpression('y', 'magnetic', '0', '0', '3*x + sqrt(y) - z**2')] assert sim.particle_interaction_model == ParticleInteractionModel("binary") assert sim._output_filename_prefix == "out_" assert sim._output_filename_suffix == ".h5"
def test_print(self): grid = TimeGrid(100, 1, 10) assert str(grid) == ("### TimeGrid:\n" "total_time = 100.0\n" "total_nodes = 101\n" "node_to_save = 10\n" "current_node = 0")
def test_dict(self): assert TimeGrid(100, 1, 10, 123).dict == { 'total_time': 100, 'time_step_size': 1, 'time_save_step': 10, 'current_node': 123 }
def test_should_save(self): t = TimeGrid(100, 1, 3) assert t.should_save for _ in range(10): t.update_to_next_step() assert not t.should_save t.update_to_next_step() assert not t.should_save t.update_to_next_step() assert t.should_save
def test_init(self): assert_dataclass_eq(TimeGrid(100.0, 1.0, 10.0), TimeGrid(100, 1, 10)) t = TimeGrid(123, 3, 13) assert t.total_time == 123 assert t.total_nodes == 42 assert t.time_step_size == 3 assert t.time_save_step == 12 assert t.node_to_save == 4 assert t.current_time == 0 assert t.current_node == 0 t = TimeGrid(123, 4, 13, 1000) assert t.total_time == 123 assert t.total_nodes == 32 assert t.time_step_size == 123 / 31 assert t.time_save_step == 123 / 31 * 3 assert t.node_to_save == 3 assert t.current_time == pytest.approx(123000 / 31) assert t.current_node == 1000
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_component_link(self): assert time_grid.TimeGridConf().make() == TimeGrid(100.0, 1.0, 10.0) assert time_grid.TimeGridConf() == TimeGrid(100.0, 1.0, 10.0).to_component() assert time_grid.TimeGridConf() == TimeGrid(100, 1, 10).to_component() # should config component also store parameters as float? assert time_grid.TimeGridConf(123.0, 13.0, 3.0) != TimeGrid(123, 3, 13).to_component() assert time_grid.TimeGridConf(123, 13, 3) != TimeGrid(123, 3, 13).to_component() assert time_grid.TimeGridConf(123, 13, 3).make() == TimeGrid(123, 3, 13)
def test_init_from_config(self): efconf = Config() parser = ConfigParser() parser.read_string(efconf.export_to_string()) sim = Config.from_configparser(parser).make() assert sim.time_grid == TimeGrid(100, 1, 10) assert sim.spat_mesh == SpatialMesh.do_init((10, 10, 10), (1, 1, 1), BoundaryConditionsConf(0)) assert sim.inner_regions == [] assert type(sim._field_solver) == FieldSolver assert sim.particle_sources == [] assert sim.electric_fields == [] assert sim.magnetic_fields == [] assert sim.particle_interaction_model == ParticleInteractionModel("PIC") assert sim._output_filename_prefix == "out_" assert sim._output_filename_suffix == ".h5"
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_init_exceptions(self): with raises(ValueError, match="Expect total_time > 0"): TimeGrid(-100, 1, 10) with raises(ValueError, match="Expect time_step_size > 0"): TimeGrid(100, -1, 10) with raises(ValueError, match="Expect time_save_step >= time_step_size"): TimeGrid(100, 1, -10) with raises(ValueError, match="Expect time_step_size <= total_time"): TimeGrid(100, 1000, 1000) with raises(ValueError, match="Expect time_save_step >= time_step_size"): TimeGrid(100, 10, 1) # Not an error, just never save after the 0th tick t = TimeGrid(100, 1, 1000) assert t.node_to_save == 1000 assert t.time_save_step == 1000
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_update_next_step(self): t = TimeGrid(100, 1, 10, 123) t.update_to_next_step() assert t.current_node == 124 assert t.current_time == 124
def test_config_make(self): assert_dataclass_eq(time_grid.TimeGridConf().make(), TimeGrid(100.0, 1.0, 10.0)) assert_dataclass_eq( time_grid.TimeGridConf(123, 13, 3).make(), TimeGrid(123, 3, 13))