solution_gather_2d Module

At np>1 every rank owns a tile of the global domain. gather_and_write_2d collects all tiles onto rank 0 via point-to-point MPI (simpler than MPI_Gatherv for irregular 2D blocks), assembles the full (neq2d,nx,ny) field on rank 0, and writes the same "x y rho u v p" ASCII format that write_result_2d produces at np=1.

At np=1 this is identical to write_result_2d (root receives nothing, just writes its own block which covers the whole domain).

The Cartesian communicator (from mpi_cart_2d) is used consistently so that rank renumbering by MPI_Cart_create(reorder=.true.) cannot cause a mismatch between gather source/destination and decomp placement indices.

Legacy-MPI note: MS-MPI ships only the legacy use mpi module; OpenMPI ships both. We guard with CFD_SOLVER_LEGACY_MPI in the same way as the other Phase-2D MPI source files.



Variables

Type Visibility Attributes Name Initial
integer, private, parameter :: TAG_META = 3001
integer, private, parameter :: TAG_BLOCK = 3002
integer, private, parameter :: TAG_COORD = 3003

(TAG_COORD+1 = 3004 carries the y block)

integer, private, parameter :: TAG_GHOST_L = 3005

Boundary-ghost frame slabs (checkpoint v6; see gather_boundary_ghosts_to_root).

integer, private, parameter :: TAG_GHOST_R = 3006
integer, private, parameter :: TAG_GHOST_B = 3007
integer, private, parameter :: TAG_GHOST_T = 3008

Subroutines

public subroutine gather_and_write_2d(state, filename, is_ok, message)

Gather all per-rank tiles to rank 0 and write the global field as ASCII.

Read more…

Arguments

Type IntentOptional Attributes Name
type(solver_state_2d_t), intent(in) :: state

Solver state (ub(:,1:nx_local,1:ny_local) = interior cells).

character(len=*), intent(in) :: filename

Output path (written by rank 0 only).

logical, intent(out) :: is_ok

.true. on success, .false. on I/O or MPI error.

character(len=*), intent(out) :: message

Human-readable error description on failure.

public subroutine gather_solution_to_root_2d(state, global_field, is_ok, message, global_xc, global_yc)

Gather all per-rank tiles to rank 0, assembling the full global solution field.

Read more…

Arguments

Type IntentOptional Attributes Name
type(solver_state_2d_t), intent(in) :: state

Solver state (ub(:,1:nx_local,1:ny_local) = interior cells).

real(kind=wp), intent(out), allocatable :: global_field(:,:,:)
logical, intent(out) :: is_ok

.true. on local success; caller reduces if needed.

character(len=*), intent(out) :: message

Human-readable error on failure.

real(kind=wp), intent(out), optional, allocatable :: global_xc(:,:)
real(kind=wp), intent(out), optional, allocatable :: global_yc(:,:)

private subroutine write_global_field(global_field, state, filename, is_ok, message, xc, yc)

Write the assembled global field to filename in the standard ASCII format.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: global_field(:,:,:)
type(solver_state_2d_t), intent(in) :: state
character(len=*), intent(in) :: filename
logical, intent(out) :: is_ok
character(len=*), intent(out) :: message
real(kind=wp), intent(in), optional :: xc(:,:)
real(kind=wp), intent(in), optional :: yc(:,:)

private subroutine write_global_field_vtk(global_field, state, filename, is_ok, message)

Write the assembled global field as legacy-ASCII VTK STRUCTURED_POINTS. Cell-centred: ORIGIN at the first cell centre, SPACING=(dx,dy). Emits SCALARS rho, SCALARS pressure, VECTORS velocity (i fastest, then j).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: global_field(:,:,:)
type(solver_state_2d_t), intent(in) :: state
character(len=*), intent(in) :: filename
logical, intent(out) :: is_ok
character(len=*), intent(out) :: message

private pure subroutine frame_slab_extents(ix1, iy1, nxl, nyl, nx_g, ny_g, h, has_l, has_r, has_b, has_t, ilo, ihi)

Slab geometry of one rank's owned piece of the GLOBAL boundary-ghost frame (the four width-h bands outside the global interior, corners included). Ownership is disjoint and exhaustive: the left/right bands cover global rows 1..ny_g only; the bottom/top bands span the FULL padded width 1-h..nx_g+h and therefore own the four corners. A rank owns a band segment iff its tile touches that global edge; a bottom/top-edge rank's segment extends into the corner columns iff it is also a left/right-edge rank (ilo/ihi below, in LOCAL i). Ghost cells of a rank that are NOT global-boundary cells are interior MPI-halo words: they are refreshed from neighbour interiors by the next halo exchange and are deliberately not part of the frame.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: ix1
integer, intent(in) :: iy1
integer, intent(in) :: nxl
integer, intent(in) :: nyl
integer, intent(in) :: nx_g
integer, intent(in) :: ny_g
integer, intent(in) :: h
logical, intent(out) :: has_l
logical, intent(out) :: has_r
logical, intent(out) :: has_b
logical, intent(out) :: has_t
integer, intent(out) :: ilo
integer, intent(out) :: ihi

public subroutine gather_boundary_ghosts_to_root(state, lft, rgt, bot, top)

Gather the GLOBAL boundary-ghost frame to cart rank 0: the four width-h ghost bands outside the global interior, corners included — every ghost cell of every rank that is NOT an interior MPI-halo cell. The 2D twin of 1D's gather_edge_ghosts_to_root (checkpoint v6; 1D's is v5/F2): the checkpoint must persist these words because the multi-stage whole-array RK kernels leave a stage-snapshot blend in them that is not reconstructable from the interior (see checkpoint_2d.f90's record-block comment for the full root cause).

Read more…

Arguments

Type IntentOptional Attributes Name
type(solver_state_2d_t), intent(in) :: state

This rank's solver state (ub must be allocated/populated).

real(kind=wp), intent(inout) :: lft(:,:,:)
real(kind=wp), intent(inout) :: rgt(:,:,:)
real(kind=wp), intent(inout) :: bot(:,:,:)
real(kind=wp), intent(inout) :: top(:,:,:)

private subroutine recv_slab(buf, n1, n2, n3, src, tag, comm, which)

Allocate buf to (n1, n2, n3) and blocking-receive one frame slab into it from cart rank src (gather_boundary_ghosts_to_root's root side).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout), allocatable :: buf(:,:,:)
integer, intent(in) :: n1
integer, intent(in) :: n2
integer, intent(in) :: n3
integer, intent(in) :: src
integer, intent(in) :: tag
integer, intent(in) :: comm
character(len=*), intent(in) :: which

private subroutine drop_slab(buf, which)

Deallocate a frame slab buffer with the mandatory stat check.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout), allocatable :: buf(:,:,:)
character(len=*), intent(in) :: which

public subroutine scatter_boundary_ghosts_from_root(state, lft, rgt, bot, top)

Inverse of gather_boundary_ghosts_to_root: deliver the checkpoint's GLOBAL boundary-ghost frame bands into this rank's ub ghost cells. Same band layout and disjoint ownership as the gather (the slab geometry lives ONLY in frame_slab_extents, so gather and scatter cannot drift).

Read more…

Arguments

Type IntentOptional Attributes Name
type(solver_state_2d_t), intent(inout) :: state

This rank's solver state (ub receives the restored ghosts).

real(kind=wp), intent(in) :: lft(:,:,:)
real(kind=wp), intent(in) :: rgt(:,:,:)
real(kind=wp), intent(in) :: bot(:,:,:)
real(kind=wp), intent(in) :: top(:,:,:)