Skip to content

Commit 205eb60

Browse files
committed
++
1 parent b891a91 commit 205eb60

File tree

27 files changed

+680
-500
lines changed

27 files changed

+680
-500
lines changed

pyphare/pyphare/pharein/__init__.py

Lines changed: 8 additions & 332 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import os
22
import sys
33
import subprocess
4-
import numpy as np
54

6-
from pyphare.core.phare_utilities import is_scalar
75
from .uniform_model import UniformModel
86
from .maxwellian_fluid_model import MaxwellianFluidModel
97
from .electron_model import ElectronModel
@@ -14,11 +12,7 @@
1412
MetaDiagnostics,
1513
InfoDiagnostics,
1614
)
17-
from .simulation import (
18-
Simulation,
19-
serialize as serialize_sim,
20-
deserialize as deserialize_sim,
21-
)
15+
from .simulation import Simulation
2216
from .load_balancer import LoadBalancer
2317

2418
__all__ = [
@@ -31,6 +25,7 @@
3125
"MetaDiagnostics",
3226
"InfoDiagnostics",
3327
"Simulation",
28+
"LoadBalancer",
3429
]
3530

3631
# This exists to allow a condition variable for when we are running PHARE from C++ via phare-exe
@@ -64,58 +59,6 @@ def NO_GUI():
6459
mpl.use("Agg")
6560

6661

