Skip to content

Commit 27e8032

Browse files
committed
branch initial commit: cleaned history and simulator merging
1 parent f177c5c commit 27e8032

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1718
-821
lines changed

pyphare/pyphare/pharein/__init__.py

Lines changed: 23 additions & 349 deletions
Large diffs are not rendered by default.

pyphare/pyphare/pharein/init.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
def get_user_inputs(jobname):
22
import importlib
3-
from . import populateDict
3+
import sys
4+
45
import pyphare.pharein as _init_
56

6-
_init_.PHARE_EXE = True
7-
print(jobname)
8-
jobmodule = importlib.import_module(jobname) # lgtm [py/unused-local-variable]
9-
if jobmodule is None:
10-
raise RuntimeError("failed to import job")
11-
populateDict()
7+
from . import populateDict
8+
9+
try:
10+
_init_.PHARE_EXE = True
11+
jobmodule = importlib.import_module(jobname) # lgtm [py/unused-local-variable]
12+
if jobmodule is None:
13+
raise RuntimeError("failed to import job")
14+
populateDict()
15+
16+
except Exception as e:
17+
import traceback
18+
19+
print(f"Exception caught in pharein/init::get_user_inputs: \n{e}")
20+
print(traceback.format_exc())
21+
sys.exit(1)
22+
except ...:
23+
print(f"UNKNOWN Exception caught in pharein/init::get_user_inputs")
24+
sys.exit(1)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import general, hybrid, mhd
2+
3+
__all__ = ["general", "hybrid", "mhd"]
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
import os
2+
3+
import numpy as np
4+
from pyphare.core.phare_utilities import is_scalar
5+
from pyphare.pharein.load_balancer import LoadBalancer
6+
from pyphare.pharein.simulation import deserialize as deserialize_sim
7+
from pyphare.pharein.simulation import serialize as serialize_sim
8+
9+
import pybindlibs.dictator as pp
10+
11+
12+
def _patch_data_ids(restart_file_dir):
13+
"""
14+
for restarts we save samrai patch data ids to the restart files, which we access from here
15+
to tell samrai which patch datas to load from the restart file on restart
16+
"""
17+
from pyphare.cpp import cpp_etc_lib
18+
19+
return cpp_etc_lib().patch_data_ids(restart_file_dir)
20+
21+
22+
def _serialized_simulation_string(restart_file_dir):
23+
from pyphare.cpp import cpp_etc_lib
24+
25+
return cpp_etc_lib().serialized_simulation_string(restart_file_dir)
26+
27+
28+
# converts scalars to array of expected size
29+
# converts lists to arrays
30+
class py_fn_wrapper:
31+
def __init__(self, fn):
32+
self.fn = fn
33+
34+
def __call__(self, *xyz):
35+
args = [np.asarray(arg) for arg in xyz]
36+
ret = self.fn(*args)
37+
if isinstance(ret, list):
38+
ret = np.asarray(ret)
39+
if is_scalar(ret):
40+
ret = np.full(len(args[-1]), ret)
41+
return ret
42+
43+
44+
# Wrap calls to user init functions to turn C++ vectors to ndarrays,
45+
# and returned ndarrays to C++ span
46+
class fn_wrapper(py_fn_wrapper):
47+
def __init__(self, fn):
48+
super().__init__(fn)
49+
50+
def __call__(self, *xyz):
51+
from pyphare.cpp import cpp_etc_lib
52+
53+
# convert numpy array to C++ SubSpan
54+
# couples vector init functions to C++
55+
return cpp_etc_lib().makePyArrayWrapper(super().__call__(*xyz))
56+
57+
58+
# pybind complains if receiving wrong type
59+
def add_int(path, val):
60+
pp.add_int(path, int(val))
61+
62+
63+
def add_bool(path, val):
64+
pp.add_bool(path, bool(val))
65+
66+
67+
def add_double(path, val):
68+
pp.add_double(path, float(val))
69+
70+
71+
def add_size_t(path, val):
72+
casted = int(val)
73+
if casted < 0:
74+
raise RuntimeError("pyphare.__init__::add_size_t received negative value")
75+
pp.add_size_t(path, casted)
76+
77+
78+
def add_vector_int(path, val):
79+
pp.add_vector_int(path, list(val))
80+
81+
82+
add_string = pp.add_string
83+
84+
85+
def populateDict(sim):
86+
87+
add_string("simulation/name", "simulation_test")
88+
add_int("simulation/dimension", sim.ndim)
89+
90+
if sim.smallest_patch_size is not None:
91+
add_vector_int("simulation/AMR/smallest_patch_size", sim.smallest_patch_size)
92+
if sim.largest_patch_size is not None:
93+
add_vector_int("simulation/AMR/largest_patch_size", sim.largest_patch_size)
94+
95+
add_string("simulation/grid/layout_type", sim.layout)
96+
add_int("simulation/grid/nbr_cells/x", sim.cells[0])
97+
add_double("simulation/grid/meshsize/x", sim.dl[0])
98+
add_double("simulation/grid/origin/x", sim.origin[0])
99+
add_string("simulation/grid/boundary_type/x", sim.boundary_types[0])
100+
101+
if sim.ndim > 1:
102+
add_int("simulation/grid/nbr_cells/y", sim.cells[1])
103+
add_double("simulation/grid/meshsize/y", sim.dl[1])
104+
add_double("simulation/grid/origin/y", sim.origin[1])
105+
add_string("simulation/grid/boundary_type/y", sim.boundary_types[1])
106+
107+
if sim.ndim > 2:
108+
add_int("simulation/grid/nbr_cells/z", sim.cells[2])
109+
add_double("simulation/grid/meshsize/z", sim.dl[2])
110+
add_double("simulation/grid/origin/z", sim.origin[2])
111+
add_string("simulation/grid/boundary_type/z", sim.boundary_types[2])
112+
113+
add_int("simulation/interp_order", sim.interp_order)
114+
add_int("simulation/refined_particle_nbr", sim.refined_particle_nbr)
115+
add_double("simulation/time_step", sim.time_step)
116+
add_int("simulation/time_step_nbr", sim.time_step_nbr)
117+
118+
add_string("simulation/AMR/clustering", sim.clustering)
119+
add_vector_int("simulation/AMR/nesting_buffer", sim.nesting_buffer)
120+
add_int("simulation/AMR/tag_buffer", sim.tag_buffer)
121+
122+
add_int("simulation/AMR/max_nbr_levels", sim.max_nbr_levels)
123+
124+
if not sim.max_mhd_level:
125+
sim.max_mhd_level = 0
126+
127+
add_int("simulation/AMR/max_mhd_level", sim.max_mhd_level)
128+
129+
refinement_boxes = sim.refinement_boxes
130+
131+
def as_paths(rb):
132+
add_int("simulation/AMR/refinement/boxes/nbr_levels/", len(rb.keys()))
133+
for level, boxes in rb.items():
134+
level_path = "simulation/AMR/refinement/boxes/" + level + "/"
135+
add_int(level_path + "nbr_boxes/", int(len(boxes)))
136+
for box_i, box in enumerate(boxes):
137+
box_id = "B" + str(box_i)
138+
lower = box.lower
139+
upper = box.upper
140+
box_lower_path_x = box_id + "/lower/x/"
141+
box_upper_path_x = box_id + "/upper/x/"
142+
add_int(level_path + box_lower_path_x, lower[0])
143+
add_int(level_path + box_upper_path_x, upper[0])
144+
if len(lower) >= 2:
145+
box_lower_path_y = box_id + "/lower/y/"
146+
box_upper_path_y = box_id + "/upper/y/"
147+
add_int(level_path + box_lower_path_y, lower[1])
148+
add_int(level_path + box_upper_path_y, upper[1])
149+
if len(lower) == 3:
150+
box_lower_path_z = box_id + "/lower/z/"
151+
box_upper_path_z = box_id + "/upper/z/"
152+
add_int(level_path + box_lower_path_z, lower[2])
153+
add_int(level_path + box_upper_path_z, upper[2])
154+
155+
if refinement_boxes is not None and sim.refinement == "boxes":
156+
as_paths(refinement_boxes)
157+
elif sim.refinement == "tagging":
158+
add_string("simulation/AMR/refinement/tagging/method", "auto")
159+
# the two following params are hard-coded for now
160+
# they will become configurable when we have multi-models or several methods
161+
# per model
162+
add_double("simulation/AMR/refinement/tagging/threshold", sim.tagging_threshold)
163+
else:
164+
add_string(
165+
"simulation/AMR/refinement/tagging/method", "none"
166+
) # integrator.h might want some looking at
167+
168+
# load balancer block start
169+
lb = sim.load_balancer or LoadBalancer(active=False, _register=False)
170+
base = "simulation/AMR/loadbalancing"
171+
add_bool(f"{base}/active", lb.active)
172+
add_string(f"{base}/mode", lb.mode)
173+
add_double(f"{base}/tolerance", lb.tol)
174+
175+
# if mode==nppc, imbalance allowed
176+
add_bool(f"{base}/auto", lb.auto)
177+
add_size_t(f"{base}/next_rebalance", lb.next_rebalance)
178+
add_size_t(f"{base}/max_next_rebalance", lb.max_next_rebalance)
179+
add_size_t(
180+
f"{base}/next_rebalance_backoff_multiplier",
181+
lb.next_rebalance_backoff_multiplier,
182+
)
183+
184+
# cadence based values
185+
add_size_t(f"{base}/every", lb.every)
186+
add_bool(f"{base}/on_init", lb.on_init)
187+
# load balancer block end
188+
189+
serialized_sim = serialize_sim(sim)
190+
191+
#### adding diagnostics
192+
193+
diag_path = "simulation/diagnostics/"
194+
for diag in list(sim.diagnostics.values()):
195+
diag.attributes["serialized_simulation"] = serialized_sim
196+
197+
type_path = diag_path + diag.type + "/"
198+
name_path = type_path + diag.name
199+
add_string(name_path + "/" + "type", diag.type)
200+
add_string(name_path + "/" + "quantity", diag.quantity)
201+
add_size_t(name_path + "/" + "flush_every", diag.flush_every)
202+
pp.add_array_as_vector(
203+
name_path + "/" + "write_timestamps", diag.write_timestamps
204+
)
205+
pp.add_array_as_vector(
206+
name_path + "/" + "compute_timestamps", diag.compute_timestamps
207+
)
208+
209+
add_size_t(name_path + "/" + "n_attributes", len(diag.attributes))
210+
for attr_idx, attr_key in enumerate(diag.attributes):
211+
add_string(name_path + "/" + f"attribute_{attr_idx}_key", attr_key)
212+
add_string(
213+
name_path + "/" + f"attribute_{attr_idx}_value",
214+
diag.attributes[attr_key],
215+
)
216+
217+
if len(sim.diagnostics) > 0:
218+
if sim.diag_options is not None and "options" in sim.diag_options:
219+
add_string(diag_path + "filePath", sim.diag_options["options"]["dir"])
220+
if "mode" in sim.diag_options["options"]:
221+
add_string(diag_path + "mode", sim.diag_options["options"]["mode"])
222+
if "fine_dump_lvl_max" in sim.diag_options["options"]:
223+
add_int(
224+
diag_path + "fine_dump_lvl_max",
225+
sim.diag_options["options"]["fine_dump_lvl_max"],
226+
)
227+
else:
228+
add_string(diag_path + "filePath", "phare_output")
229+
#### diagnostics added
230+
231+
#### adding restarts
232+
if sim.restart_options is not None:
233+
restart_options = sim.restart_options
234+
restarts_path = "simulation/restarts/"
235+
restart_file_path = "phare_outputs"
236+
237+
if "dir" in restart_options:
238+
restart_file_path = restart_options["dir"]
239+
240+
if "restart_time" in restart_options:
241+
from pyphare.cpp import cpp_etc_lib
242+
243+
restart_time = restart_options["restart_time"]
244+
restart_file_load_path = cpp_etc_lib().restart_path_for_time(
245+
restart_file_path, restart_time
246+
)
247+
248+
if not os.path.exists(restart_file_load_path):
249+
raise ValueError(
250+
f"PHARE restart file not found for time {restart_time}"
251+
)
252+
253+
deserialized_simulation = deserialize_sim(
254+
_serialized_simulation_string(restart_file_load_path)
255+
)
256+
if not sim.is_restartable_compared_to(deserialized_simulation):
257+
raise ValueError(
258+
"deserialized Restart simulation is incompatible with configured simulation parameters"
259+
)
260+
261+
add_vector_int(
262+
restarts_path + "restart_ids", _patch_data_ids(restart_file_load_path)
263+
)
264+
add_string(restarts_path + "loadPath", restart_file_load_path)
265+
add_double(restarts_path + "restart_time", restart_time)
266+
267+
if "mode" in restart_options:
268+
add_string(restarts_path + "mode", restart_options["mode"])
269+
270+
add_string(restarts_path + "filePath", restart_file_path)
271+
272+
if "elapsed_timestamps" in restart_options:
273+
pp.add_array_as_vector(
274+
restarts_path + "elapsed_timestamps",
275+
restart_options["elapsed_timestamps"],
276+
)
277+
278+
if "timestamps" in restart_options:
279+
pp.add_array_as_vector(
280+
restarts_path + "write_timestamps", restart_options["timestamps"]
281+
)
282+
283+
add_string(restarts_path + "serialized_simulation", serialized_sim)
284+
#### restarts added
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import pybindlibs.dictator as pp
2+
3+
from .general import add_double, add_int, add_size_t, add_string, fn_wrapper
4+
5+
6+
def populateDict(sim):
7+
8+
addInitFunction = getattr(pp, "addInitFunction{:d}".format(sim.ndim) + "D")
9+
10+
if sim.refinement == "tagging":
11+
add_string("simulation/AMR/refinement/tagging/hybrid_method", "default")
12+
13+
add_string("simulation/algo/ion_updater/pusher/name", sim.particle_pusher)
14+
15+
add_double("simulation/algo/ohm/resistivity", sim.resistivity)
16+
add_double("simulation/algo/ohm/hyper_resistivity", sim.hyper_resistivity)
17+
add_string("simulation/algo/ohm/hyper_mode", sim.hyper_mode)
18+
19+
init_model = sim.model
20+
modelDict = init_model.model_dict
21+
22+
if init_model.nbr_populations() < 0:
23+
raise RuntimeError("Number of populations cannot be negative")
24+
add_size_t("simulation/ions/nbrPopulations", init_model.nbr_populations())
25+
26+
partinit = "particle_initializer"
27+
for pop_index, pop in enumerate(init_model.populations):
28+
pop_path = "simulation/ions/pop"
29+
partinit_path = pop_path + "{:d}/".format(pop_index) + partinit + "/"
30+
d = modelDict[pop]
31+
add_string(pop_path + "{:d}/name".format(pop_index), pop)
32+
add_double(pop_path + "{:d}/mass".format(pop_index), d["mass"])
33+
add_string(partinit_path + "name", "maxwellian")
34+
35+
addInitFunction(partinit_path + "density", fn_wrapper(d["density"]))
36+
addInitFunction(partinit_path + "bulk_velocity_x", fn_wrapper(d["vx"]))
37+
addInitFunction(partinit_path + "bulk_velocity_y", fn_wrapper(d["vy"]))
38+
addInitFunction(partinit_path + "bulk_velocity_z", fn_wrapper(d["vz"]))
39+
addInitFunction(partinit_path + "thermal_velocity_x", fn_wrapper(d["vthx"]))
40+
addInitFunction(partinit_path + "thermal_velocity_y", fn_wrapper(d["vthy"]))
41+
addInitFunction(partinit_path + "thermal_velocity_z", fn_wrapper(d["vthz"]))
42+
add_double(partinit_path + "charge", d["charge"])
43+
add_string(partinit_path + "basis", "cartesian")
44+
if "init" in d and "seed" in d["init"]:
45+
pp.add_optional_size_t(partinit_path + "init/seed", d["init"]["seed"])
46+
47+
add_int(partinit_path + "nbr_part_per_cell", d["nbrParticlesPerCell"])
48+
add_double(partinit_path + "density_cut_off", d["density_cut_off"])
49+
50+
add_string("simulation/electromag/name", "EM")
51+
add_string("simulation/electromag/electric/name", "E")
52+
53+
add_string("simulation/electromag/magnetic/name", "B")
54+
maginit_path = "simulation/electromag/magnetic/initializer/"
55+
addInitFunction(maginit_path + "x_component", fn_wrapper(modelDict["bx"]))
56+
addInitFunction(maginit_path + "y_component", fn_wrapper(modelDict["by"]))
57+
addInitFunction(maginit_path + "z_component", fn_wrapper(modelDict["bz"]))
58+
59+
#### adding electrons
60+
if sim.electrons is None:
61+
raise RuntimeError("Error - no electrons registered to this Simulation")
62+
else:
63+
for item in sim.electrons.dict_path():
64+
if isinstance(item[1], str):
65+
add_string("simulation/" + item[0], item[1])
66+
else:
67+
add_double("simulation/" + item[0], item[1])

0 commit comments

Comments
 (0)