Skip to content

Inner boundary - #1241

Draft
igirault wants to merge 6 commits into
PHAREHUB:masterfrom
igirault:inner-boundary
Draft

Inner boundary#1241
igirault wants to merge 6 commits into
PHAREHUB:masterfrom
igirault:inner-boundary

Conversation

@igirault

@igirault igirault commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

No description provided.

igirault and others added 6 commits July 6, 2026 21:38
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…field BCs, manager)

Ported from the embedded-boundary branch, adapted to master's total-B
formulation (no B0/B1 splitting): the safe state and all boundary
conditions read/write B and Etot directly.

- inner-boundary geometry (sphere, plane) with signed distance and
  characteristicLength(); mesh classifier producing per-centering cell
  status + ghost-element lists (mirror point, normal, interpolability),
  including the 1-cell degraded shell on under-resolved levels
- field inner BCs: none, Dirichlet (constant fills every ghost,
  including non-interpolable ones), Neumann, symmetric, antisymmetric,
  adaptive Dirichlet-or-Neumann, total-energy-from-pressure,
  ionospheric-convection momentum (Tanaka)
- InnerBoundaryManager with config-driven inactive-cell safe state
- Thermo/ideal-gas EOS helpers, FieldAtPoint interpolator, generic
  face/edge/node/cell-centered quantities on Hybrid and MHD layouts
- distance-aware ghost fill deliberately NOT ported (known-incorrect);
  ghosts with a non-interpolable mirror are skipped, which magnetospheric
  cases circumvent with a 0th-order Dirichlet condition

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- MHDModel owns an optional InnerBoundaryManager (created from the
  simulation dict, null when no inner_boundary is configured) plus the
  Thermo EOS it needs; setupInnerBoundaryState() classifies the mesh,
  pins inactive cells to the safe state and applies the moment BCs
- ghost-element lists are per-patch SAMRAI PatchData (variable/factory/
  data) wired through the resources manager
- level initializer establishes the inner-boundary state at init/regrid;
  the simulator re-establishes it on restart for restored levels
- per-substep: finite-volume Euler only evolves Fluid/Cut cells, the
  safe state is re-pinned, and the moment inner BCs are re-applied;
  E gets its inner BC and is zeroed in inactive cells after CT
- under-resolved levels: Godunov recomputes listed faces with
  first-order ideal fluxes and CT recomputes listed edges with a
  first-order ideal Ohm's law (no-op on resolved levels)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simulation(inner_boundary={...}) accepts a sphere (center/radius) or
plane (point/normal) with an optional condition_type ('reflective' or
'ionospheric-convection', the latter requiring prescribed density and
pressure) and an optional inactive_safe_state dict (density, pressure,
velocity, B — total field) pinned into in-body cells. populateDict
forwards the validated dict under simulation/inner_boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Uniform flow past a spherical inner boundary in a fully periodic domain,
exercising the full stack (classification, safe-state pinning, moment
ghost BCs, degraded fluxes) without outer physical boundary conditions.
Verified locally: 50 steps, rho/P finite and positive on the dumped
hierarchy, in-body cells hold the configured safe-state density.

Registered at exec level 101 behind HighFive, like the other heavy MHD
functional cases (excluded from default PHARE_EXEC_LEVEL_MAX=10 runs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@igirault, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 581d3eb3-6ede-4286-96f2-0e0179baa7d5

📥 Commits

Reviewing files that changed from the base of the PR and between 07d6e6d and 68e7181.

📒 Files selected for processing (72)
  • docs/superpowers/plans/2026-07-06-inner-boundary-extraction.md
  • docs/superpowers/specs/2026-07-06-inner-boundary-extraction-design.md
  • pyphare/pyphare/pharein/initialize/general.py
  • pyphare/pyphare/pharein/simulation.py
  • pyphare/pyphare_tests/pharein/simulation_test.py
  • res/cmake/test.cmake
  • src/amr/data/inner_boundary/ghost_elem_data.hpp
  • src/amr/data/inner_boundary/ghost_elem_data_factory.hpp
  • src/amr/data/inner_boundary/ghost_elem_variable.hpp
  • src/amr/level_initializer/mhd_level_initializer.hpp
  • src/amr/physical_models/mhd_model.hpp
  • src/amr/resources_manager/ghost_elem_resource.hpp
  • src/amr/resources_manager/resources_manager.hpp
  • src/amr/resources_manager/resources_manager_utilities.hpp
  • src/amr/solvers/solver_mhd_field_evolvers.hpp
  • src/amr/solvers/time_integrator/compute_fluxes.hpp
  • src/amr/solvers/time_integrator/euler_using_computed_flux.hpp
  • src/core/CMakeLists.txt
  • src/core/data/field/field_traits.hpp
  • src/core/data/grid/gridlayout_traits.hpp
  • src/core/data/grid/gridlayoutdefs.hpp
  • src/core/data/grid/gridlayoutimplyee.hpp
  • src/core/data/grid/gridlayoutimplyee_mhd.hpp
  • src/core/data/tensorfield/tensorfield_traits.hpp
  • src/core/hybrid/hybrid_quantities.hpp
  • src/core/inner_boundary/field_adaptive_dirichlet_or_neumann_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_antisymmetric_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_dirichlet_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_ionospheric_convection_momentum_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_neumann_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_none_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_symmetric_inner_boundary_condition.hpp
  • src/core/inner_boundary/field_total_energy_from_pressure_inner_boundary_condition.hpp
  • src/core/inner_boundary/ghost_elem_pack.hpp
  • src/core/inner_boundary/inner_bc_context.hpp
  • src/core/inner_boundary/inner_boundary_condition.hpp
  • src/core/inner_boundary/inner_boundary_condition_factory.hpp
  • src/core/inner_boundary/inner_boundary_defs.hpp
  • src/core/inner_boundary/inner_boundary_factory.hpp
  • src/core/inner_boundary/inner_boundary_geometry.hpp
  • src/core/inner_boundary/inner_boundary_manager.hpp
  • src/core/inner_boundary/inner_boundary_mesh_classifier.hpp
  • src/core/inner_boundary/inner_boundary_mesh_data.hpp
  • src/core/inner_boundary/plane_inner_boundary.hpp
  • src/core/inner_boundary/sphere_inner_boundary.hpp
  • src/core/mhd/mhd_quantities.hpp
  • src/core/numerics/constrained_transport/upwind_constrained_transport.hpp
  • src/core/numerics/finite_volume_euler/finite_volume_euler.hpp
  • src/core/numerics/finite_volume_euler/finite_volume_euler_per_field.hpp
  • src/core/numerics/godunov_fluxes/godunov_fluxes.hpp
  • src/core/numerics/interpolator/field_at_point.hpp
  • src/core/numerics/primite_conservative_converter/conversion_utils.hpp
  • src/core/numerics/thermo/ideal_gas_thermo.hpp
  • src/core/numerics/thermo/thermo.hpp
  • src/core/numerics/thermo/thermo_defs.hpp
  • src/core/numerics/thermo/thermo_factory.hpp
  • src/core/utilities/point/point.hpp
  • src/simulator/simulator.hpp
  • tests/core/utilities/inner_boundary/CMakeLists.txt
  • tests/core/utilities/inner_boundary/test_field_adaptive_dirichlet_or_neumann_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_antisymmetric_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_dirichlet_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_ionospheric_convection_momentum_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_neumann_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_symmetric_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_field_total_energy_from_pressure_inner_boundary_condition.cpp
  • tests/core/utilities/inner_boundary/test_inner_boundary.cpp
  • tests/core/utilities/inner_boundary/test_inner_boundary_manager.cpp
  • tests/core/utilities/inner_boundary/test_inner_boundary_mesh_classifier.cpp
  • tests/functional/mhd_inner_boundary/CMakeLists.txt
  • tests/functional/mhd_inner_boundary/sphere_periodic.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

}

