|
PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
|
This document provides a detailed explanation of the solver's grid and variable architecture. A clear understanding of this architecture is critical for correctly implementing new physics, boundary conditions, or post-processing routines.
The solver employs a structured curvilinear grid system managed by PETSc's DMDA. The core variables are defined on a staggered grid, with face-centered fluxes (ucont) and cell-centered quantities (ucat, P).
The most important architectural feature to understand is the Shifted Index Architecture for cell-centered data. In this design, the physical value for a geometric cell at index i is stored in the corresponding array at index i+1. This seemingly simple offset creates a clean, symmetric, and robust system for handling boundary conditions, resolving what might otherwise appear to be bugs or asymmetries in the code.
The grid is defined by a set of nodes with physical coordinates. The space between nodes forms the computational cells (or control volumes).
IM nodes in the i-direction is indexed from 0 to IM-1. Node coordinates are stored in the coor array, where coor[i] holds the (x,y,z) position of the i-th node.IM nodes form IM-1 physical cells, indexed 0 to IM-2. Cell i is the physical volume spanning between Node i and Node i+1.Example in 1D (i-direction):
(IM-1) x (JM-1) x (KM-1) physical cells.The solver's fundamental fluid dynamics variable is ucont, the contravariant flux, which is physically located on the faces of the cells. Its mapping is direct and intuitive.
ucont.x is on i-faces, ucont.y is on j-faces, etc.Node i is stored at index i.ucont.x[0]: Flux through the -Xi boundary face.ucont.x[IM-1]: Flux through the +Xi boundary face.FormBCS sets boundary fluxes. This is a standard, symmetric approach.Example in 1D (i-direction):
The Cartesian velocity (ucat) and pressure (P) are cell-centered variables. The key to this architecture is understanding their mapping:
The physical value for
Cell iis stored in the array at indexi+1.
This means there is a one-to-one correspondence between the IM-1 physical cells and IM-1 physical ucat values, but with a simple offset. The first and last elements of the array (ucat[0] and ucat[IM]) are reserved for ghost values.
This shifted index system creates a clean and symmetric ghost-cell framework.
At the "-Xi" Boundary (Min Boundary):
Cell 0**. Its velocity is stored at **ucat[1]**.ucat[0]** is now cleanly a ghost value for Cell 0.FormBCS function correctly sets this ghost value (e.g., ucat[0] = -ucat[1] for a wall) based on the first physical value.Diagram for the -Xi Boundary:
At the "+Xi" Boundary (Max Boundary):
Cell IM-2**. Its velocity is stored at **ucat[IM-1]**.Contra2Cart kernel correctly computes up to ucat[IM-1], which is the value for the last physical cell. There is no "leaked physics."ucat[IM]** is now cleanly a ghost value for Cell IM-2.FormBCS correctly sets this ghost value (e.g., ucat[IM] = -ucat[IM-1] for a wall) based on the last physical value.Diagram for the +Xi Boundary:
This architecture means there is no loss of resolution. The effective computational domain for cell-centered variables matches the geometric domain.
IM - 1 (indices 0 to IM-2)ucat Value Count (i-dir): IM - 1 (stored at indices 1 to IM-1)For a grid defined with IM x JM x KM nodes, the resolution is:
ucat/P Resolution: (IM-1) x (JM-1) x (KM-1) cells.This understanding is critical for validating post-processing functions. The ComputeNodalAverage function interpolates cell values to the nodes.
Node i, the function averages the 8 cells that meet at that node.+Xi Boundary: To compute the value at Node IM-1 (the physical boundary), the stencil correctly averages the surrounding cells. The key inputs in the i-direction are Cell IM-2 and its ghost representation.
ComputeNodalAverage function, by sampling ucat[IM-1] and ucat[IM], is correctly averaging the last physical cell with its proper ghost value. For a wall where ucat[IM] = -ucat[IM-1], the average will be near zero, correctly representing the no-slip condition at the node. The post-processing code is therefore correctly implemented for this architecture.This table provides a quick reference for the mapping.
Array Index i | Geometric Association | Role in Solver |
|---|---|---|
0 | Ghost value for Cell 0 | Boundary Condition Tool |
1 | Center of Cell 0 | First True Physical Value |
... | ... | ... |
i+1 | Center of Cell i | Interior Physical Value |
... | ... | ... |
IM-1 | Center of Cell IM-2 | Last True Physical Value |
IM | Ghost value for Cell IM-2 | Boundary Condition Tool |