Skip to content

max battle#1146

Merged
nicolasaunai merged 2 commits intoPHAREHUB:masterfrom
PhilipDeegan:maxbattle
Feb 10, 2026
Merged

max battle#1146
nicolasaunai merged 2 commits intoPHAREHUB:masterfrom
PhilipDeegan:maxbattle

Conversation

@PhilipDeegan
Copy link
Member

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

Refactors field-border operations to generic operation templates, adds ion-border filling across the messenger/refiner/solver stack with new max-border refiners, adjusts related transaction/functor APIs (SetMax/PlusEquals), and makes minor simulator, MPI utility, and test baseline tweaks.

Changes

Cohort / File(s) Summary
Field data & ops generalization
src/amr/data/field/field_data.hpp, src/amr/data/tensorfield/tensor_field_data.hpp, src/core/utilities/types.hpp
Replaced concrete sum/plus-equals APIs with templated operation APIs (operate, unpackStreamAnd<Operation>). Added SetMax functor; improved const-correctness and generalized internal copy/unpack logic.
Border transaction & refiner changes
src/amr/messengers/field_operate_transaction.hpp, src/amr/messengers/refiner.hpp, src/diagnostic/diagnostic_model_view.hpp
Renamed FieldBorderSumTransaction → FieldBorderOpTransaction and added Operation template; updated factories to use generic ops (PlusEquals/SetMax). Added new RefinerType values for max-border operations and switched diagnostic scheduling to use PlusEqualsOp.
Hybrid messenger / ion-border feature
src/amr/messengers/hybrid_hybrid_messenger_strategy.hpp, src/amr/messengers/hybrid_messenger.hpp, src/amr/messengers/hybrid_messenger_strategy.hpp, src/amr/messengers/mhd_hybrid_messenger_strategy.hpp, src/amr/messengers/hybrid_messenger_info.hpp
Introduced fillIonBorders hook in messenger strategy and HybridMessenger; added maxBorderFields/maxBorderVecFields in HybridMessengerInfo; created max-refiner pools (ionDensityBorderMaxRefiners_, ionFluxBorderMaxRefiners_).
Model/solver/initializer integration
src/amr/physical_models/hybrid_model.hpp, src/amr/solvers/solver_ppc.hpp, src/amr/level_initializer/hybrid_level_initializer.hpp
Registered ion max-border fields in fillMessengerInfo and invoked fillIonBorders from SolverPPC moveIons_ flow. Level initializer switched to rm.enumerate(...)/rm.setTime(...) and calls hybMessenger.fillIonBorders(...).
Python simulator & utilities
pyphare/pyphare/simulator/simulator.py, pyphare/pyphare/pharein/simulation.py, src/core/utilities/mpi_utils.hpp
Changed Simulator default print_one_line to False; altered smallest patch-size derivation to be interpolation-order–based; fixed collectVector to emplace default vectors for zero-sized MPI chunks.
Tests
tests/simulator/__init__.py
Adjusted second refinement box lower bound from 8 → 12 in test helper initialization.

Sequence Diagram(s)

sequenceDiagram
    participant Solver as SolverPPC
    participant Messenger as HybridMessenger
    participant Strategy as HybridHybridMessengerStrategy
    participant Refiner as RefinerPool
    participant Field as FieldData/TensorFieldData
    participant Transaction as FieldBorderOpTransaction

    Solver->>Messenger: request fillIonBorders(ions, level, time)
    Messenger->>Strategy: strat_->fillIonBorders(ions, level, time)
    Strategy->>Refiner: select ionDensity/ionFlux max-refiner pool
    Refiner->>Field: invoke operate<SetMaxOp>/operate<PlusEqualsOp> on patch data
    Field->>Transaction: pack/unpack using templated Operation
    Transaction->>Field: apply Operation during unpackStreamAnd<Operation>
    Transaction-->>Strategy: border data applied
    Strategy-->>Messenger: ion borders filled
    Messenger-->>Solver: return control
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • fix master improved #1083: touches AMR messenger/field operation codepaths and Operation-based transactions—closely related to the FieldBorderOpTransaction and functor changes.
  • Patchghostless #1019: refactors field-data operation APIs and border transaction factories—directly connected to the templated operate/unpackStreamAnd changes.
  • Refine patch strategy #1006: modifies hybrid messenger/refiner logic and magnetic-border refiners—related to HybridHybridMessengerStrategy changes and max-border refiners.

Suggested labels

refactoring

Suggested reviewers

  • UCaromel
  • nicolasaunai