md.ghostElemsData._data = &ghost_array;
md.degradedElemsData._data = &degraded_array;
md.elemStatus[i].setBuffer(&tmp);
}

md.ghostElemsData._data = &ghost_array;
std::size_t n = 0;
for (auto i = 0u; i < shaped.shape()[0]; ++i)
for (auto j = 0u; j < shaped.shape()[1]; ++j)
if (cellStatus(i, j) == PHARE::core::toDouble(PHARE::core::ElemStatus::Inactive))
Comment on lines +36 to +44
switch (model)
{
case ThermoModel::ideal_gas:
{
double const gamma
= dict["to_conservative_init"]["heat_capacity_ratio"].template to<double>();
return std::make_shared<IdealGasThermo>(gamma);
}
}
layout.evalOnGhostBox(cell_status, [&](auto... idx) {
auto const cell = local_index_type{static_cast<std::uint32_t>(idx)...};
auto const s = cell_status(cell);
if (s == toDouble(ElemStatus::Cut) || s == toDouble(ElemStatus::Ghost))
layout.evalOnGhostBox(P, [&](auto&... args) {
auto const idx = core::MeshIndex<dimension>{args...};
auto const st = cellStatus(idx);
if (st != toDouble(ElemStatus::Fluid) && st != toDouble(ElemStatus::Cut))
Comment on lines +77 to +94
// --- 8. Projection Helpers (Static Methods) ---
// { GridLayoutT::momentsToEx() };
// { GridLayoutT::momentsToEy() };
// { GridLayoutT::momentsToEz() };
// { GridLayoutT::ExToMoments() };
// { GridLayoutT::EyToMoments() };
// { GridLayoutT::EzToMoments() };
// { GridLayoutT::JxToMoments() };
// { GridLayoutT::JyToMoments() };
// { GridLayoutT::JzToMoments() };
// { GridLayoutT::BxToEx() };
// { GridLayoutT::ByToEx() };
// { GridLayoutT::BzToEx() };
// { GridLayoutT::JxToEx() };
// { GridLayoutT::JyToEy() };
// { GridLayoutT::JzToEz() };
// { GridLayoutT::faceXToCellCenter() };
// { GridLayoutT::edgeXToCellCenter() };
auto& status = meshData.getStatusFieldFromCentering(centering);
layout.evalOnBox(state.E(component), [&](auto&... args) {
auto idx = core::MeshIndex<gridlayout_type::dimension>{args...};
if (status(idx) == core::toDouble(core::ElemStatus::Inactive))
core_type{layout}(state, statenew, fluxes, dt, [&cellStatus](auto const& idx) {
auto const s = cellStatus(idx);
return s != core::toDouble(core::ElemStatus::Ghost)
&& s != core::toDouble(core::ElemStatus::Inactive);
auto const& cellStatus = ibm.getMeshData().cellStatusField();
core_type{layout}(state, statenew, fluxes, dt, [&cellStatus](auto const& idx) {
auto const s = cellStatus(idx);
return s != core::toDouble(core::ElemStatus::Ghost)
@igirault
igirault marked this pull request as draft July 11, 2026 09:32
)

# per-type extra keys (prescribed reservoir values the user must provide)
condition_keys = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe something like we do for LoadBalancers could work here

https://github.com/PHAREHUB/PHARE/blob/master/pyphare/pyphare/pharein/load_balancer.py#L9

makes things more obvious about what variables exist or are required

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.

3 participants