67-
def getSimulation():
68-
from .global_vars import sim
69-
70-
return sim
71-
72-
73-
def _patch_data_ids(restart_file_dir):
74-
"""
75-
for restarts we save samrai patch data ids to the restart files, which we access from here
76-
to tell samrai which patch datas to load from the restart file on restart
77-
"""
78-
from pyphare.cpp import cpp_etc_lib
79-
80-
return cpp_etc_lib().patch_data_ids(restart_file_dir)
81-
82-
83-
def _serialized_simulation_string(restart_file_dir):
84-
from pyphare.cpp import cpp_etc_lib
85-
86-
return cpp_etc_lib().serialized_simulation_string(restart_file_dir)
87-
88-
89-
# converts scalars to array of expected size
90-
# converts lists to arrays
91-
class py_fn_wrapper:
92-
def __init__(self, fn):
93-
self.fn = fn
94-
95-
def __call__(self, *xyz):
96-
args = [np.asarray(arg) for arg in xyz]
97-
ret = self.fn(*args)
98-
if isinstance(ret, list):
99-
ret = np.asarray(ret)
100-
if is_scalar(ret):
101-
ret = np.full(len(args[-1]), ret)
102-
return ret
103-
104-
105-
# Wrap calls to user init functions to turn C++ vectors to ndarrays,
106-
# and returned ndarrays to C++ span
107-
class fn_wrapper(py_fn_wrapper):
108-
def __init__(self, fn):
109-
super().__init__(fn)
110-
111-
def __call__(self, *xyz):
112-
from pyphare.cpp import cpp_etc_lib
113-
114-
# convert numpy array to C++ SubSpan
115-
# couples vector init functions to C++
116-
return cpp_etc_lib().makePyArrayWrapper(super().__call__(*xyz))
117-
118-
11962
def clearDict():
12063
"""
12164
dict may contain dangling references from a previous simulation unless cleared
@@ -126,279 +69,12 @@ def clearDict():
12669

12770

12871
def populateDict():
129-
from .global_vars import sim as simulation
130-
import pybindlibs.dictator as pp
131-
132-
# pybind complains if receiving wrong type
133-
def add_int(path, val):
134-
pp.add_int(path, int(val))
135-
136-
def add_bool(path, val):
137-
pp.add_bool(path, bool(val))
138-
139-
def add_double(path, val):
140-
pp.add_double(path, float(val))
141-
142-
def add_size_t(path, val):
143-
casted = int(val)
144-
if casted < 0:
145-
raise RuntimeError("pyphare.__init__::add_size_t received negative value")
146-
pp.add_size_t(path, casted)
147-
148-
def add_vector_int(path, val):
149-
pp.add_vector_int(path, list(val))
150-
151-
add_string = pp.add_string
152-
addInitFunction = getattr(pp, "addInitFunction{:d}".format(simulation.ndim) + "D")
153-
154-
add_string("simulation/name", "simulation_test")
155-
add_int("simulation/dimension", simulation.ndim)
156-
157-
if simulation.smallest_patch_size is not None:
158-
add_vector_int(
159-
"simulation/AMR/smallest_patch_size", simulation.smallest_patch_size
160-
)
161-
if simulation.largest_patch_size is not None:
162-
add_vector_int(
163-
"simulation/AMR/largest_patch_size", simulation.largest_patch_size
164-
)
165-
166-
add_string("simulation/grid/layout_type", simulation.layout)
167-
add_int("simulation/grid/nbr_cells/x", simulation.cells[0])
168-
add_double("simulation/grid/meshsize/x", simulation.dl[0])
169-
add_double("simulation/grid/origin/x", simulation.origin[0])
170-
add_string("simulation/grid/boundary_type/x", simulation.boundary_types[0])
171-
172-
if simulation.ndim > 1:
173-
add_int("simulation/grid/nbr_cells/y", simulation.cells[1])
174-
add_double("simulation/grid/meshsize/y", simulation.dl[1])
175-
add_double("simulation/grid/origin/y", simulation.origin[1])
176-
add_string("simulation/grid/boundary_type/y", simulation.boundary_types[1])
177-
178-
if simulation.ndim > 2:
179-
add_int("simulation/grid/nbr_cells/z", simulation.cells[2])
180-
add_double("simulation/grid/meshsize/z", simulation.dl[2])
181-
add_double("simulation/grid/origin/z", simulation.origin[2])
182-
add_string("simulation/grid/boundary_type/z", simulation.boundary_types[2])
183-
184-
add_int("simulation/interp_order", simulation.interp_order)
185-
add_int("simulation/refined_particle_nbr", simulation.refined_particle_nbr)
186-
add_double("simulation/time_step", simulation.time_step)
187-
add_int("simulation/time_step_nbr", simulation.time_step_nbr)
188-
189-
add_string("simulation/AMR/clustering", simulation.clustering)
190-
add_int("simulation/AMR/max_nbr_levels", simulation.max_nbr_levels)
191-
add_vector_int("simulation/AMR/nesting_buffer", simulation.nesting_buffer)
192-
193-
add_int("simulation/AMR/tag_buffer", simulation.tag_buffer)
194-
195-
refinement_boxes = simulation.refinement_boxes
196-
197-
def as_paths(rb):
198-
add_int("simulation/AMR/refinement/boxes/nbr_levels/", len(rb.keys()))
199-
for level, boxes in rb.items():
200-
level_path = "simulation/AMR/refinement/boxes/" + level + "/"
201-
add_int(level_path + "nbr_boxes/", int(len(boxes)))
202-
for box_i, box in enumerate(boxes):
203-
box_id = "B" + str(box_i)
204-
lower = box.lower
205-
upper = box.upper
206-
box_lower_path_x = box_id + "/lower/x/"
207-
box_upper_path_x = box_id + "/upper/x/"
208-
add_int(level_path + box_lower_path_x, lower[0])
209-
add_int(level_path + box_upper_path_x, upper[0])
210-
if len(lower) >= 2:
211-
box_lower_path_y = box_id + "/lower/y/"
212-
box_upper_path_y = box_id + "/upper/y/"
213-
add_int(level_path + box_lower_path_y, lower[1])
214-
add_int(level_path + box_upper_path_y, upper[1])
215-
if len(lower) == 3:
216-
box_lower_path_z = box_id + "/lower/z/"
217-
box_upper_path_z = box_id + "/upper/z/"
218-
add_int(level_path + box_lower_path_z, lower[2])
219-
add_int(level_path + box_upper_path_z, upper[2])
220-
221-
if refinement_boxes is not None and simulation.refinement == "boxes":
222-
as_paths(refinement_boxes)
223-
elif simulation.refinement == "tagging":
224-
add_string("simulation/AMR/refinement/tagging/method", "auto")
225-
else:
226-
add_string(
227-
"simulation/AMR/refinement/tagging/method", "none"
228-
) # integrator.h might want some looking at
229-
230-
add_string("simulation/algo/ion_updater/pusher/name", simulation.particle_pusher)
231-
add_double("simulation/algo/ohm/resistivity", simulation.resistivity)
232-
add_double("simulation/algo/ohm/hyper_resistivity", simulation.hyper_resistivity)
233-
234-
# load balancer block start
235-
lb = simulation.load_balancer or LoadBalancer(active=False, _register=False)
236-
base = "simulation/AMR/loadbalancing"
237-
add_bool(f"{base}/active", lb.active)
238-
add_string(f"{base}/mode", lb.mode)
239-
add_double(f"{base}/tolerance", lb.tol)
240-
241-
# if mode==nppc, imbalance allowed
242-
add_bool(f"{base}/auto", lb.auto)
243-
add_size_t(f"{base}/next_rebalance", lb.next_rebalance)
244-
add_size_t(f"{base}/max_next_rebalance", lb.max_next_rebalance)
245-
add_size_t(
246-
f"{base}/next_rebalance_backoff_multiplier",
247-
lb.next_rebalance_backoff_multiplier,
248-
)
249-
250-
# cadence based values
251-
add_size_t(f"{base}/every", lb.every)
252-
add_bool(f"{base}/on_init", lb.on_init)
253-
# load balancer block end
254-
255-
init_model = simulation.model
256-
modelDict = init_model.model_dict
257-
258-
if init_model.nbr_populations() < 0:
259-
raise RuntimeError("Number of populations cannot be negative")
260-
add_size_t("simulation/ions/nbrPopulations", init_model.nbr_populations())
261-
262-
partinit = "particle_initializer"
263-
for pop_index, pop in enumerate(init_model.populations):
264-
pop_path = "simulation/ions/pop"
265-
partinit_path = pop_path + "{:d}/".format(pop_index) + partinit + "/"
266-
d = modelDict[pop]
267-
add_string(pop_path + "{:d}/name".format(pop_index), pop)
268-
add_double(pop_path + "{:d}/mass".format(pop_index), d["mass"])
269-
add_string(partinit_path + "name", "maxwellian")
270-
271-
addInitFunction(partinit_path + "density", fn_wrapper(d["density"]))
272-
addInitFunction(partinit_path + "bulk_velocity_x", fn_wrapper(d["vx"]))
273-
addInitFunction(partinit_path + "bulk_velocity_y", fn_wrapper(d["vy"]))
274-
addInitFunction(partinit_path + "bulk_velocity_z", fn_wrapper(d["vz"]))
275-
addInitFunction(partinit_path + "thermal_velocity_x", fn_wrapper(d["vthx"]))
276-
addInitFunction(partinit_path + "thermal_velocity_y", fn_wrapper(d["vthy"]))
277-
addInitFunction(partinit_path + "thermal_velocity_z", fn_wrapper(d["vthz"]))
278-
add_double(partinit_path + "charge", d["charge"])
279-
add_string(partinit_path + "basis", "cartesian")
280-
if "init" in d and "seed" in d["init"]:
281-
pp.add_optional_size_t(partinit_path + "init/seed", d["init"]["seed"])
282-
283-
add_int(partinit_path + "nbr_part_per_cell", d["nbrParticlesPerCell"])
284-
add_double(partinit_path + "density_cut_off", d["density_cut_off"])
285-
286-
add_string("simulation/electromag/name", "EM")
287-
add_string("simulation/electromag/electric/name", "E")
288-
289-
add_string("simulation/electromag/magnetic/name", "B")
290-
maginit_path = "simulation/electromag/magnetic/initializer/"
291-
addInitFunction(maginit_path + "x_component", fn_wrapper(modelDict["bx"]))
292-
addInitFunction(maginit_path + "y_component", fn_wrapper(modelDict["by"]))
293-
addInitFunction(maginit_path + "z_component", fn_wrapper(modelDict["bz"]))
294-
295-
serialized_sim = serialize_sim(simulation)
296-
297-
#### adding diagnostics
298-
299-
diag_path = "simulation/diagnostics/"
300-
for diag in list(simulation.diagnostics.values()):
301-
diag.attributes["serialized_simulation"] = serialized_sim
302-
303-
type_path = diag_path + diag.type + "/"
304-
name_path = type_path + diag.name
305-
add_string(name_path + "/" + "type", diag.type)
306-
add_string(name_path + "/" + "quantity", diag.quantity)
307-
add_size_t(name_path + "/" + "flush_every", diag.flush_every)
308-
pp.add_array_as_vector(
309-
name_path + "/" + "write_timestamps", diag.write_timestamps
310-
)
311-
pp.add_array_as_vector(
312-
name_path + "/" + "compute_timestamps", diag.compute_timestamps
313-
)
314-
315-
add_size_t(name_path + "/" + "n_attributes", len(diag.attributes))
316-
for attr_idx, attr_key in enumerate(diag.attributes):
317-
add_string(name_path + "/" + f"attribute_{attr_idx}_key", attr_key)
318-
add_string(
319-
name_path + "/" + f"attribute_{attr_idx}_value",
320-
diag.attributes[attr_key],
321-
)
322-
323-
if len(simulation.diagnostics) > 0:
324-
if simulation.diag_options is not None and "options" in simulation.diag_options:
325-
add_string(
326-
diag_path + "filePath", simulation.diag_options["options"]["dir"]
327-
)
328-
if "mode" in simulation.diag_options["options"]:
329-
add_string(
330-
diag_path + "mode", simulation.diag_options["options"]["mode"]
331-
)
332-
if "fine_dump_lvl_max" in simulation.diag_options["options"]:
333-
add_int(
334-
diag_path + "fine_dump_lvl_max",
335-
simulation.diag_options["options"]["fine_dump_lvl_max"],
336-
)
337-
else:
338-
add_string(diag_path + "filePath", "phare_output")
339-
#### diagnostics added
340-
341-
#### adding restarts
342-
if simulation.restart_options is not None:
343-
restart_options = simulation.restart_options
344-
restarts_path = "simulation/restarts/"
345-
restart_file_path = "phare_outputs"
346-
347-
if "dir" in restart_options:
348-
restart_file_path = restart_options["dir"]
349-
350-
if "restart_time" in restart_options:
351-
from pyphare.cpp import cpp_etc_lib
352-
353-
restart_time = restart_options["restart_time"]
354-
restart_file_load_path = cpp_etc_lib().restart_path_for_time(
355-
restart_file_path, restart_time
356-
)
357-
358-
if not os.path.exists(restart_file_load_path):
359-
raise ValueError(
360-
f"PHARE restart file not found for time {restart_time}"
361-
)
362-
363-
deserialized_simulation = deserialize_sim(
364-
_serialized_simulation_string(restart_file_load_path)
365-
)
366-
if not simulation.is_restartable_compared_to(deserialized_simulation):
367-
raise ValueError(
368-
"deserialized Restart simulation is incompatible with configured simulation parameters"
369-
)
370-
371-
add_vector_int(
372-
restarts_path + "restart_ids", _patch_data_ids(restart_file_load_path)
373-
)
374-
add_string(restarts_path + "loadPath", restart_file_load_path)
375-
add_double(restarts_path + "restart_time", restart_time)
376-
377-
if "mode" in restart_options:
378-
add_string(restarts_path + "mode", restart_options["mode"])
379-
380-
add_string(restarts_path + "filePath", restart_file_path)
381-
382-
if "elapsed_timestamps" in restart_options:
383-
pp.add_array_as_vector(
384-
restarts_path + "elapsed_timestamps",
385-
restart_options["elapsed_timestamps"],
386-
)
387-
388-
if "timestamps" in restart_options:
389-
pp.add_array_as_vector(
390-
restarts_path + "write_timestamps", restart_options["timestamps"]
391-
)
72+
from .global_vars import sim
73+
from . import initialize
39274

393-
add_string(restarts_path + "serialized_simulation", serialized_sim)
394-
#### restarts added
75+
initialize.general.populateDict(sim)
39576

396-
#### adding electrons
397-
if simulation.electrons is None:
398-
raise RuntimeError("Error - no electrons registered to this Simulation")
77+
if sim.init_options is None:
78+
initialize.user_fns.populateDict(sim)
39979
else:
400-
for item in simulation.electrons.dict_path():
401-
if isinstance(item[1], str):
402-
add_string("simulation/" + item[0], item[1])
403-
else:
404-
add_double("simulation/" + item[0], item[1])
80+
initialize.samrai_hdf5.populateDict(sim)

0 commit comments

Comments
 (0)