Skip to content

Topic linearsolvers#585

Draft
ax3l wants to merge 9 commits into
AMReX-Codes:developmentfrom
ax3l:topic-linearsolvers
Draft

Topic linearsolvers#585
ax3l wants to merge 9 commits into
AMReX-Codes:developmentfrom
ax3l:topic-linearsolvers

Conversation

@ax3l

@ax3l ax3l commented Jun 5, 2026

Copy link
Copy Markdown
Member

ax3l and others added 9 commits June 5, 2026 12:14
Reintroduce `AMRCore` with trampolines for virtual members.
Also add `AMRMesh` and GDB classes.
Add the Boundary module with bindings for:
- BCType and PhysBCType enums (AMReX_BC_TYPES.H)
- BCRec and Vector<BCRec>, incl. the setBC helper functions
- fill_domain_boundary (AMReX_BCUtil.H)
- PhysBCFunctNoOp, CpuBndryFuncFab,
  PhysBCFunct<CpuBndryFuncFab> ("PhysBCFunct_CpuBndryFuncFab")
- PhysBCFunctUser: a physical boundary condition functor calling
  back into Python at the MultiFab level, e.g., for external
  Dirichlet (BCType.ext_dir) fills

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pybind11 renders parameter/return type names in docstrings at binding
definition time. ParticleContainer (ParGDBBase args), AmrParGDB
(AmrCore ctor arg) and AmrCore.get_par_gdb (AmrParGDB return) were
defined before the respective types were registered, leaving raw C++
type names in docstrings and failing pybind11-stubgen.

Declare the AmrCore class before ParGDB and the particle containers,
and add its member functions after ParGDB is registered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add bindings for inter-level and inter-centering averaging operations
(AMReX_MultiFabUtil.H):
- average_down (cell-centered w/ volume weighting; centering-agnostic
  without), average_down_faces, average_down_edges, average_down_nodal
- average_node_to_cellcenter, average_edge_to_cellcenter,
  average_face_to_cellcenter, average_cellcenter_to_face
- sum_fine_to_coarse

Per-direction MultiFab lists and destination component counts are
validated: AMReX release builds otherwise corrupt memory on, e.g., a
cell-centered destination with too few components.

Add multi-level IO bindings:
- write_multi_level_plotfile, plotfile path helpers (level_path,
  multifab_header_path, level_full_path, multifab_file_full_prefix),
  pre_build_director_hierarchy
- util_create_directory, util_create_clean_directory,
  util_create_directory_destructive, file_exists

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Complete the AmrCore module so that full AMR applications can be
written in Python, following the C++ AmrCore pattern (e.g., the
Advection_AmrCore tutorial):

- TagBoxArray & TagVal: cell tagging for refinement, with zero-copy
  Array4 (of char) views for error_est overrides
- Array4<char> instantiations (Array4_char, Array4_char_const)
- Interpolater & MFInterpolater class hierarchy and the global
  interpolater singleton instances (cell_cons_interp, ...)
- fill_patch_single_level, fill_patch_two_levels,
  interp_from_coarse_level: MultiFab instantiations, overloaded for
  the PhysBCFunctNoOp / PhysBCFunct_CpuBndryFuncFab / PhysBCFunctUser
  boundary functors and dispatching on Interpolater vs MFInterpolater
- FluxRegister: conservative flux corrections (refluxing) at
  coarse-fine interfaces
- AmrMesh: per-level box_array, dist_map, set_box_array, set_dist_map,
  clear_box_array, clear_dist_map, blocking_factor, max_grid_size,
  n_error_buf, max_ref_ratio, count_cells, level_defined
- AmrCore.error_est trampoline: pass the (non-copyable) TagBoxArray by
  reference so that tags set in Python propagate back to AMReX
- BoxArray: == and != operators

The new test_amrcore_fillpatch.py runs a full two-level AmrCore
lifecycle in Python: init from scratch, threshold tagging, new level
from coarse (verifying conservation of cell_cons_interp against
average_down), level remake, and level removal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gaps found while translating the Advection_AmrCore tutorial to Python:

- ParmParse: complete the scalar get/query family (get_string,
  query_bool, query_real, query_string) and add typed array accessors
  (get_<T>_arr, query_<T>_arr, countval)
- ParmParse.to_dict: fix a crash on prefixed instances (the table
  names are fully qualified; lookups now use an unprefixed instance)
- ParallelDescriptor: Barrier and Reduce{Real,Int,Long}{Min,Max,Sum},
  ReduceBool{And,Or}; reduced values are returned (e.g., needed for
  the C++ ComputeDt pattern of reducing per-level dt estimates)
- AmrMesh.set_finest_level: needed when restarting from checkpoints
- average_down_faces: add the periodicity-aware per-direction-list
  overload (used by the no-subcycling advance to average down fluxes)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the LinearSolvers module with bindings of the MultiFab
instantiations of the multi-level multigrid solver stack:

- enums: LinOpBCType, BottomSolver, Location; LPInfo
- the operator class hierarchy MLLinOp -> MLCellLinOp ->
  MLCellABecLap -> {MLPoisson, MLABecLaplacian} and
  MLLinOp -> MLNodeLinOp -> MLNodeLaplacian, with the operator
  surface used by the AMReX tutorials: set_domain_bc, set_level_bc,
  set_coarse_fine_bc (keep_alive: AMReX stores the raw pointer),
  set_max_order, set_scalars, set_a_coeffs, set_b_coeffs, set_sigma
- MLMG: solve, get_grad_solution, get_fluxes (face and cell-centered),
  comp_residual, and the iteration/bottom-solver controls

Tests solve the Poisson (single-level and two-level composite),
ABecLaplacian (MultiFab and constant coefficients) and nodal Poisson
problems against analytic solutions with second-order accuracy
checks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

def test_singletons_identical():
"""Repeated access returns the same global instance"""
assert amr.cell_cons_interp is amr.cell_cons_interp

def test_physbcfunct_noop(std_box):
"""PhysBCFunctNoOp leaves ghost cells untouched"""
geom = make_geometry(std_box) # noqa: F841

def test_physbcfunct_user(std_box):
"""PhysBCFunctUser calls back into Python with reference semantics"""
geom = make_geometry(std_box) # noqa: F841
@ax3l ax3l marked this pull request as draft June 6, 2026 02:02
#include <sstream>


void init_FluxRegister(py::module& m)
Comment thread src/Base/MultiFabUtil.cpp
}


void init_MultiFabUtil (py::module& m)
Comment thread src/Boundary/BCRec.cpp
#include <vector>


void init_BCRec(py::module& m)
Comment thread src/Boundary/BCRec.cpp
s << "<amrex.BCRec (";
for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
s << bcr.lo(dir);
s << (dir < AMREX_SPACEDIM-1 ? "," : ") (");
Comment thread src/Boundary/BCRec.cpp
}
for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
s << bcr.hi(dir);
s << (dir < AMREX_SPACEDIM-1 ? "," : ")>");
* instantiation.
*/
template< typename F >
void dispatch_mapper (InterpBase* mapper, F&& f)
}

template< typename BC >
void register_fill_patch (py::module& m)

/** per-level lists of per-direction (face) MultiFabs */
Vector<Array<MultiFab*, AMREX_SPACEDIM>>
to_face_vector (std::vector<std::vector<MultiFab*>> const & in)
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