🚥 Pre-merge checks | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, making it impossible to assess whether the description is related to the changeset. Add a pull request description that explains the objectives, changes, and rationale for the modifications across the multiple files and systems involved.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'max battle' is vague and does not convey meaningful information about the changeset, which involves adding max-border refiners, generalizing border operations, and related infrastructure changes. Use a more descriptive title that summarizes the main change, such as 'Add max-border refiners and generalize field border operations' or 'Introduce SetMax operation for field border refinement'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Updated smallest_patch_size calculation to use interpolation order.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pyphare/pyphare/pharein/simulation.py`:
- Around line 409-413: The first assignment to smallest_patch_size (using
phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1) is dead because it is
overwritten unconditionally by the SAMRAI workaround assignment using
min_per_interp; remove or comment out the first assignment to avoid confusion,
or wrap it behind a clear conditional/feature flag (eg. use a constant like
USE_SAMRAI_WORKAROUND) so that smallest_patch_size is assigned from
phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1 when the SAMRAI bug is
resolved; references to smallest_patch_size, phare_utilities.np_array_ify,
max_ghosts, min_per_interp, interp and ndim should remain to locate the change.
🧹 Nitpick comments (3)
src/core/utilities/types.hpp (1)

563-568: std::max requires identical types — consider explicit cast or std::max<D>.

Unlike operator+= (in PlusEquals) which allows implicit conversions, std::max(d, d0) requires both arguments to have the exact same type for template deduction. If d0 ever has a slightly different type than D, this will fail to compile. Using std::max<D>(d, d0) would be safer and consistent with the implicit conversion behavior of the sibling functors.

Suggested fix
 template<typename D>
 struct SetMax
 {
-    void operator()(auto& d0) { d = std::max(d, d0); }
+    void operator()(auto& d0) { d = std::max<D>(d, d0); }
     D& d;
 };
src/amr/messengers/refiner.hpp (1)

122-123: Duplicate comments for two distinct branches.

Lines 122–123 and 135–136 have identical comments. The second block handles PatchVecFieldBorderMax (vector fields), so it would be clearer to differentiate, e.g. "schedule used to set max of vec field density and flux…".

Also, the phrasing "== max" is a bit ambiguous — consider "set to max" for clarity.

Also applies to: 135-136

src/amr/messengers/hybrid_hybrid_messenger_strategy.hpp (1)

876-891: Hard-coded size assertions on maxBorderFields and maxBorderVecFields may be brittle.

Lines 878 and 885 assert exact sizes (== 2 and == 1). If a future change adds additional max-border quantities, these assertions will fire at runtime with no compile-time indication. Consider adding a comment explaining why exactly 2 fields and 1 vec field are expected, so maintainers know the contract.

The in-place registration pattern (field, field, nullptr, field) is correct for max operations since max(a, b) is idempotent — unlike +=, repeated overlaps don't corrupt the result.

Comment on lines +409 to +413
# to prevent primal ghost box overlaps of non adjacent patches, we need smallest_patch_size * 2 + 1
smallest_patch_size = phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1
# TORM next lines after https://github.com/llnl/SAMRAI/issues/311
min_per_interp = [6, 9, 9] # SAMRAI BORDER BUG
smallest_patch_size = phare_utilities.np_array_ify(min_per_interp[interp - 1], ndim)
Copy link

@coderabbitai coderabbitai bot Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Dead assignment on Line 410 — value is immediately overwritten on Line 413.

The smallest_patch_size computed on Line 410 is never used because it's unconditionally reassigned on Line 413. This was also flagged by CodeQL. If the Line 410 computation is kept as documentation of the "correct" formula (for when the SAMRAI bug is fixed), consider commenting it out to make the intent clearer and avoid confusion.

Suggested cleanup
-    # to prevent primal ghost box overlaps of non adjacent patches, we need smallest_patch_size * 2 + 1
-    smallest_patch_size = phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1
+    # to prevent primal ghost box overlaps of non adjacent patches, we'd need smallest_patch_size * 2 + 1
+    # smallest_patch_size = phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1
     # TORM next lines after https://github.com/llnl/SAMRAI/issues/311
     min_per_interp = [6, 9, 9]  # SAMRAI BORDER BUG
     smallest_patch_size = phare_utilities.np_array_ify(min_per_interp[interp - 1], ndim)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# to prevent primal ghost box overlaps of non adjacent patches, we need smallest_patch_size * 2 + 1
smallest_patch_size = phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1
# TORM next lines after https://github.com/llnl/SAMRAI/issues/311
min_per_interp = [6, 9, 9] # SAMRAI BORDER BUG
smallest_patch_size = phare_utilities.np_array_ify(min_per_interp[interp - 1], ndim)
# to prevent primal ghost box overlaps of non adjacent patches, we'd need smallest_patch_size * 2 + 1
# smallest_patch_size = phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1
# TORM next lines after https://github.com/llnl/SAMRAI/issues/311
min_per_interp = [6, 9, 9] # SAMRAI BORDER BUG
smallest_patch_size = phare_utilities.np_array_ify(min_per_interp[interp - 1], ndim)
🧰 Tools
🪛 GitHub Check: CodeQL

[warning] 409-409: Variable defined multiple times
This assignment to 'smallest_patch_size' is unnecessary as it is redefined before this value is used.

🤖 Prompt for AI Agents
In `@pyphare/pyphare/pharein/simulation.py` around lines 409 - 413, The first
assignment to smallest_patch_size (using
phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1) is dead because it is
overwritten unconditionally by the SAMRAI workaround assignment using
min_per_interp; remove or comment out the first assignment to avoid confusion,
or wrap it behind a clear conditional/feature flag (eg. use a constant like
USE_SAMRAI_WORKAROUND) so that smallest_patch_size is assigned from
phare_utilities.np_array_ify(max_ghosts, ndim) * 2 + 1 when the SAMRAI bug is
resolved; references to smallest_patch_size, phare_utilities.np_array_ify,
max_ghosts, min_per_interp, interp and ndim should remain to locate the change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in future it will only require removing code, this is clear.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PhilipDeegan, understood! The current structure makes the future fix straightforward—just remove the SAMRAI workaround lines and the correct computation will take effect. Thanks for clarifying.


✏️ Learnings added
Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 1146
File: pyphare/pyphare/pharein/simulation.py:409-413
Timestamp: 2026-02-09T17:54:56.848Z
Learning: In Python file pyphare/pyphare/pharein/simulation.py, PhilipDeegan prefers to keep the correct/intended implementation uncommented above temporary workarounds (even if it results in dead code), as this makes future fixes clearer—simply removing the workaround section activates the correct code.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 784
File: tests/simulator/test_restarts.py:333-339
Timestamp: 2024-10-09T08:32:15.667Z
Learning: PhilipDeegan has indicated a preference for minimal and efficient code, even after making changes to get a function working. There may be opportunities to remove or optimize parts of the code such as sleep/wait/advances.

Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 784
File: tests/simulator/test_restarts.py:333-339
Timestamp: 2024-07-26T22:04:34.160Z
Learning: PhilipDeegan has indicated a preference for minimal and efficient code, even after making changes to get a function working. There may be opportunities to remove or optimize parts of the code such as sleep/wait/advances.

Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 1068
File: src/amr/data/field/coarsening/electric_field_coarsener.hpp:1-2
Timestamp: 2025-09-17T13:35:11.533Z
Learning: PhilipDeegan prefers header guard names that include the full directory path structure, following the pattern PHARE_[PATH_WITH_UNDERSCORES]_HPP. For example, a file at src/amr/data/field/coarsening/electric_field_coarsener.hpp should use PHARE_AMR_DATA_FIELD_COARSENING_ELECTRIC_FIELD_COARSENER_HPP as the header guard.

Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 888
File: src/hdf5/detail/h5/h5_file.hpp:78-79
Timestamp: 2024-10-09T08:32:15.667Z
Learning: Avoid commenting on draft PRs for the user PhilipDeegan.

Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 888
File: src/hdf5/detail/h5/h5_file.hpp:78-79
Timestamp: 2024-09-05T17:02:58.784Z
Learning: Avoid commenting on draft PRs for the user PhilipDeegan.

Learnt from: PhilipDeegan
Repo: PHAREHUB/PHARE PR: 888
File: pyphare/pyphare/pharesee/hierarchy/hierarchy_utils.py:566-568
Timestamp: 2024-09-09T13:57:02.285Z
Learning: Avoid commenting on draft PRs for PhilipDeegan unless explicitly requested.

@nicolasaunai nicolasaunai merged commit 1f7a12b into PHAREHUB:master Feb 10, 2026
10 checks passed
@PhilipDeegan PhilipDeegan deleted the maxbattle branch February 10, 2026 15:24
rochSmets pushed a commit to rochSmets/PHARE that referenced this pull request Feb 11, 2026
max battle : overlapped patch values are assigned to their max to avoid spurious floating point errors mismatches. Also updated smallest_patch_size calculation to use interpolation order.
@coderabbitai coderabbitai bot mentioned this pull request Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants