Skip to content

Commit

Permalink
3d-ish
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipDeegan committed Jun 24, 2024
1 parent fc41581 commit 914fce6
Show file tree
Hide file tree
Showing 45 changed files with 1,984 additions and 545 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake_macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
cmake $GITHUB_WORKSPACE -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DENABLE_SAMRAI_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DlowResourceTests=ON \
-DCMAKE_CXX_FLAGS="-DPHARE_DIAG_DOUBLES=1 -O2"
-DCMAKE_CXX_FLAGS="-DPHARE_DIAG_DOUBLES=1 -O2 -DPHARE_SIMULATORS=2"
- name: Build
working-directory: ${{runner.workspace}}/build
Expand Down
40 changes: 40 additions & 0 deletions pyphare/pyphare/core/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def __eq__(self, other):
)

def __sub__(self, other):
if isinstance(other, (list, tuple)):
assert all([isinstance(item, Box) for item in other])
return remove_all(self, other)
assert isinstance(other, Box)
return remove(self, other)

Expand Down Expand Up @@ -179,5 +182,42 @@ def copy(arr, replace):
return list(boxes.values())


def remove_all(box, to_remove):
if len(to_remove) > 0:
remaining = box - to_remove[0]
for to_rm in to_remove[1:]:
tmp, remove = [], []
for i, rem in enumerate(remaining):
if rem * to_rm is not None:
remove.append(i)
tmp += rem - to_rm
for rm in reversed(remove):
del remaining[rm]
remaining += tmp
return remaining
return box



def amr_to_local(box, ref_box):
return Box(box.lower - ref_box.lower, box.upper - ref_box.lower)


def select(data, box):
return data[tuple([slice(l, u + 1) for l,u in zip(box.lower, box.upper)])]

class DataSelector:
"""
can't assign return to function unless []
usage
DataSelector(data)[box] = val
"""
def __init__(self, data):
self.data = data
def __getitem__(self, box_or_slice):
if isinstance(box_or_slice, Box):
return select(self.data, box_or_slice)
return self.data[box_or_slice]

def __setitem__(self, box_or_slice, val):
self.__getitem__(box_or_slice)[:] = val
14 changes: 14 additions & 0 deletions pyphare/pyphare/core/gridlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,20 @@ def yeeCoords(self, knode, iStart, centering, direction, ds, origin, derivOrder)

return x

def meshCoords(self, qty):
ndim = self.ndim
assert ndim > 0 and ndim < 4
x = self.yeeCoordsFor(qty, "x")
if ndim == 1:
return x
y = self.yeeCoordsFor(qty, "y")
if ndim == 2:
X,Y = np.meshgrid(x,y,indexing="ij")
return np.array([X.flatten(),Y.flatten()]).T.reshape((len(x), len(y), ndim))
z = self.yeeCoordsFor(qty, "z")
X ,Y, Z = np.meshgrid(x,y,z,indexing="ij")
return np.array([X.flatten(), Y.flatten(), Z.flatten()]).T.reshape((len(x), len(y), len(z), ndim))

