-
Notifications
You must be signed in to change notification settings - Fork 32
overlap Difference hierarchies #1115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -147,10 +147,10 @@ | |
| patch_levels_per_time = [] | ||
| for t in reference_hier.times(): | ||
| patch_levels = {} | ||
| for ilvl in range(reference_hier.levelNbr()): | ||
| patch_levels[ilvl] = PatchLevel( | ||
| ilvl, new_patches_from(compute, hierarchies, ilvl, t, **kwargs) | ||
| ) | ||
| for ilvl in reference_hier.levels(t).keys(): | ||
| patches = new_patches_from(compute, hierarchies, ilvl, t, **kwargs) | ||
| if patches: | ||
| patch_levels[ilvl] = PatchLevel(ilvl, patches) | ||
| patch_levels_per_time.append(patch_levels) | ||
| return PatchHierarchy( | ||
| patch_levels_per_time, | ||
|
|
@@ -182,6 +182,9 @@ | |
|
|
||
| def new_patches_from(compute, hierarchies, ilvl, t, **kwargs): | ||
| reference_hier = hierarchies[0] | ||
| if ilvl not in reference_hier.levels(t): | ||
| return [] | ||
|
|
||
| new_patches = [] | ||
| ref_patches = reference_hier.level(ilvl, time=t).patches | ||
| for ip, current_patch in enumerate(ref_patches): | ||
|
|
@@ -596,7 +599,7 @@ | |
| phut.assert_fp_any_all_close(ref[:], cmp[:], atol=1e-16) | ||
| except AssertionError as e: | ||
| print(e) | ||
| return self.failed[0][0] | ||
| return self.failed[0][0] if self.failed else "==" | ||
|
|
||
| def __call__(self, reason, ref=None, cmp=None): | ||
| self.failed.append((reason, ref, cmp)) | ||
|
|
@@ -612,6 +615,66 @@ | |
| return reversed(self.failed) | ||
|
|
||
|
|
||
| def overlap_diff_hierarchy(hier, time): | ||
| """ | ||
| This function creates a hierarchy whose values are the maximum difference | ||
| there can be for each node existing in multiple patches's ghost boxes | ||
| """ | ||
| import pyphare.core.box as boxm | ||
| from pyphare.pharesee.geometry import hierarchy_overlaps | ||
|
PhilipDeegan marked this conversation as resolved.
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Check noticeCode scanning / CodeQL Cyclic import Note
Import of module
pyphare.pharesee.geometry Error loading related location Loading |
||
|
|
||
| diff_hier = zeros_like(hier, time=time) | ||
|
|
||
| def diff_patch_for(box, ilvl): | ||
| for patch in diff_hier.levels(time)[ilvl]: | ||
| if patch.box == box: | ||
| return patch | ||
| raise RuntimeError("Patch not found") | ||
|
|
||
| found = 0 | ||
| for ilvl, overlaps in hierarchy_overlaps(hier, time).items(): | ||
| for overlap in overlaps: | ||
| pd1, pd2 = overlap["pdatas"] | ||
| ovrlp_box = overlap["box"] | ||
| offsets = overlap["offset"] | ||
| patch0, patch1 = overlap["patches"] | ||
| name = overlap["name"] | ||
|
|
||
| box_pd1 = boxm.amr_to_local( | ||
| ovrlp_box, boxm.shift(pd1.ghost_box, offsets[0]) | ||
| ) | ||
| box_pd2 = boxm.amr_to_local( | ||
| ovrlp_box, boxm.shift(pd2.ghost_box, offsets[1]) | ||
| ) | ||
|
|
||
| slice1 = boxm.select(pd1.dataset, box_pd1) | ||
| slice2 = boxm.select(pd2.dataset, box_pd2) | ||
|
|
||
| diff = np.abs(slice1 - slice2) | ||
|
|
||
| diff_patch0 = diff_patch_for(patch0.box, ilvl) | ||
| diff_patch1 = diff_patch_for(patch1.box, ilvl) | ||
|
|
||
| diff_data0 = diff_patch0.patch_datas[name].dataset | ||
| diff_data1 = diff_patch1.patch_datas[name].dataset | ||
|
|
||
| dif0 = boxm.select(diff_data0, box_pd1) | ||
| dif1 = boxm.select(diff_data1, box_pd2) | ||
|
|
||
| if len(np.nonzero(diff)[0]): | ||
| boxm.DataSelector(diff_data0)[box_pd1] = np.maximum(dif0, diff) | ||
| boxm.DataSelector(diff_data1)[box_pd2] = np.maximum(dif1, diff) | ||
|
|
||
| assert len(np.nonzero(diff_patch0.patch_datas[name].dataset)[0]) | ||
| assert len(np.nonzero(diff_patch1.patch_datas[name].dataset)[0]) | ||
| found = 1 | ||
|
|
||
| if found: | ||
| assert has_non_zero(diff_hier, time=time) | ||
|
|
||
| return diff_hier | ||
|
|
||
|
|
||
| def hierarchy_compare(this, that, atol=1e-16): | ||
| eqr = EqualityReport() | ||
|
|
||
|
|
@@ -699,3 +762,103 @@ | |
| else: | ||
| raise RuntimeError("unexpected state") | ||
| return cier | ||
|
|
||
|
|
||
| def zero_patch_hierarchy_like(hier, **kwargs): | ||
| from copy import deepcopy | ||
|
|
||
| times = phut.listify(kwargs.get("time", hier.times())) | ||
|
|
||
| cpy = deepcopy(hier) | ||
| cpy.time_hier = {} | ||
| for time in times: | ||
| cpy.time_hier[format_timestamp(time)] = deepcopy(hier.levels(time)) | ||
| for lvl in cpy.levels(time).values(): | ||
| for patch in lvl: | ||
| for key, pd in patch.patch_datas.items(): | ||
| patch.patch_datas[key] = zeros_like(pd) | ||
| assert not has_non_zero(cpy, time=time) | ||
| return cpy | ||
|
|
||
|
|
||
| def zero_field_data_like(field_data): | ||
| from copy import deepcopy | ||
|
|
||
| cpy = deepcopy(field_data) | ||
| assert id(cpy.dataset) == id(field_data.dataset) | ||
| cpy.dataset = np.zeros(field_data.dataset.shape) | ||
| assert id(cpy.dataset) != id(field_data.dataset) | ||
| return cpy | ||
|
|
||
|
|
||
| def zeros_like(that, **kwargs): | ||
| if issubclass(type(that), PatchHierarchy): | ||
| return zero_patch_hierarchy_like(that, **kwargs) | ||
| if issubclass(type(that), FieldData): | ||
| return zero_field_data_like(that, **kwargs) | ||
| raise RuntimeError( | ||
| "Cannot resolve type to zeros_like, consider updating if required" | ||
| ) | ||
|
|
||
|
|
||
| def field_data_has_non_zero(field_data): | ||
| return bool(len(np.nonzero(field_data.dataset[:])[0])) | ||
|
|
||
|
|
||
| def patch_hierarchy_has_non_zero(hier, time): | ||
| for ilvl, lvl in hier.levels(time).items(): | ||
| for patch in lvl: | ||
| for pd in patch.patch_datas.values(): | ||
| if has_non_zero(pd): | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def has_non_zero(that, time=None): | ||
| if issubclass(type(that), PatchHierarchy): | ||
| return patch_hierarchy_has_non_zero(that, time) | ||
| if issubclass(type(that), FieldData): | ||
| return field_data_has_non_zero(that) | ||
| raise RuntimeError( | ||
| "Cannot resolve type to has_non_zero, consider updating if required" | ||
| ) | ||
|
|
||
|
|
||
| def max_from_field_data(field_data): | ||
| return np.max(field_data.dataset[:]) | ||
|
|
||
|
|
||
| def max_from_patch_hierarchy(hier, time, qty): | ||
| vals = {} | ||
| for ilvl, lvl in hier.levels(time).items(): | ||
| for patch in lvl: | ||
| for key, pd in patch.patch_datas.items(): | ||
| if qty is None or key == qty: | ||
| if ilvl in vals: | ||
| vals[ilvl] = max(max_from(pd), vals[ilvl]) | ||
| else: | ||
| vals[ilvl] = max_from(pd) | ||
|
|
||
| return vals | ||
|
|
||
|
|
||
| def max_from(that, time=None, qty=None): | ||
| if issubclass(type(that), PatchHierarchy): | ||
| return max_from_patch_hierarchy(that, time, qty) | ||
| if issubclass(type(that), FieldData): | ||
| return max_from_field_data(that) | ||
| raise RuntimeError("Cannot resolve type to max_from, consider updating if required") | ||
|
|
||
|
|
||
| def min_max_patch_shape(hier, time, qty=None): | ||
| time_hier = hier.levels(time) | ||
| val = {ilvl: [10000, 0] for ilvl in time_hier.keys()} | ||
|
|
||
| for ilvl, lvl in time_hier.items(): | ||
| for patch in lvl: | ||
| for key, pd in patch.patch_datas.items(): | ||
| if qty is None or key == qty: | ||
| val[ilvl][0] = min(np.min(pd.dataset.shape), val[ilvl][0]) | ||
| val[ilvl][1] = max(np.max(pd.dataset.shape), val[ilvl][1]) | ||
|
Comment on lines
+853
to
+862
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reports data-array shapes, not patch shapes. Lines 861-862 use 🧭 Suggested fix for ilvl, lvl in time_hier.items():
for patch in lvl:
- for key, pd in patch.patch_datas.items():
- if qty is None or key == qty:
- val[ilvl][0] = min(np.min(pd.dataset.shape), val[ilvl][0])
- val[ilvl][1] = max(np.max(pd.dataset.shape), val[ilvl][1])
+ if qty is None or qty in patch.patch_datas:
+ patch_shape = patch.box.shape
+ val[ilvl][0] = min(np.min(patch_shape), val[ilvl][0])
+ val[ilvl][1] = max(np.max(patch_shape), val[ilvl][1])🤖 Prompt for AI Agents |
||
|
|
||
| return val | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
|
|
||
| #include "core/def.hpp" | ||
|
|
||
| #include <stdexcept> | ||
| #include <string> | ||
| #include <sstream> | ||
| #include <iostream> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,6 @@ | |
|
|
||
|
|
||
|
|
||
|
|
||
| namespace PHARE::core | ||
| { | ||
| template<std::size_t dim> | ||
|
|
||
Check notice
Code scanning / CodeQL
Cyclic import Note