Skip to content

PATCH ​

PATCH — Poisson solver with Adaptive mesh refinement for HPC computing — is a distributed-memory elliptic solver built on the ADAM framework. It solves the Poisson equation for a scalar potential field using iterative smoothing methods on AMR grids.

Governing Equation ​

PATCH solves the Poisson boundary-value problem:

∇2φ=f

where φ is the scalar potential (output field) and f is a prescribed source distribution. Convergence is measured by the point-wise residual:

ri,j,k=fi,j,k−∇2φi,j,k

The solver iterates until maxi,j,k|ri,j,k|<ε or a maximum iteration count is reached.

Source Layout ​

src/app/patch/
├── common/                              # Shared across all backends
│   ├── adam_patch_common_object.F90     # patch_common_object base type
│   ├── adam_patch_bc_object.F90         # Boundary conditions handler
│   ├── adam_patch_ic_object.F90         # Initial conditions handler
│   ├── adam_patch_io_object.F90         # I/O handler
│   ├── adam_patch_time_object.F90       # Time / convergence handler
│   └── adam_patch_common_library.F90    # Barrel re-export of all common modules
└── cpu/                                 # CPU backend
    ├── adam_patch_cpu.F90               # Entry point (program)
    └── adam_patch_cpu_object.F90        # patch_cpu_object implementation

Field Variables ​

ArrayShapeNameDescription
q(nv, ni, nj, nk, nb)phiScalar potential (1 variable, nv=1)
r(nv, ni, nj, nk, nb)rhoSource / forcing distribution
dq(nv, ni, nj, nk, nb)—Residual scratch array

All arrays use the standard ADAM 5D layout (nv, ni, nj, nk, nb) with Fortran column-major ordering.

Type Hierarchy ​

patch_common_object          (src/app/patch/common/)
└── patch_cpu_object         (src/app/patch/cpu/)

patch_common_object Data Members ​

MemberTypeDescription
mpihmpih_objectMPI handler
adamadam_objectCore ADAM object (tree, grid, field, I/O)
fieldfield_object*Pointer to adam%field
gridgrid_object*Pointer to adam%grid
amramr_objectAMR marker handler
ibib_objectImmersed boundary handler
flailflail_objectLinear algebra / smoothing handler (FLAIL)
iopatch_io_objectI/O configuration
icpatch_ic_objectInitial conditions
bcpatch_bc_objectBoundary conditions
timepatch_time_objectConvergence / time parameters
qreal(R8P)(:,:,:,:,:)Scalar potential field
rreal(R8P)(:,:,:,:,:)Source distribution

patch_cpu_object Additional Member ​

MemberTypeDescription
dqreal(R8P)(:,:,:,:,:)Residual scratch array

Boundary Conditions ​

The only supported boundary condition is Dirichlet — the potential is set to a constant value on each domain face.

Six independent faces are configured in the INI file:

INI sectionFace
[bc_x_min]x-minimum face
[bc_x_max]x-maximum face
[bc_y_min]y-minimum face
[bc_y_max]y-maximum face
[bc_z_min]z-minimum face
[bc_z_max]z-maximum face
ini
[bc_x_min]
type = dirichlet
phi  = 0.0

[bc_x_max]
type = dirichlet
phi  = 0.0

Initial Conditions ​

The only supported IC type sets a Gaussian distribution of the source term:

IC typetype keyDescription
Gaussiangaussr=exp(−(x−0.5)2+(y−0.5)2+(z−0.5)20.01) centred at (0.5,0.5,0.5)
ini
[initial_conditions]
type           = gauss
amr_iterations = 2
regions_number = 1

[initial_conditions_region_1]
r      = 1.0
emin_x = 0.0
emin_y = 0.0
emin_z = 0.0
emax_x = 1.0
emax_y = 1.0
emax_z = 1.0

Iterative Smoothing Solvers (FLAIL) ​

The FLAIL library (adam_flail_object) provides the iterative smoothing kernels. The solver is selected in the INI file and dispatched via a Fortran procedure-pointer argument to integrate.

Smoothing method[linear-algebra] smoothing keyAlgorithm
Gauss-SeidelGAUSS-SEIDELSequential point update: φi,j,kn+1=12(1/Δx2+1/Δy2+1/Δz2)(neighbour sum−fi,j,k)
SORSORGauss-Seidel with over-relaxation: φn+1=φn+ω(φGS−φn), ω=1.8
SOR-OMPSOR-OMPParallel SOR with 8-colour red-black ordering (mod(i+j+k, 8)) and OpenMP parallel do
MultigridMULTIGRIDTwo-level V-cycle: pre-smooth (Gauss-Seidel) → restrict residuals (full-weighting) → coarse solve (Gauss-Seidel) → prolongate correction (trilinear) → post-smooth

