def test_mode_conserve(self, dim=1, interp=1, simput=dup(simArgs)): print(f"test_mode_conserve dim/interp:{dim}/{interp}") for key in ["cells", "dl", "boundary_types"]: simput[key] = [simput[key]] * dim # first simulation local_out = f"{out}/conserve/{dim}/{interp}/mpi_n/{cpp.mpi_size()}/id{self.ddt_test_id()}" self.register_diag_dir_for_cleanup(local_out) simput["restart_options"]["dir"] = local_out ph.global_vars.sim = ph.Simulation(**simput) self.assertEqual(len(ph.global_vars.sim.restart_options["timestamps"]), 1) self.assertEqual(ph.global_vars.sim.restart_options["timestamps"][0], .004) model = setup_model() Simulator(ph.global_vars.sim).run().reset() # second simulation (not restarted) ph.global_vars.sim = None simput["restart_options"]["mode"] = "conserve" ph.global_vars.sim = ph.Simulation(**simput) self.assertEqual(len(ph.global_vars.sim.restart_options["timestamps"]), 0)
def test_dump_diags_timestamps(self): print("test_dump_diags dim/interp:{}/{}".format(1, 1)) simulation = ph.Simulation(**simArgs.copy()) sim = simulation dump_every = 1 timestamps = np.arange(0, sim.final_time + sim.time_step, dump_every * sim.time_step) setup_model(10) for quantity in ["B"]: ElectromagDiagnostics( quantity=quantity, write_timestamps=timestamps, compute_timestamps=timestamps, flush_every=ElectromagDiagnostics.h5_flush_never, ) Simulator(simulation).run() def make_time(stamp): return "{:.10f}".format(stamp) for diagInfo in ph.global_vars.sim.diagnostics: h5_filename = os.path.join(out, h5_filename_from(diagInfo)) self.assertTrue(os.path.exists(h5_filename)) h5_file = h5py.File(h5_filename, "r") for timestamp in timestamps: self.assertIn(make_time(timestamp), h5_file[h5_time_grp_key])
def config(): ph.Simulation(# strict=True, smallest_patch_size=patch_sizes[0], largest_patch_size=patch_sizes[1], time_step_nbr=10, time_step=0.001, cells=[cells] * 2, dl=[dl] * 2, resistivity=0.001, hyper_resistivity=0.001, diag_options={"format": "phareh5", "options": {"dir": diag_outputs, "mode":"overwrite"}}, refinement_boxes={}, ) ph.MaxwellianFluidModel( bx=bx, by=by, bz=bz, protons={"charge": 1, "density": density, "init":{"seed": seed}, **{ "nbr_part_per_cell":100, "vbulkx": vxyz, "vbulky": vxyz, "vbulkz": vxyz, "vthx": vthxyz, "vthy": vthxyz, "vthz": vthxyz, } }, ) ph.ElectronModel(closure="isothermal", Te=0.0) from tests.diagnostic import all_timestamps timestamps = all_timestamps(ph.global_vars.sim) timestamps = np.asarray([timestamps[0], timestamps[-1]]) for quantity in ["E", "B"]: ph.ElectromagDiagnostics( quantity=quantity, write_timestamps=timestamps, compute_timestamps=timestamps, )
def _test_dump_diags(self, dim, **simInput): test_id = self.ddt_test_id() for key in ["cells", "dl", "boundary_types"]: simInput[key] = [simInput[key] for d in range(dim)] for interp in range(1, 4): local_out = f"{out}_dim{dim}_interp{interp}_mpi_n_{cpp.mpi_size()}_id{test_id}" simInput["diag_options"]["options"]["dir"] = local_out simulation = ph.Simulation(**simInput) self.assertTrue(len(simulation.cells) == dim) dump_all_diags(setup_model().populations) self.simulator = Simulator( simulation).initialize().advance().reset() self.assertTrue( any([ diagInfo.quantity.endswith("tags") for diagInfo in ph.global_vars.sim.diagnostics ])) checks = 0 found = 0 for diagInfo in ph.global_vars.sim.diagnostics: h5_filepath = os.path.join(local_out, h5_filename_from(diagInfo)) self.assertTrue(os.path.exists(h5_filepath)) h5_file = h5py.File(h5_filepath, "r") self.assertTrue("0.0000000000" in h5_file[h5_time_grp_key]) # init dump n_patches = len( list(h5_file[h5_time_grp_key]["0.0000000000"] ["pl0"].keys())) if h5_filepath.endswith("tags.h5"): found = 1 hier = hierarchy_from(h5_filename=h5_filepath) patches = hier.level(0).patches tag_found = 0 for patch in patches: self.assertTrue(len(patch.patch_datas.items())) for qty_name, pd in patch.patch_datas.items(): self.assertTrue((pd.dataset[:] >= 0).all()) self.assertTrue((pd.dataset[:] < 2).all()) tag_found |= (pd.dataset[:] == 1).any() checks += 1 self.assertEqual(found, 1) self.assertEqual(tag_found, 1) self.assertEqual(checks, n_patches) self.simulator = None ph.global_vars.sim = None
def _test_dump_diags(self, dim, **simInput): test_id = self.ddt_test_id() # configure simulation dim sized values for key in ["cells", "dl", "boundary_types"]: simInput[key] = [simInput[key] for d in range(dim)] b0 = [[10 for i in range(dim)], [19 for i in range(dim)]] simInput["refinement_boxes"] = {"L0": {"B0": b0}} for interp in range(1, 4): print("_test_dump_diags dim/interp:{}/{}".format(dim, interp)) local_out = f"{out}_dim{dim}_interp{interp}_mpi_n_{cpp.mpi_size()}_id{test_id}" simInput["diag_options"]["options"]["dir"] = local_out simulation = ph.Simulation(**simInput) self.assertTrue(len(simulation.cells) == dim) dump_all_diags(setup_model().populations) self.simulator = Simulator(simulation).initialize().advance() for diagInfo in ph.global_vars.sim.diagnostics: # diagInfo.quantity starts with a / this interferes with os.path.join, hence [1:] h5_filename = os.path.join(local_out, (diagInfo.quantity + ".h5").replace('/', '_')[1:]) print("h5_filename", h5_filename) h5_file = h5py.File(h5_filename, "r") self.assertTrue("t0.000000" in h5_file) # init dump self.assertTrue("t0.000100" in h5_file) self.assertTrue("pl1" in h5_file["t0.000100"]) self.assertFalse("pl0" in h5_file["t0.000100"]) self.assertTrue("t0.001000" in h5_file) # advance dump # SEE https://github.com/PHAREHUB/PHARE/issues/275 if dim == 1: # REMOVE WHEN PHARESEE SUPPORTS 2D self.assertTrue(os.path.exists(h5_filename)) hier = hierarchy_from(h5_filename=h5_filename) if h5_filename.endswith("domain.h5"): for patch in hier.level(0).patches: for qty_name, pd in patch.patch_datas.items(): splits = pd.dataset.split(ph.global_vars.sim) self.assertTrue(splits.size() == pd.dataset.size() * 2) print("splits.iCell", splits.iCells) print("splits.delta", splits.deltas) print("splits.weight", splits.weights) print("splits.charge", splits.charges) print("splits.v", splits.v) self.simulator = None ph.global_vars.sim = None
def populate_simulation(dim, interp, **input): ph.global_vars.sim = None simulation = ph.Simulation(**basicSimulatorArgs(dim, interp, **input)) extra_pops = {} if "populations" in input: for pop, vals in input["populations"].items(): extra_pops[pop] = defaultPopulationSettings() extra_pops[pop].update(vals) model = makeBasicModel(extra_pops) if "diags_fn" in input: input["diags_fn"](model) ElectronModel(closure="isothermal", Te=0.12) return simulation
def test_hierarchy_timestamp_cadence(self, refinement_boxes): dim = refinement_boxes["L0"]["B0"].ndim time_step = .001 # time_step_nbr chosen to force diagnostics dumping double imprecision cadence calculations accuracy testing time_step_nbr = 101 final_time = time_step * time_step_nbr for trailing in [0, 1]: # 1 = skip init dumps for i in [2, 3]: simInput = simArgs.copy() diag_outputs = f"phare_outputs_hierarchy_timestamp_cadence_{dim}_{self.ddt_test_id()}_{i}" simInput["diag_options"]["options"]["dir"] = diag_outputs simInput["time_step_nbr"] = time_step_nbr ph.global_vars.sim = None simulation = ph.Simulation(**simInput) setup_model(10) timestamps = np.arange(0, final_time, time_step * i)[trailing:] for quantity in ["B"]: ElectromagDiagnostics( quantity=quantity, write_timestamps=timestamps, compute_timestamps=timestamps, flush_every=ElectromagDiagnostics.h5_flush_never, ) Simulator(simulation).run() for diagInfo in simulation.diagnostics: h5_filename = os.path.join(diag_outputs, h5_filename_from(diagInfo)) self.assertTrue(os.path.exists(h5_filename)) hier = hierarchy_from(h5_filename=h5_filename) time_hier_keys = list(hier.time_hier.keys()) self.assertEqual(len(time_hier_keys), len(timestamps)) for i, timestamp in enumerate(time_hier_keys): self.assertEqual(hier.format_timestamp(timestamps[i]), timestamp)
def config(**options): ph.Simulation(**options) ph.MaxwellianFluidModel(bx=bx, by=by, bz=bz, protons={ "charge": 1, "density": density, **vvv }) ph.ElectronModel(closure="isothermal", Te=0.12) sim = ph.global_vars.sim timestamps = all_timestamps(sim) for quantity in ["E", "B"]: ph.ElectromagDiagnostics( quantity=quantity, write_timestamps=timestamps, compute_timestamps=timestamps, ) for quantity in ["density", "bulkVelocity"]: ph.FluidDiagnostics( quantity=quantity, write_timestamps=timestamps, compute_timestamps=timestamps, ) for pop in sim.model.populations: for quantity in ['domain']: ph.ParticleDiagnostics( quantity=quantity, compute_timestamps=timestamps[:particle_diagnostics["count"] + 1], write_timestamps=timestamps[:particle_diagnostics["count"] + 1], population_name=pop)
def test_twice_register(self): simulation = ph.Simulation(**simArgs.copy()) model = setup_model() dump_all_diags(model.populations) # first register self.assertRaises(RuntimeError, dump_all_diags, model.populations)
def _test_dump_diags(self, dim, **simInput): test_id = self.ddt_test_id() # configure simulation dim sized values for key in ["cells", "dl", "boundary_types"]: simInput[key] = [simInput[key] for d in range(dim)] b0 = [[10 for i in range(dim)], [19 for i in range(dim)]] simInput["refinement_boxes"] = {"L0": {"B0": b0}} py_attrs = [ f"{dep}_version" for dep in ["samrai", "highfive", "pybind"] ] py_attrs += ["git_hash"] for interp in range(1, 4): print("test_dump_diags dim/interp:{}/{}".format(dim, interp)) local_out = f"{out}_dim{dim}_interp{interp}_mpi_n_{cpp.mpi_size()}_id{test_id}" simInput["diag_options"]["options"]["dir"] = local_out simulation = ph.Simulation(**simInput) self.assertTrue(len(simulation.cells) == dim) dump_all_diags(setup_model().populations) self.simulator = Simulator( simulation).initialize().advance().reset() refined_particle_nbr = simulation.refined_particle_nbr self.assertTrue( any([ diagInfo.quantity.endswith("domain") for diagInfo in ph.global_vars.sim.diagnostics ])) particle_files = 0 for diagInfo in ph.global_vars.sim.diagnostics: h5_filepath = os.path.join(local_out, h5_filename_from(diagInfo)) self.assertTrue(os.path.exists(h5_filepath)) h5_file = h5py.File(h5_filepath, "r") self.assertTrue("0.0000000000" in h5_file[h5_time_grp_key]) # init dump self.assertTrue( "0.0010000000" in h5_file[h5_time_grp_key]) # first advance dump h5_py_attrs = h5_file["py_attrs"].attrs.keys() for py_attr in py_attrs: self.assertIn(py_attr, h5_py_attrs) hier = hierarchy_from(h5_filename=h5_filepath) if h5_filepath.endswith("domain.h5"): particle_files += 1 self.assertTrue("pop_mass" in h5_file.attrs) if "protons" in h5_filepath: self.assertTrue(h5_file.attrs["pop_mass"] == 1) elif "alpha" in h5_filepath: self.assertTrue(h5_file.attrs["pop_mass"] == 4) else: raise RuntimeError("Unknown population") self.assertGreater(len(hier.level(0).patches), 0) for patch in hier.level(0).patches: self.assertTrue(len(patch.patch_datas.items())) for qty_name, pd in patch.patch_datas.items(): splits = pd.dataset.split(ph.global_vars.sim) self.assertTrue(splits.size() > 0) self.assertTrue(pd.dataset.size() > 0) self.assertTrue( splits.size() == pd.dataset.size() * refined_particle_nbr) self.assertEqual(particle_files, ph.global_vars.sim.model.nbr_populations()) self.simulator = None ph.global_vars.sim = None
def test_restarts(self, dim, interp, simInput): print(f"test_restarts dim/interp:{dim}/{interp}") simput = copy.deepcopy(simInput) for key in ["cells", "dl", "boundary_types"]: simput[key] = [simput[key]] * dim if "refinement" not in simput: b0 = [[10 for i in range(dim)], [19 for i in range(dim)]] simput["refinement_boxes"] = {"L0": {"B0": b0}} else: # https://github.com/LLNL/SAMRAI/issues/199 # tagging can handle more than one timestep as it does not # appear subject to regridding issues, so we make more timesteps # to confirm simulations are still equivalent simput["time_step_nbr"] = 10 # if restart time exists it "loads" from restart file # otherwise just saves restart files based on timestamps assert "restart_time" not in simput["restart_options"] simput["interp_order"] = interp time_step = simput["time_step"] time_step_nbr = simput["time_step_nbr"] restart_idx = 4 restart_time = time_step * restart_idx timestamps = [time_step * restart_idx, time_step * time_step_nbr] # first simulation local_out = f"{out}/test/{dim}/{interp}/mpi_n/{cpp.mpi_size()}/id{self.ddt_test_id()}" simput["restart_options"]["dir"] = local_out simput["diag_options"]["options"]["dir"] = local_out ph.global_vars.sim = None ph.global_vars.sim = ph.Simulation(**simput) assert "restart_time" not in ph.global_vars.sim.restart_options model = setup_model() dump_all_diags(model.populations, timestamps=np.array(timestamps)) Simulator(ph.global_vars.sim).run().reset() self.register_diag_dir_for_cleanup(local_out) diag_dir0 = local_out # second restarted simulation local_out = f"{local_out}_n2" simput["diag_options"]["options"]["dir"] = local_out simput["restart_options"]["restart_time"] = restart_time ph.global_vars.sim = None ph.global_vars.sim = ph.Simulation(**simput) assert "restart_time" in ph.global_vars.sim.restart_options model = setup_model() dump_all_diags(model.populations, timestamps=np.array(timestamps)) Simulator(ph.global_vars.sim).run().reset() self.register_diag_dir_for_cleanup(local_out) diag_dir1 = local_out def check(qty0, qty1, checker): checks = 0 for ilvl, lvl0 in qty0.patch_levels.items(): patch_level1 = qty1.patch_levels[ilvl] for p_idx, patch0 in enumerate(lvl0): patch1 = patch_level1.patches[p_idx] for pd_key, pd0 in patch0.patch_datas.items(): pd1 = patch1.patch_datas[pd_key] self.assertNotEqual(id(pd0), id(pd1)) checker(pd0, pd1) checks += 1 return checks def check_particles(qty0, qty1): return check( qty0, qty1, lambda pd0, pd1: self.assertEqual(pd0.dataset, pd1.dataset)) def check_field(qty0, qty1): return check( qty0, qty1, lambda pd0, pd1: np.testing.assert_equal( pd0.dataset[:], pd1.dataset[:])) def count_levels_and_patches(qty): n_levels = len(qty.patch_levels) n_patches = 0 for ilvl, lvl in qty.patch_levels.items(): n_patches += len(qty.patch_levels[ilvl].patches) return n_levels, n_patches n_quantities_per_patch = 20 pops = model.populations for time in timestamps: checks = 0 run0 = Run(diag_dir0) run1 = Run(diag_dir1) checks += check_particles(run0.GetParticles(time, pops), run1.GetParticles(time, pops)) checks += check_field(run0.GetB(time), run1.GetB(time)) checks += check_field(run0.GetE(time), run1.GetE(time)) checks += check_field(run0.GetNi(time), run1.GetNi(time)) checks += check_field(run0.GetVi(time), run1.GetVi(time)) for pop in pops: checks += check_field(run0.GetFlux(time, pop), run1.GetFlux(time, pop)) checks += check_field(run0.GetN(time, pop), run1.GetN(time, pop)) n_levels, n_patches = count_levels_and_patches(run0.GetB(time)) self.assertEqual(n_levels, 2) # at least 2 levels self.assertGreaterEqual(n_patches, n_levels) # at least one patch per level self.assertEqual(checks, n_quantities_per_patch * n_patches)