Fill the four halo bands for the NODAL finite-difference (FDM) path.
Node anchoring: the physical boundary lies ON the boundary node (column 1 / nx_local, row 1 / ny_local), not on a cell face, so the ghost fills differ from the cell-centred FVM kernel: * reflecting: mirror about the boundary NODE — ghost(1-k)=node(1+k) with the wall-normal momentum negated (vs. the FVM face mirror ghost(1-k)=cell(k)). * periodic: duplicate-endpoint-aware nodal wrap. The nodal mesh has nodes ON both boundaries with node 1 == node nx_local the SAME physical point (period = (nx_local-1)*dx), so the wrap SKIPS the duplicate endpoint: ub(1-k)=ub(nx_local-k), ub(nx_local+k)=ub(1+k). This is the 2D analogue of the verified-correct 1D convention (boundary_conditions::apply_bcs_fdm, n_pt = n_cell+1 with ub(:,1)==ub(:,n_pt)). It differs from the FVM cell-centred wrap at the boundary (FVM cell averages have no duplicate endpoint), so the FDM operator equals FVM only in the INTERIOR away from the boundary ghosts — which is what the equivalence oracle in test_spatial_discretization_fdm_2d now pins. * outflow: zeroth-order extrapolation (copy the boundary node). * supersonic_inlet: free-stream conserved state.
Dual-path identical to apply_halos_2d: serial (np=1 / no cart comm) fills all four physical edges; under MPI the interior partition edges are filled by exchange_halos_2d and only the global-boundary edges (Cart neighbour == MPI_PROC_NULL) get a physical-BC fill, so no interior edge is double-filled.
NOTE (np>1 periodic): the MPI cartesian wrap in exchange_halos_2d performs the neighbour copy across the periodic boundary; verifying it stays consistent with the nodal grid under decomposition is deferred to the Phase 5 np>1 full-solve task.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(solver_state_2d_t), | intent(inout) | :: | state |