Inner boundary - #1241
Conversation
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>
|
Warning Review limit reached
Next review available in: 38 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (72)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
| } | ||
|
|
||
| md.ghostElemsData._data = &ghost_array; | ||
| md.degradedElemsData._data = °raded_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)) |
| 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)) |
| // --- 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) |
| ) | ||
|
|
||
| # per-type extra keys (prescribed reservoir values the user must provide) | ||
| condition_keys = { |
There was a problem hiding this comment.
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
No description provided.