def yeeCoordsFor(self, qty, direction, withGhosts=True, **kwargs):
"""
from a qty and a direction, returns a 1d array containing
Expand Down
129 changes: 82 additions & 47 deletions pyphare/pyphare/pharesee/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,24 @@ def domain_border_ghost_boxes(domain_box, patches):
elif domain_box.ndim == 2:
upper_x, upper_y = domain_box.upper
return {
"bottom": Box(
(
0,
0,
),
(upper_x, ghost_box_width),
),
"top": Box((0, upper_y - ghost_box_width), (upper_x, upper_y)),
"left": Box((0, 0), (ghost_box_width, upper_y)),
"right": Box((upper_x - ghost_box_width, 0), (upper_x, upper_y)),
"bottom": Box((0, 0), (upper_x, ghost_box_width)),
"top": Box((0, upper_y - ghost_box_width), (upper_x, upper_y)),
}

raise ValueError("Unhandeled dimension")
else:
upper_x, upper_y, upper_z = domain_box.upper
return {
"left": Box((0, 0, 0), (ghost_box_width, upper_y, upper_z)),
"right": Box(
(upper_x - ghost_box_width, 0, 0), (upper_x, upper_y, upper_z)
),
"bottom": Box((0, 0, 0), (upper_x, ghost_box_width, upper_z)),
"top": Box((0, upper_y - ghost_box_width, 0), (upper_x, upper_y, upper_z)),
"front": Box((0, 0, 0), (upper_x, upper_y, ghost_box_width)),
"back": Box((0, 0, upper_z - ghost_box_width), (upper_x, upper_y, upper_z)),
}


def touch_domain_border(box, domain_box, border):
Expand All @@ -78,21 +83,29 @@ def touch_domain_border(box, domain_box, border):


def periodicity_shifts(domain_box):
shifts = {}

if domain_box.ndim == 1:
shape_x = domain_box.shape
return {
shifts = {
"left": shape_x,
"right": -shape_x,
}
shifts.update({"leftright": [shifts["left"], shifts["right"]]})

if domain_box.ndim == 2:
shape_x, shape_y = domain_box.shape
if domain_box.ndim == 3:
shape_x, shape_y, shape_z = domain_box.shape

if domain_box.ndim > 1:
shifts = {
"left": [(shape_x, 0)],
"right": [(-shape_x, 0)],
"bottom": [(0, shape_y)],
"top": [(0, -shape_y)],
}

shifts.update(
{
"bottomleft": [*shifts["left"], *shifts["bottom"], (shape_x, shape_y)],
Expand Down Expand Up @@ -133,7 +146,7 @@ def periodicity_shifts(domain_box):
shifts["topleft"][-1],
shifts["topright"][-1],
],
"bottomtopleftright": [ # one patch covers domain
"leftrightbottomtop": [ # one patch covers domain
*shifts["bottomleft"],
*shifts["topright"],
shifts["bottomright"][-1],
Expand All @@ -143,7 +156,35 @@ def periodicity_shifts(domain_box):
)

if domain_box.ndim == 3:
raise ValueError("Unhandeled dimension")
front = {
f"{k}front": [(v[0], v[1], shape_z) for v in l] for k, l in shifts.items()
}
back = {
f"{k}back": [([v[0], v[1], -shape_z]) for v in l] for k, l in shifts.items()
}

shifts = {k: [([v[0], v[1], 0]) for v in l] for k, l in shifts.items()}

shifts.update(front)
shifts.update(back)
shifts.update(
{
"back": [(0, 0, -shape_z)],
"front": [(0, 0, shape_z)],
"leftrightbottomtopfrontback": [
*shifts["bottomleftfront"],
*shifts["bottomrightback"],
*shifts["topleftfront"],
*shifts["toprightback"],
],
}
)

assert len(list(shifts.keys())) == len(
set(["".join(sorted(k)) for k in list(shifts.keys())])
)

shifts = {"".join(sorted(k)): l for k, l in shifts.items()}

return shifts

Expand Down Expand Up @@ -245,7 +286,7 @@ def borders_per(patch):
]

for patch_i, ref_patch in enumerate(border_patches):
in_sides = borders_per_patch[ref_patch]
in_sides = "".join(sorted(borders_per_patch[ref_patch]))
assert in_sides in shifts

for ref_pdname, ref_pd in ref_patch.patch_datas.items():
Expand Down Expand Up @@ -335,36 +376,41 @@ def get_periodic_list(patches, domain_box, n_ghosts):
shift_patch(first_patch, domain_box.shape)
sorted_patches.append(first_patch)

return sorted_patches

dbu = domain_box.upper

if dim == 2:
sides = {
"bottom": Box([0, 0], [domain_box.upper[0], 0]),
"top": Box(
[0, domain_box.upper[1]], [domain_box.upper[0], domain_box.upper[1]]
),
"left": Box([0, 0], [0, domain_box.upper[1]]),
"right": Box(
[domain_box.upper[0], 0], [domain_box.upper[0], domain_box.upper[1]]
),
"left": Box([0, 0], [0, dbu[1]]),
"right": Box([dbu[0], 0], [dbu[0], dbu[1]]),
"bottom": Box([0, 0], [dbu[0], 0]),
"top": Box([0, dbu[1]], [dbu[0], dbu[1]]),
}

shifts = periodicity_shifts(domain_box)
else:
sides = {
"left": Box([0, 0, 0], [0, dbu[1], dbu[2]]),
"right": Box([dbu[0], 0, 0], [dbu[0], dbu[1], dbu[2]]),
"bottom": Box([0, 0, 0], [dbu[0], 0, dbu[2]]),
"top": Box([0, dbu[1], 0], [dbu[0], dbu[1], dbu[2]]),
"front": Box([0, 0, 0], [dbu[0], dbu[1], 0]),
"back": Box([0, 0, dbu[2]], [dbu[0], dbu[1], dbu[2]]),
}

def borders_per(box):
return "".join(
[key for key, side in sides.items() if box * side is not None]
)
shifts = periodicity_shifts(domain_box)

for patch in patches:
in_sides = borders_per(boxm.grow(patch.box, n_ghosts))
def borders_per(box):
return "".join([key for key, side in sides.items() if box * side is not None])

if in_sides in shifts: # in_sides might be empty, so no borders
for shift in shifts[in_sides]:
patch_copy = copy(patch)
shift_patch(patch_copy, shift)
sorted_patches.append(patch_copy)
for patch in patches:
in_sides = "".join(sorted(borders_per(boxm.grow(patch.box, n_ghosts))))

if dim == 3:
raise ValueError("not yet implemented")
if in_sides in shifts: # in_sides might be empty, so no borders
for shift in shifts[in_sides]:
patch_copy = copy(patch)
shift_patch(patch_copy, shift)
sorted_patches.append(patch_copy)

return sorted_patches

Expand Down Expand Up @@ -470,18 +516,7 @@ def level_ghost_boxes(hierarchy, quantities, levelNbrs=[], time=None):
check_patches = patches

for gabox in ghostAreaBoxes:
remaining = gabox - check_patches[0].box

for patch in check_patches[1:]:
tmp = []
remove = []
for i, rem in enumerate(remaining):
if rem * patch.box is not None:
remove.append(i)
tmp += rem - patch.box
for rm in reversed(remove):
del remaining[rm]
remaining += tmp
remaining = gabox - [p.box for p in check_patches]

if ilvl not in lvl_gaboxes:
lvl_gaboxes[ilvl] = {}
Expand Down
54 changes: 47 additions & 7 deletions pyphare/pyphare/pharesee/hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,7 @@ def select(self, box):

overlap = box * gbox
if overlap is not None:
lower = self.layout.AMRToLocal(overlap.lower)
upper = self.layout.AMRToLocal(overlap.upper)

if box.ndim == 1:
return self.dataset[lower[0] : upper[0] + 1]
if box.ndim == 2:
return self.dataset[lower[0] : upper[0] + 1, lower[1] : upper[1] + 1]
return boxm.select(self.dataset, self.layout.AMRBoxToLocal(overlap))
return np.array([])

def __getitem__(self, box):
Expand Down Expand Up @@ -1029,11 +1023,44 @@ def plot2d(self, **kwargs):

return fig, ax

def plot3d(self, **kwargs):
"""!HAX!"""
time = kwargs.get("time", self._default_time())
usr_lvls = kwargs.get("levels", self.levelNbrs(time))
default_qty = None
if len(self.quantities()) == 1:
default_qty = self.quantities()[0]
qty = kwargs.get("qty", default_qty)
for lvl_nbr, lvl in self.levels(time).items():
if lvl_nbr not in usr_lvls:
continue
for patch in self.level(lvl_nbr, time).patches:
pdat = patch.patch_datas[qty]
primals = pdat.primal_directions()
if primals[0]:
pdat._x = pdat.x[:-1]
if primals[1]:
pdat._y = pdat.y[:-1]
pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)]
patch.box.lower = patch.box.lower[:-1]
patch.box.upper = patch.box.upper[:-1]
patch.box.ndim = 2

pdat.ghost_box.lower = pdat.ghost_box.lower[:-1]
pdat.ghost_box.upper = pdat.ghost_box.upper[:-1]
pdat.ghost_box.ndim = 2
pdat.size = np.copy(pdat.ghost_box.shape)
pdat.layout.dl = pdat.layout.dl[:-1]

return self.plot2d(**kwargs) # ¯\_(ツ)_/¯

def plot(self, **kwargs):
if self.ndim == 1:
return self.plot1d(**kwargs)
elif self.ndim == 2:
return self.plot2d(**kwargs)
elif self.ndim == 3:
return self.plot3d(**kwargs)

def dist_plot(self, **kwargs):
"""
Expand Down Expand Up @@ -1695,6 +1722,19 @@ def hierarchy_from_sim(simulator, qty, pop=""):
return PatchHierarchy(patch_levels, domain_box, time=simulator.currentTime())


def hierarchy_from_box(domain_box, ghosts_nbr):
"""
constructs a basic hierarchy with one patch for level 0 as the entire domain
"""
layout = GridLayout(
domain_box, np.asarray([0] * domain_box.ndim), [0.1] * domain_box.ndim, 1
)
pdata = PatchData(layout, "qty")
object.__setattr__(pdata, "ghosts_nbr", np.asarray(ghosts_nbr))
object.__setattr__(pdata, "ghost_box", boxm.grow(layout.box, ghosts_nbr))
return PatchHierarchy({0: PatchLevel(0, [Patch({"qty": pdata})])}, domain_box)


def hierarchy_from(
simulator=None, qty=None, pop="", h5_filename=None, time=None, hier=None
):
Expand Down
2 changes: 1 addition & 1 deletion pyphare/pyphare/pharesee/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def _get_rank(patchdatas, **kwargs):
layout = reference_pd.layout
centering = "dual"
nbrGhosts = layout.nbrGhosts(layout.interp_order, centering)
shape = grow(reference_pd.box, [nbrGhosts] * 2).shape
shape = grow(reference_pd.box, [nbrGhosts] * ndim).shape

if ndim == 1:
pass
Expand Down
Loading

0 comments on commit 914fce6

Please sign in to comment.