1
1
import os
2
2
import sys
3
3
import subprocess
4
- import numpy as np
5
4
6
- from pyphare .core .phare_utilities import is_scalar
7
5
from .uniform_model import UniformModel
8
6
from .maxwellian_fluid_model import MaxwellianFluidModel
9
7
from .electron_model import ElectronModel
14
12
MetaDiagnostics ,
15
13
InfoDiagnostics ,
16
14
)
17
- from .simulation import (
18
- Simulation ,
19
- serialize as serialize_sim ,
20
- deserialize as deserialize_sim ,
21
- )
15
+ from .simulation import Simulation
22
16
from .load_balancer import LoadBalancer
23
17
24
18
__all__ = [
31
25
"MetaDiagnostics" ,
32
26
"InfoDiagnostics" ,
33
27
"Simulation" ,
28
+ "LoadBalancer" ,
34
29
]
35
30
36
31
# 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():
64
59
mpl .use ("Agg" )
65
60
66
61
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
-
119
62
def clearDict ():
120
63
"""
121
64
dict may contain dangling references from a previous simulation unless cleared
@@ -126,279 +69,12 @@ def clearDict():
126
69
127
70
128
71
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
392
74
393
- add_string (restarts_path + "serialized_simulation" , serialized_sim )
394
- #### restarts added
75
+ initialize .general .populateDict (sim )
395
76
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 )
399
79
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