Skip to content

Commit 8473002

Browse files
committed
introduce charge, mass and particle densities
1 parent e61b34c commit 8473002

Some content is hidden

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

45 files changed

+726
-268
lines changed

pyphare/pyphare/pharein/diagnostics.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ def population_in_model(population):
222222
class FluidDiagnostics_(Diagnostics):
223223
fluid_quantities = [
224224
"density",
225+
"charge_density",
225226
"mass_density",
226227
"flux",
227228
"bulkVelocity",

pyphare/pyphare/pharesee/hierarchy/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212

1313
def hierarchy_from(
14-
simulator=None, qty=None, pop="", h5_filename=None, times=None, hier=None, **kwargs
14+
simulator=None, qty=None, pop="", h5_filename=None, times=None, hier=None, func=None, **kwargs
1515
):
1616
from .fromh5 import hierarchy_fromh5
1717
from .fromsim import hierarchy_from_sim
18+
from .fromfunc import hierarchy_from_func
1819

1920
"""
2021
this function reads an HDF5 PHARE file and returns a PatchHierarchy from
@@ -39,4 +40,9 @@ def hierarchy_from(
3940
if simulator is not None and qty is not None:
4041
return hierarchy_from_sim(simulator, qty, pop=pop)
4142

43+
if func is not None and hier is not None:
44+
if not callable(func):
45+
raise TypeError("func must be callable")
46+
return hierarchy_from_func(func, hier, **kwargs)
47+
4248
raise ValueError("can't make hierarchy")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from pyphare.pharesee.hierarchy.hierarchy_utils import compute_hier_from
2+
3+
4+
def hierarchy_from_func1d(func, hier, **kwargs):
5+
assert hier.ndim == 1
6+
7+
def compute_(patch_datas, **kwargs):
8+
ref_name = next(iter(patch_datas.keys()))
9+
x_ = patch_datas[ref_name].x
10+
11+
return (
12+
{"name": "value", "data": func(x_, **kwargs), "centering": patch_datas[ref_name].centerings},
13+
)
14+
15+
return compute_hier_from(compute_, hier, **kwargs)
16+
17+
18+
def hierarchy_from_func2d(func, hier, **kwargs):
19+
from pyphare.pharesee.hierarchy.hierarchy_utils import compute_hier_from
20+
21+
def compute_(patch_datas, **kwargs):
22+
ref_name = next(iter(patch_datas.keys()))
23+
x_ = patch_datas[ref_name].x
24+
y_ = patch_datas[ref_name].y
25+
26+
return (
27+
{"name": "value", "data": func(x_, y_, **kwargs), "centering": patch_datas[ref_name].centerings},
28+
)
29+
30+
return compute_hier_from(compute_, hier, **kwargs)
31+
32+
33+
def hierarchy_from_func(func, hier, **kwargs):
34+
35+
"""
36+
Route hierarchical computation to appropriate dimension handler.
37+
38+
Parameters
39+
----------
40+
func : callable
41+
Function to apply to coordinates of the hierarchy
42+
hier : Hierarchy
43+
Hierarchy object (1D or 2D)
44+
**kwargs : dict
45+
Additional arguments passed to func
46+
47+
Returns
48+
-------
49+
dict
50+
Computed hierarchical data
51+
52+
Raises
53+
------
54+
ValueError
55+
If hierarchy dimension is not supported
56+
"""
57+
58+
if hier.ndim == 1:
59+
return hierarchy_from_func1d(func, hier, **kwargs)
60+
if hier.ndim == 2:
61+
return hierarchy_from_func2d(func, hier, **kwargs)
62+
else:
63+
raise ValueError(f"Unsupported hierarchy dimension: {hier.ndim}")

pyphare/pyphare/pharesee/hierarchy/hierarchy.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ def box_to_Rectangle(self, box):
358358
return Rectangle(box.lower, *box.shape)
359359

360360
def plot_2d_patches(self, ilvl, collections, **kwargs):
361+
from matplotlib.patches import Rectangle
362+
361363
if isinstance(collections, list) and all(
362364
[isinstance(el, Box) for el in collections]
363365
):
@@ -368,35 +370,47 @@ def plot_2d_patches(self, ilvl, collections, **kwargs):
368370
level_domain_box = self.level_domain_box(ilvl)
369371
mi, ma = level_domain_box.lower.min(), level_domain_box.upper.max()
370372

371-
fig, ax = kwargs.get("subplot", plt.subplots(figsize=(6, 6)))
373+
fig, ax = kwargs.get("subplot", plt.subplots(figsize=(16, 16)))
374+
375+
i0, j0 = level_domain_box.lower
376+
i1, j1 = level_domain_box.upper
377+
ij = np.zeros((i1 - i0 + 1, j1 - j0 + 1)) + np.nan
378+
ix = np.arange(i0, i1 + 1)
379+
iy = np.arange(j0, j1 + 1)
372380

373381
for collection in collections:
374-
facecolor = collection.get("facecolor", "none")
375-
edgecolor = collection.get("edgecolor", "purple")
376-
alpha = collection.get("alpha", 1)
377-
rects = [self.box_to_Rectangle(box) for box in collection["boxes"]]
378-
379-
ax.add_collection(
380-
PatchCollection(
381-
rects, facecolor=facecolor, alpha=alpha, edgecolor=edgecolor
382-
)
383-
)
382+
value = collection.get("value", np.nan)
383+
for box in collection["boxes"]:
384+
i0, j0 = box.lower
385+
i1, j1 = box.upper
386+
ij[i0 : i1 + 1, j0 : j1 + 1] = value
387+
if "coords" in collection:
388+
for coords in collection["coords"]:
389+
ij[coords] = collection["value"]
390+
391+
ax.pcolormesh(ix, iy, ij.T, edgecolors="k", cmap="jet")
392+
ax.set_xticks(ix)
393+
ax.set_yticks(iy)
394+
395+
for patch in self.level(ilvl).patches:
396+
box = patch.box
397+
r = Rectangle(box.lower - 0.5, *(box.upper + 0.5))
398+
399+
r.set_edgecolor("r")
400+
r.set_facecolor("none")
401+
r.set_linewidth(2)
402+
ax.add_patch(r)
384403

385404
if "title" in kwargs:
386405
from textwrap import wrap
387406

388407
xfigsize = int(fig.get_size_inches()[0] * 10) # 10 characters per inch
389408
ax.set_title("\n".join(wrap(kwargs["title"], xfigsize)))
390409

391-
major_ticks = np.arange(mi - 5, ma + 5 + 5, 5)
392-
ax.set_xticks(major_ticks)
393-
ax.set_yticks(major_ticks)
394-
395-
minor_ticks = np.arange(mi - 5, ma + 5 + 5, 1)
396-
ax.set_xticks(minor_ticks, minor=True)
397-
ax.set_yticks(minor_ticks, minor=True)
398-
399-
ax.grid(which="both")
410+
if "xlim" in kwargs:
411+
ax.set_xlim(kwargs["xlim"])
412+
if "ylim" in kwargs:
413+
ax.set_ylim(kwargs["ylim"])
400414

401415
return fig
402416

@@ -431,7 +445,8 @@ def plot1d(self, **kwargs):
431445
qty = pdata_names[0]
432446

433447
layout = patch.patch_datas[qty].layout
434-
nbrGhosts = layout.nbrGhostFor(qty)
448+
# nbrGhosts = layout.nbrGhostFor(qty) # bad !!!
449+
nbrGhosts = patch.patch_datas[qty].ghosts_nbr
435450
val = patch.patch_datas[qty][patch.box]
436451
x = patch.patch_datas[qty].x[nbrGhosts[0] : -nbrGhosts[0]]
437452
label = "L{level}P{patch}".format(level=lvl_nbr, patch=ip)
@@ -542,9 +557,10 @@ def plot2d(self, **kwargs):
542557
if "ylim" in kwargs:
543558
ax.set_ylim(kwargs["ylim"])
544559

545-
divider = make_axes_locatable(ax)
546-
cax = divider.append_axes("right", size="5%", pad=0.08)
547-
plt.colorbar(im, ax=ax, cax=cax)
560+
if kwargs.get("cbar", True):
561+
divider = make_axes_locatable(ax)
562+
cax = divider.append_axes("right", size="5%", pad=0.08)
563+
fig.colorbar(im, ax=ax, cax=cax)
548564

549565
if kwargs.get("legend", None) is not None:
550566
ax.legend()

pyphare/pyphare/pharesee/hierarchy/hierarchy_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"momentum_tensor_zz": "Mzz",
3737
"density": "rho",
3838
"mass_density": "rho",
39+
"charge_density": "rho",
3940
"tags": "tags",
4041
}
4142

pyphare/pyphare/pharesee/plotting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def finest_field_plot(run_path, qty, **kwargs):
274274
time = times[0]
275275
interpolator, finest_coords = r.GetVi(time, merged=True, interp=interp)[qty]
276276
elif qty == "rho":
277-
file = os.path.join(run_path, "ions_density.h5")
277+
file = os.path.join(run_path, "ions_charge_density.h5")
278278
if time is None:
279279
times = get_times_from_h5(file)
280280
time = times[0]

pyphare/pyphare/pharesee/run/run.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"EM_B": "B",
2828
"EM_E": "E",
2929
"ions_bulkVelocity": "Vi",
30-
"ions_density": "Ni",
30+
"ions_charge_density": "Ni",
3131
"particle_count": "nppc",
3232
}
3333

@@ -114,7 +114,7 @@ def GetMassDensity(self, time, merged=False, interp="nearest", **kwargs):
114114
return ScalarField(self._get(hier, time, merged, interp))
115115

116116
def GetNi(self, time, merged=False, interp="nearest", **kwargs):
117-
hier = self._get_hierarchy(time, "ions_density.h5", **kwargs)
117+
hier = self._get_hierarchy(time, "ions_charge_density.h5", **kwargs)
118118
return ScalarField(self._get(hier, time, merged, interp))
119119

120120
def GetN(self, time, pop_name, merged=False, interp="nearest", **kwargs):
@@ -151,7 +151,7 @@ def GetPi(self, time, merged=False, interp="nearest", **kwargs):
151151
return self._get(Pi, time, merged, interp) # should later be a TensorField
152152

153153
def GetPe(self, time, merged=False, interp="nearest", all_primal=True):
154-
hier = self._get_hierarchy(time, "ions_density.h5")
154+
hier = self._get_hierarchy(time, "ions_charge_density.h5")
155155

156156
Te = hier.sim.electrons.closure.Te
157157

pyphare/pyphare_tests/test_pharesee/test_geometry_2d.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,11 @@ def test_large_patchoverlaps(self, expected):
177177
collections=[
178178
{
179179
"boxes": overlap_boxes,
180-
"facecolor": "yellow",
180+
"value": 1,
181181
},
182182
{
183183
"boxes": [p.box for p in hierarchy.level(ilvl).patches],
184-
"facecolor": "grey",
184+
"value": 2,
185185
},
186186
],
187187
)
@@ -390,11 +390,11 @@ def test_level_ghost_boxes(self, refinement_boxes, expected):
390390
collections=[
391391
{
392392
"boxes": ghost_area_box_list,
393-
"facecolor": "yellow",
393+
"value": 1,
394394
},
395395
{
396396
"boxes": [p.box for p in hierarchy.level(ilvl).patches],
397-
"facecolor": "grey",
397+
"value": 2,
398398
},
399399
],
400400
title="".join(
@@ -502,7 +502,7 @@ def test_patch_periodicity_copy(self, refinement_boxes, expected):
502502
collections=[
503503
{
504504
"boxes": [p.box for p in periodic_list],
505-
"facecolor": "grey",
505+
"value": 2,
506506
},
507507
],
508508
)

pyphare/pyphare_tests/test_pharesee/test_hierarchy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def vthz(x, y):
145145
for quantity in ["E", "B"]:
146146
ph.ElectromagDiagnostics(quantity=quantity, write_timestamps=timestamps)
147147

148-
for quantity in ["density", "bulkVelocity"]:
148+
for quantity in ["charge_density", "bulkVelocity"]:
149149
ph.FluidDiagnostics(quantity=quantity, write_timestamps=timestamps)
150150

151151
return sim

src/amr/level_initializer/hybrid_level_initializer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ namespace solver
9898
core::depositParticles(ions, layout, interpolate_, core::LevelGhostDeposit{});
9999
}
100100

101-
ions.computeDensity();
101+
ions.computeChargeDensity();
102102
ions.computeBulkVelocity();
103103
}
104104

src/amr/messengers/hybrid_hybrid_messenger_strategy.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,20 +385,21 @@ namespace amr
385385
{
386386
// first thing to do is to project patchGhostParitcles moments
387387
auto& patchGhosts = pop.patchGhostParticles();
388-
auto& density = pop.density();
388+
auto& particleDensity = pop.particleDensity();
389+
auto& chargeDensity = pop.chargeDensity();
389390
auto& flux = pop.flux();
390391

391-
interpolate_(makeRange(patchGhosts), density, flux, layout);
392+
interpolate_(makeRange(patchGhosts), particleDensity, chargeDensity, flux, layout);
392393

393394
if (level.getLevelNumber() > 0) // no levelGhost on root level
394395
{
395396
// then grab levelGhostParticlesOld and levelGhostParticlesNew
396397
// and project them with alpha and (1-alpha) coefs, respectively
397398
auto& levelGhostOld = pop.levelGhostParticlesOld();
398-
interpolate_(makeRange(levelGhostOld), density, flux, layout, 1. - alpha);
399+
interpolate_(makeRange(levelGhostOld), particleDensity, chargeDensity, flux, layout, 1. - alpha);
399400

400401
auto& levelGhostNew = pop.levelGhostParticlesNew();
401-
interpolate_(makeRange(levelGhostNew), density, flux, layout, alpha);
402+
interpolate_(makeRange(levelGhostNew), particleDensity, chargeDensity, flux, layout, alpha);
402403
}
403404
}
404405
}
@@ -538,7 +539,7 @@ namespace amr
538539

539540
auto& J = hybridModel.state.J;
540541
auto& Vi = hybridModel.state.ions.velocity();
541-
auto& Ni = hybridModel.state.ions.density();
542+
auto& Ni = hybridModel.state.ions.chargeDensity();
542543

543544
Jold_.copyData(J);
544545
ViOld_.copyData(Vi);

src/amr/physical_models/hybrid_model.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ void HybridModel<GridLayoutT, Electromag, Ions, Electrons, AMR_Types, Grid_t>::f
154154

155155
hybridInfo.modelMagnetic = core::VecFieldNames{state.electromag.B};
156156
hybridInfo.modelElectric = core::VecFieldNames{state.electromag.E};
157-
hybridInfo.modelIonDensity = state.ions.densityName();
157+
hybridInfo.modelIonDensity = state.ions.chargeDensityName();
158158
hybridInfo.modelIonBulkVelocity = core::VecFieldNames{state.ions.velocity()};
159159
hybridInfo.modelCurrent = core::VecFieldNames{state.J};
160160

src/amr/tagging/default_hybrid_tagger_strategy.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void DefaultHybridTaggerStrategy<HybridModel>::tag(HybridModel& model,
3636
auto& By = model.state.electromag.B.getComponent(PHARE::core::Component::Y);
3737
auto& Bz = model.state.electromag.B.getComponent(PHARE::core::Component::Z);
3838

39-
auto& N = model.state.ions.density();
39+
// auto& N = model.state.ions.chargeDensity();
4040

4141
// we loop on cell indexes for all qties regardless of their centering
4242
auto const& [start_x, _]

0 commit comments

Comments
 (0)