Skip to content

Commit

Permalink
run multiple simulations in // from python
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipDeegan committed Oct 31, 2023
1 parent 276a4d6 commit 3e1349f
Show file tree
Hide file tree
Showing 13 changed files with 570 additions and 35 deletions.
25 changes: 16 additions & 9 deletions pyphare/pyphare/cpp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@

# continue to use override if set
_cpp_lib_override = None
_globals = dict(module=None)

def cpp_lib(override=None):
import importlib

global _cpp_lib_override
if override is not None:
_cpp_lib_override = override
if _cpp_lib_override is not None:
return importlib.import_module(_cpp_lib_override)

if not __debug__:
return importlib.import_module("pybindlibs.cpp")
try:
return importlib.import_module("pybindlibs.cpp_dbg")
except ImportError as err:
return importlib.import_module("pybindlibs.cpp")

def get_module():
if _cpp_lib_override is not None:
return importlib.import_module(_cpp_lib_override)
if not __debug__:
return importlib.import_module("pybindlibs.cpp")
try:
return importlib.import_module("pybindlibs.cpp_dbg")
except ImportError as err:
return importlib.import_module("pybindlibs.cpp")

if _globals["module"] is None:
_globals["module"] = get_module()
print("Loaded C++ module", _globals["module"].__file__)
return _globals["module"]


def cpp_etc_lib():
Expand Down
59 changes: 59 additions & 0 deletions pyphare/pyphare/pharesee/hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ def __init__(self, layout, field_name, data, **kwargs):

self.dataset = data

def compare(self, that, atol=1e-16, rtol=0):
if isinstance(that, FieldData):
assert self.name == that.name
# drop nans
a = self.dataset
b = that.dataset
mask = ~(np.isnan(a) | np.isnan(b))
if __debug__:
try:
np.testing.assert_allclose(a[mask], b[mask], atol=atol, rtol=rtol)
except AssertionError as e:
print(f"FieldData comparison failure in {self.name}")
raise e
return True
return np.allclose(a[mask], b[mask], atol=atol, rtol=rtol)
return False

def meshgrid(self, select=None):
def grid():
Expand All @@ -182,6 +198,10 @@ def grid():
return mesh


def __eq__(self, that):
return self.compare(that)


class ParticleData(PatchData):
"""
Concrete type of PatchData representing particles in a region
Expand Down Expand Up @@ -1690,3 +1710,42 @@ def get_times_from_h5(filepath):
times = np.array(sorted([float(s) for s in list(f["t"].keys())]))
f.close()
return times


def hierarchy_compare(this, that):
if not isinstance(this, PatchHierarchy) or not isinstance(that, PatchHierarchy):
return False

if this.ndim != that.ndim or this.domain_box != that.domain_box:
return False

if this.time_hier.keys() != that.time_hier.keys():
return False

for tidx in this.times():
patch_levels_ref = this.time_hier[tidx]
patch_levels_cmp = that.time_hier[tidx]

if patch_levels_ref.keys() != patch_levels_cmp.keys():
return False

for level_idx in patch_levels_cmp.keys():
patch_level_ref = patch_levels_ref[level_idx]
patch_level_cmp = patch_levels_cmp[level_idx]

for patch_idx in range(len(patch_level_cmp.patches)):
patch_ref = patch_level_ref.patches[patch_idx]
patch_cmp = patch_level_cmp.patches[patch_idx]

if patch_ref.patch_datas.keys() != patch_cmp.patch_datas.keys():
return False

for patch_data_key in patch_ref.patch_datas.keys():
patch_data_ref = patch_ref.patch_datas[patch_data_key]
patch_data_cmp = patch_cmp.patch_datas[patch_data_key]

if patch_data_cmp != patch_data_ref:
return False

return True

8 changes: 4 additions & 4 deletions pyphare/pyphare/pharesee/particles.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ def all_assert_sorted(part1, part2):
deltol = 1e-6 if any([part.deltas.dtype == np.float32 for part in [part1, part2]] ) else 1e-12

np.testing.assert_array_equal(part1.iCells[idx1], part2.iCells[idx2])
np.testing.assert_allclose(part1.deltas[idx1], part2.deltas[idx2], atol=deltol)
np.testing.assert_allclose(part1.deltas[idx1], part2.deltas[idx2], rtol=0, atol=deltol)

np.testing.assert_allclose(part1.v[idx1,0], part2.v[idx2,0], atol=1e-12)
np.testing.assert_allclose(part1.v[idx1,1], part2.v[idx2,1], atol=1e-12)
np.testing.assert_allclose(part1.v[idx1,2], part2.v[idx2,2], atol=1e-12)
np.testing.assert_allclose(part1.v[idx1,0], part2.v[idx2,0], rtol=0, atol=1e-12)
np.testing.assert_allclose(part1.v[idx1,1], part2.v[idx2,1], rtol=0, atol=1e-12)
np.testing.assert_allclose(part1.v[idx1,2], part2.v[idx2,2], rtol=0, atol=1e-12)


def any_assert(part1, part2):
Expand Down
22 changes: 13 additions & 9 deletions pyphare/pyphare/pharesee/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,18 @@ def GetDl(self, level='finest', time=None):
def GetAllAvailableQties(self, time, pops):
assert self.single_hier_for_all_quantities == True # can't work otherwise

self.GetParticles(time, pops)
self.GetB(time)
self.GetE(time)
self.GetNi(time)
self.GetVi(time)

for pop in pops:
self.GetFlux(time, pop)
self.GetN(time, pop)
for fn in [self.GetB, self.GetE, self.GetNi, self.GetVi]:
try:
fn(time)
except:
pass

try:
self.GetParticles(time, pops)
for pop in pops:
self.GetFlux(time, pop)
self.GetN(time, pop)
except:
pass

return self.hier
4 changes: 4 additions & 0 deletions pyphare/pyphare/simulator/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ def _auto_dump(self):
return self.auto_dump and self.dump()


def finished(self):
return self.cpp_sim.currentTime() >= self.cpp_sim.endTime()


def dump(self, *args):
assert len(args) == 0 or len(args) == 2

Expand Down
Loading

0 comments on commit 3e1349f

Please sign in to comment.