FLAIL iteration counts are tunable per smoothing level:

INI keyDescription
iterationsGeneral iteration count
iterations_initPre-smoothing iterations (Multigrid: initial guess on fine grid)
iterations_finePost-smoothing iterations on fine grid
iterations_coarseSmoothing iterations on coarse grid
toleranceMaximum residual tolerance for convergence
ini
[linear-algebra]
smoothing          = MULTIGRID
iterations         = 1
iterations_init    = 3
iterations_fine    = 3
iterations_coarse  = 10
tolerance          = 1e-6

Methods ​

Lifecycle ​

ProcedureDescription
allocate_commonAllocates r with ghost-cell bounds
initialize_commonReads INI, initialises MPI, grid, AMR tree, field, IB, FLAIL, allocates arrays
allocate_cpuAllocates dq
initializeCalls initialize_common, allocates CPU data, loads restart or applies IC, saves initial snapshot
finalizeSaves final data, closes residuals file, finalises MPI

AMR and Immersed Boundary ​

ProcedureDescription
amr_updateRuns AMR marker loop (geometry and gradient criteria), calls adam%amr_update, recomputes φ
compute_phiComputes signed-distance (level-set) field φ for all IB bodies
mark_by_geoMarks blocks for refinement/de-refinement based on IB proximity (φ sign change)
mark_by_grad_varMarks blocks based on field-gradient threshold (skeleton, not yet active)
move_phiTranslates φ by a given body velocity
refine_uniformForces uniform refinement to a given level
integrate_eikonalAdvances the eikonal equation to propagate φ and inverts it

I/O ​

ProcedureDescription
load_restart_filesLoads q and grid state from restart files
save_xh5fWrites field data in XH5F format
save_residualsComputes L2 norm of dq via MPI_ALLREDUCE and appends to {basename}-residuals.dat
save_restart_filesWrites checkpoint (grid + field + XH5F snapshot)
save_simulation_dataOrchestrates periodic saves based on it_save and restart_save frequencies

Initial and Boundary Conditions ​

ProcedureDescription
set_initial_conditionsSets r to the selected IC distribution (Gaussian)
set_boundary_conditionsApplies Dirichlet BCs to ghost cells via the local_map_bc_crown map
update_ghostExchanges halos (local + MPI) and applies BCs

Numerical Kernel ​

ProcedureDescription
integrateConvergence iteration loop; dispatches to the selected smoothing procedure
simulateTop-level driver: initialise → select smoother → integrate → finalise

Convergence Loop ​

integrate runs the selected smoothing procedure until the residual drops below tolerance or the iteration budget is exhausted:

loop:
  it += 1
  call compute_smoothing(ni,nj,nk,ngc,nv,blocks_number, dxyz, r, q, dq=dq, dq_max=dq_max,
                         iterations_init, iterations_fine, iterations_coarse)
  if dq_max < tolerance:  EXIT  (convergence)
  dq = q                         ! store current solution for residuals log
  print_progress
  save_simulation_data
  if it >= it_max:  EXIT         (iteration budget)

simulate selects the smoothing procedure at startup:

fortran
select case(self%flail%smoothing)
case(SMOOTHING_MULTIGRID)    ; call self%integrate(compute_smoothing=compute_smoothing_multigrid)
case(SMOOTHING_GAUSS_SEIDEL) ; call self%integrate(compute_smoothing=compute_smoothing_gauss_seidel)
case(SMOOTHING_SOR)          ; call self%integrate(compute_smoothing=compute_smoothing_sor)
case(SMOOTHING_SOR_OMP)      ; call self%integrate(compute_smoothing=compute_smoothing_sor_omp)
endselect

Building and Running ​

bash
# Release build (GNU)
FoBiS.py build -mode patch-gnu

# Debug build
FoBiS.py build -mode patch-gnu-debug

The executable is written to exe/adam_patch_cpu.

bash
mpirun -np <N> exe/adam_patch_cpu [input.ini]

If no argument is given, input.ini in the working directory is used.

License ​

PATCH is part of the ADAM framework, released under the GNU Lesser General Public License v3.0 (LGPLv3).

Copyright (C) Andrea Di Mascio, Federico Negro, Giacomo Rossi, Francesco Salvadore, Stefano Zaghi.