PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
Internal Scattering Helpers

Lower-level functions used by the main scattering routines. More...

Collaboration diagram for Internal Scattering Helpers:

Macros

#define __FUNCT__   "InterpolateFieldFromCornerToCenter_Vector"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateFieldFromCornerToCenter_Scalar"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "TestCornerToCenterInterpolation"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateFieldFromCenterToCorner_Vector"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateFieldFromCenterToCorner_Scalar"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateEulerFieldToSwarm"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateAllFieldsToSwarm"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "GetScatterTargetInfo"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "GetPersistentLocalVector"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "AccumulateParticleField"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "NormalizeGridVectorByCount"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "ScatterParticleFieldToEulerField_Internal"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "ScatterParticleFieldToEulerField"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "ScatterAllParticleFieldsToEulerFields"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateCornerToFaceCenter_Scalar"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
#define __FUNCT__   "InterpolateCornerToFaceCenter_Vector"
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 

Functions

PetscErrorCode AccumulateParticleField (DM swarm, const char *particleFieldName, DM gridSumDM, Vec gridSumVec)
 Accumulates a particle field (scalar or vector) into a target grid sum vector.
 
PetscErrorCode NormalizeGridVectorByCount (DM countDM, Vec countVec, DM dataDM, Vec sumVec, Vec avgVec)
 Normalizes a grid vector of sums by a grid vector of counts to produce an average.
 
PetscErrorCode GetScatterTargetInfo (UserCtx *user, const char *particleFieldName, DM *targetDM, PetscInt *expected_dof)
 Determines the target Eulerian DM and expected DOF for scattering a given particle field.
 
PetscErrorCode GetPersistentLocalVector (UserCtx *user, const char *fieldName, Vec *localVec)
 Retrieves the persistent local vector (e.g., lPsi, lUcat) for a given field name.
 
static PetscErrorCode ScatterParticleFieldToEulerField_Internal (UserCtx *user, const char *particleFieldName, DM targetDM, PetscInt expected_dof, Vec eulerFieldAverageVec)
 Internal helper function to orchestrate the scatter operation (accumulate + normalize).
 

Detailed Description

Lower-level functions used by the main scattering routines.

Macro Definition Documentation

◆ __FUNCT__ [1/16]

#define __FUNCT__   "InterpolateFieldFromCornerToCenter_Vector"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [2/16]

#define __FUNCT__   "InterpolateFieldFromCornerToCenter_Scalar"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [3/16]

#define __FUNCT__   "TestCornerToCenterInterpolation"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [4/16]

#define __FUNCT__   "InterpolateFieldFromCenterToCorner_Vector"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [5/16]

#define __FUNCT__   "InterpolateFieldFromCenterToCorner_Scalar"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [6/16]

#define __FUNCT__   "InterpolateEulerFieldToSwarm"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [7/16]

#define __FUNCT__   "InterpolateAllFieldsToSwarm"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [8/16]

#define __FUNCT__   "GetScatterTargetInfo"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [9/16]

#define __FUNCT__   "GetPersistentLocalVector"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [10/16]

#define __FUNCT__   "AccumulateParticleField"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [11/16]

#define __FUNCT__   "NormalizeGridVectorByCount"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [12/16]

#define __FUNCT__   "ScatterParticleFieldToEulerField_Internal"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [13/16]

#define __FUNCT__   "ScatterParticleFieldToEulerField"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [14/16]

#define __FUNCT__   "ScatterAllParticleFieldsToEulerFields"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [15/16]

#define __FUNCT__   "InterpolateCornerToFaceCenter_Scalar"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

◆ __FUNCT__ [16/16]

#define __FUNCT__   "InterpolateCornerToFaceCenter_Vector"

Accumulates a particle field (scalar or vector) into a target grid sum vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF of gridSumDM).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist, DMs are incompatible, or memory access fails.

Definition at line 20 of file interpolation.c.

Function Documentation

◆ AccumulateParticleField()

PetscErrorCode AccumulateParticleField ( DM  swarm,
const char *  particleFieldName,
DM  gridSumDM,
Vec  localAccumulatorVec 
)

Accumulates a particle field (scalar or vector) into a target grid sum vector.

Accumulates particle field values into a ghosted Local Vector.

This function iterates through local particles, identifies their cell using the "DMSwarm_CellID" field, and adds the particle's field value (particleFieldName) to the corresponding cell location in the gridSumVec. It handles both scalar (DOF=1) and vector (DOF=3) fields automatically based on the DOF of gridSumDM.

IMPORTANT: The caller must ensure gridSumVec is zeroed before calling this function if a fresh sum calculation is desired.

Parameters
[in]swarmThe DMSwarm containing particles.
[in]particleFieldNameName of the field on the particles (must match DOF).
[in]gridSumDMThe DMDA associated with gridSumVec. Its DOF determines how many components are accumulated.
[in,out]gridSumVecThe Vec (associated with gridSumDM) to accumulate sums into.
Returns
PetscErrorCode 0 on success. Errors if fields don't exist or DMs are incompatible.

This function iterates over local particles and sums their specified field property into the provided grid vector. It supports both scalar (DOF=1) and vector (DOF=3) fields.

CRITICAL USAGE NOTES:

  1. localAccumulatorVec MUST be a Local Vector (obtained via DMGetLocalVector or DMCreateLocalVector). It must have memory allocated for ghost slots. Passing a Global Vector will trigger an error.
  2. The vector is NOT zeroed internally. The caller must zero it if fresh accumulation is desired.
  3. This function performs pure accumulation. It does NOT communicate ghost values to owners. The caller is responsible for calling DMLocalToGlobalBegin/End afterwards.
Parameters
[in]swarmThe DMSwarm object containing the particles.
[in]particleFieldNameThe name of the particle field to accumulate (e.g., "Psi", "Ucat").
[in]gridSumDMThe DMDA defining the grid topology.
[in,out]localAccumulatorVecThe ghosted local vector to accumulate into.
Returns
PetscErrorCode 0 on success.

Definition at line 1538 of file interpolation.c.

1540{
1541 PetscErrorCode ierr;
1542 PetscInt dof;
1543 PetscInt nlocal, p;
1544 const PetscReal *particle_arr = NULL;
1545 const PetscInt *cell_id_arr = NULL;
1546
1547 // DMDA Accessors
1548 PetscScalar ***arr_1d = NULL; // For scalar fields
1549 PetscScalar ****arr_3d = NULL; // For vector fields
1550
1551 // Ghosted dimension variables
1552 PetscInt gxs, gys, gzs, gxm, gym, gzm;
1553 PetscMPIInt rank;
1554 char msg[ERROR_MSG_BUFFER_SIZE];
1555
1556 PetscFunctionBeginUser;
1558
1559 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1560
1561 // --- 1. Validation & Setup ---
1562 if (!swarm || !gridSumDM || !localAccumulatorVec)
1563 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null input in AccumulateParticleField.");
1564
1565 // Get DMDA information
1566 ierr = DMDAGetInfo(gridSumDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1567 // Get Ghosted Corners (Global indices of the ghosted patch start, and its dimensions)
1568 ierr = DMDAGetGhostCorners(gridSumDM, &gxs, &gys, &gzs, &gxm, &gym, &gzm); CHKERRQ(ierr);
1569
1570 // --- 2. Verify Vector Type (Global vs Local) ---
1571 {
1572 PetscInt vecSize;
1573 PetscInt expectedLocalSize = gxm * gym * gzm * dof;
1574 ierr = VecGetSize(localAccumulatorVec, &vecSize); CHKERRQ(ierr);
1575
1576 if (vecSize != expectedLocalSize) {
1577 PetscSNPrintf(msg, sizeof(msg),
1578 "Vector dimension mismatch! Expected Ghosted Local Vector size %d (gxm*gym*gzm*dof), got %d. "
1579 "Did you pass a Global Vector instead of a Local Vector?",
1580 expectedLocalSize, vecSize);
1581 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1582 }
1583 }
1584
1585 // --- 3. Acquire Particle Data ---
1586 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1587 // These calls will fail nicely if the field doesn't exist
1588 ierr = DMSwarmGetField(swarm, particleFieldName, NULL, NULL, (void **)&particle_arr); CHKERRQ(ierr);
1589 ierr = DMSwarmGetField(swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_id_arr); CHKERRQ(ierr);
1590
1591 // --- 4. Acquire Grid Accessors ---
1592 // DMDAVecGetArray* handles the mapping from Global (i,j,k) to the underlying Local Array index
1593 if (dof == 1) {
1594 ierr = DMDAVecGetArray(gridSumDM, localAccumulatorVec, &arr_1d); CHKERRQ(ierr);
1595 } else if (dof == 3) {
1596 ierr = DMDAVecGetArrayDOF(gridSumDM, localAccumulatorVec, &arr_3d); CHKERRQ(ierr);
1597 } else {
1598 PetscSNPrintf(msg, sizeof(msg), "Unsupported DOF=%d. AccumulateParticleField supports DOF 1 or 3.", dof);
1599 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, msg);
1600 }
1601
1602 // --- 5. Accumulate Loop ---
1603 // Iterate through all local particles
1604 for (p = 0; p < nlocal; ++p) {
1605 // Retrieve Geometric Grid Index (0-based)
1606 PetscInt i_geom = cell_id_arr[p * 3 + 0];
1607 PetscInt j_geom = cell_id_arr[p * 3 + 1];
1608 PetscInt k_geom = cell_id_arr[p * 3 + 2];
1609
1610 // Apply Shift (+1) to match Memory Layout (Index 0 is boundary/ghost)
1611 PetscInt i = i_geom + 1;
1612 PetscInt j = j_geom + 1;
1613 PetscInt k = k_geom + 1;
1614
1615 // Bounds Check: Ensure (i,j,k) falls within the Local Ghosted Patch.
1616 // This allows writing to ghost slots which will later be reduced to the owner rank.
1617 if (i >= gxs && i < gxs + gxm &&
1618 j >= gys && j < gys + gym &&
1619 k >= gzs && k < gzs + gzm)
1620 {
1621 if (dof == 1) {
1622 arr_1d[k][j][i] += particle_arr[p];
1623 } else {
1624 // For DOF=3, unroll the loop for slight optimization
1625 arr_3d[k][j][i][0] += particle_arr[p * 3 + 0];
1626 arr_3d[k][j][i][1] += particle_arr[p * 3 + 1];
1627 arr_3d[k][j][i][2] += particle_arr[p * 3 + 2];
1628 }
1629 }
1630 // Note: Particles outside the ghost layer are skipped. This is expected behavior
1631 // if particles have not yet been migrated or localized correctly.
1632 }
1633
1634 // --- 6. Restore Arrays and Fields ---
1635 if (dof == 1) {
1636 ierr = DMDAVecRestoreArray(gridSumDM, localAccumulatorVec, &arr_1d); CHKERRQ(ierr);
1637 } else {
1638 ierr = DMDAVecRestoreArrayDOF(gridSumDM, localAccumulatorVec, &arr_3d); CHKERRQ(ierr);
1639 }
1640
1641 ierr = DMSwarmRestoreField(swarm, particleFieldName, NULL, NULL, (void **)&particle_arr); CHKERRQ(ierr);
1642 ierr = DMSwarmRestoreField(swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_id_arr); CHKERRQ(ierr);
1643
1645 PetscFunctionReturn(0);
1646}
#define ERROR_MSG_BUFFER_SIZE
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:746
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:737
Here is the caller graph for this function:

◆ NormalizeGridVectorByCount()

PetscErrorCode NormalizeGridVectorByCount ( DM  countDM,
Vec  countVec,
DM  dataDM,
Vec  sumVec,
Vec  avgVec 
)

Normalizes a grid vector of sums by a grid vector of counts to produce an average.

Calculates avgVec[i] = sumVec[i] / countVec[i] for each component of each OWNED cell where countVec[i] > 0. Sets avgVec[i] = 0 otherwise. Handles both scalar (DOF=1) and vector (DOF=3) data fields based on dataDM. Uses basic VecGetArray/VecGetArrayRead and manual index calculation.

Parameters
[in]countDMThe DMDA associated with countVec (must have DOF=1).
[in]countVecThe Vec containing particle counts per cell (read-only).
[in]dataDMThe DMDA associated with sumVec and avgVec (must have DOF=1 or DOF=3).
[in]sumVecThe Vec containing the accumulated sums per cell (read-only).
[in,out]avgVecThe Vec where the calculated averages will be stored (overwritten).
Returns
PetscErrorCode 0 on success.

Calculates avgVec[i] = sumVec[i] / countVec[i] for each component of each cell owned by the current process, provided countVec[i] > 0. Otherwise, sets avgVec[i] = 0. Handles both scalar (DOF=1) and vector (DOF=3) data fields based on the DOF of dataDM. Uses DMDA multi-dimensional array accessors (DMDAVecGetArray...) for safe and convenient indexing.

Parameters
[in]countDMThe DMDA associated with countVec (must have DOF=1).
[in]countVecThe Vec containing particle counts per cell (read-only).
[in]dataDMThe DMDA associated with sumVec and avgVec (must have DOF=1 or DOF=3).
[in]sumVecThe Vec containing the accumulated sums per cell (read-only).
[in,out]avgVecThe Vec where the calculated averages will be stored (overwritten). Must be associated with dataDM.
Returns
PetscErrorCode 0 on success. Errors on incompatible DMs or memory access failure.

Definition at line 1795 of file interpolation.c.

1797{
1798 PetscErrorCode ierr;
1799 PetscInt data_dof;
1800 PetscInt count_dof;
1801 PetscMPIInt rank;
1802 char msg[ERROR_MSG_BUFFER_SIZE];
1803
1804 // Pointers for DMDA array accessors - declare specific types
1805 PetscScalar ***count_arr_3d = NULL; // For DOF=1 count vector (3D DMDA)
1806 PetscScalar ***sum_arr_scalar = NULL; // For DOF=1 sum vector (3D DMDA)
1807 PetscScalar ***avg_arr_scalar = NULL; // For DOF=1 avg vector (3D DMDA)
1808 PetscScalar ****sum_arr_vector = NULL; // For DOF=3 sum vector (3D DMDA + DOF)
1809 PetscScalar ****avg_arr_vector = NULL; // For DOF=3 avg vector (3D DMDA + DOF)
1810
1811
1812 PetscFunctionBeginUser;
1813
1815
1816 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1817
1818 // --- Validation ---
1819 ierr = DMDAGetInfo(countDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &count_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1820 ierr = DMDAGetInfo(dataDM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &data_dof, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
1821 if (count_dof != 1) { PetscSNPrintf(msg, sizeof(msg), "countDM must have DOF=1, got %d.", count_dof); SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg); }
1822 if (data_dof != 1 && data_dof != 3) { PetscSNPrintf(msg, sizeof(msg), "dataDM DOF must be 1 or 3, got %d.", data_dof); SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg); }
1823
1824 // --- Get Array Access using appropriate DMDA accessors ---
1825 ierr = DMDAVecGetArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1826
1827 if (data_dof == 1) {
1828 ierr = DMDAVecGetArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1829 ierr = DMDAVecGetArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1830 } else { // data_dof == 3
1831 ierr = DMDAVecGetArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1832 ierr = DMDAVecGetArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1833 }
1834
1835 // Get the corners (global start indices) and dimensions of the *local owned* region
1836 PetscInt xs, ys, zs, xm, ym, zm;
1837 ierr = DMDAGetCorners(countDM, &xs, &ys, &zs, &xm, &ym, &zm); CHKERRQ(ierr);
1838
1839 // --- Normalize Over Owned Cells ---
1840 LOG_ALLOW(LOCAL, LOG_DEBUG, "(Rank %d): Normalizing DOF=%d data over owned range [%d:%d, %d:%d, %d:%d].\n",
1841 rank, data_dof, xs, xs+xm, ys, ys+ym, zs, zs+zm);
1842
1843 // Loop using GLOBAL indices (i, j, k) over the range owned by this process
1844 for (PetscInt k = zs; k < zs + zm; ++k) {
1845 for (PetscInt j = ys; j < ys + ym; ++j) {
1846 for (PetscInt i = xs; i < xs + xm; ++i) {
1847
1848 // Access the count using standard 3D indexing
1849 PetscScalar count = count_arr_3d[k][j][i];
1850
1851 if (PetscRealPart(count) > 0.5) { // Use tolerance for float comparison
1852 if (data_dof == 1) {
1853 // Access scalar sum/avg using standard 3D indexing
1854 avg_arr_scalar[k][j][i] = sum_arr_scalar[k][j][i] / count;
1855 } else { // data_dof == 3
1856 // Access vector components using DOF indexing on the last dimension
1857 for (PetscInt c = 0; c < data_dof; ++c) {
1858 avg_arr_vector[k][j][i][c] = sum_arr_vector[k][j][i][c] / count;
1859 }
1860 }
1861 } else { // count is zero or negative
1862 // Set average to zero
1863 if (data_dof == 1) {
1864 avg_arr_scalar[k][j][i] = 0.0;
1865 } else { // data_dof == 3
1866 for (PetscInt c = 0; c < data_dof; ++c) {
1867 avg_arr_vector[k][j][i][c] = 0.0;
1868 }
1869 }
1870 } // end if count > 0.5
1871 } // end i loop
1872 } // end j loop
1873 } // end k loop
1874
1875 // --- Restore Arrays using appropriate functions ---
1876 ierr = DMDAVecRestoreArrayRead(countDM, countVec, &count_arr_3d); CHKERRQ(ierr);
1877 if (data_dof == 1) {
1878 ierr = DMDAVecRestoreArrayRead(dataDM, sumVec, &sum_arr_scalar); CHKERRQ(ierr);
1879 ierr = DMDAVecRestoreArray(dataDM, avgVec, &avg_arr_scalar); CHKERRQ(ierr);
1880 } else { // data_dof == 3
1881 ierr = DMDAVecRestoreArrayDOFRead(dataDM, sumVec, &sum_arr_vector); CHKERRQ(ierr);
1882 ierr = DMDAVecRestoreArrayDOF(dataDM, avgVec, &avg_arr_vector); CHKERRQ(ierr);
1883 }
1884
1885 // --- Assemble Final Average Vector ---
1886 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Assembling final average vector (DOF=%d).\n", data_dof);
1887 ierr = VecAssemblyBegin(avgVec); CHKERRQ(ierr);
1888 ierr = VecAssemblyEnd(avgVec); CHKERRQ(ierr);
1889
1890
1892
1893 PetscFunctionReturn(0);
1894}
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:45
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:46
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:200
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
Here is the caller graph for this function:

◆ GetScatterTargetInfo()

PetscErrorCode GetScatterTargetInfo ( UserCtx user,
const char *  particleFieldName,
DM *  targetDM,
PetscInt *  expected_dof 
)

Determines the target Eulerian DM and expected DOF for scattering a given particle field.

Based on hardcoded rules mapping particle field names ("P", "Nvert", "Ucat", "Ucont") to user context DMs (user->da or user->fda). This function encapsulates the policy of where different fields should be scattered. Modify this function to add rules for custom fields.

Parameters
[in]userPointer to the UserCtx containing required DMs (da, fda).
[in]particleFieldNameName of the particle field.
[out]targetDMPointer to store the determined target DM (user->da or user->fda).
[out]expected_dofPointer to store the expected DOF (1 or 3) for this field.
Returns
PetscErrorCode Returns 0 on success. Error codes:
  • PETSC_ERR_ARG_NULL if required inputs are NULL.
  • PETSC_ERR_ARG_WRONG if particleFieldName is not recognized.

Definition at line 1426 of file interpolation.c.

1428{
1429 char msg[ERROR_MSG_BUFFER_SIZE]; // Buffer for formatted error messages
1430 PetscFunctionBeginUser;
1431
1433
1434 // --- Input Validation ---
1435 // Check for NULL pointers in essential inputs
1436 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx pointer is NULL.");
1437 if (!user->da) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx->da is NULL.");
1438 if (!user->fda) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "UserCtx->fda is NULL."); // Needed for vector fields
1439 if (!particleFieldName) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "particleFieldName is NULL.");
1440 if (!targetDM) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Output targetDM pointer is NULL.");
1441 if (!expected_dof) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Output expected_dof pointer is NULL.");
1442
1443 // --- Determine Target DM and DOF based on Field Name ---
1444 // Compare the input field name with known scalar fields targeting 'da'
1445 if (strcmp(particleFieldName, "Psi") == 0 || strcmp(particleFieldName, "Nvert") == 0) {
1446 *expected_dof = 1; // Scalar fields have DOF 1
1447 *targetDM = user->da; // Target the primary scalar DMDA
1448 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Field '%s' targets DM 'da' (DOF=1).\n", particleFieldName);
1449 }
1450 // Compare with known vector fields targeting 'fda'
1451 else if (strcmp(particleFieldName, "Ucat") == 0 || strcmp(particleFieldName, "Ucont") == 0) {
1452 *expected_dof = 3; // Vector fields have DOF 3
1453 *targetDM = user->fda; // Target the vector DMDA (often node-based)
1454 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Field '%s' targets DM 'fda' (DOF=3).\n", particleFieldName);
1455 }
1456 // --- Add rules for other fields here ---
1457 // else if (strcmp(particleFieldName, "SomeOtherScalar") == 0) { *expected_dof = 1; *targetDM = user->da; }
1458 // else if (strcmp(particleFieldName, "SomeOtherVector") == 0) { *expected_dof = 3; *targetDM = user->someOtherDM; }
1459 else {
1460 // The provided field name doesn't match any known rules
1461 *targetDM = NULL; // Indicate failure
1462 *expected_dof = 0;
1463 // Format the error message manually
1464 PetscSNPrintf(msg, sizeof(msg), "Field name '%s' is not recognized for automatic DM selection.", particleFieldName);
1465 // Use SETERRQ with the formatted message and appropriate error code
1466 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg); // Use WRONG argument error code
1467 }
1468
1470
1471 PetscFunctionReturn(0);
1472}
Here is the caller graph for this function:

◆ GetPersistentLocalVector()

PetscErrorCode GetPersistentLocalVector ( UserCtx user,
const char *  fieldName,
Vec *  localVec 
)

Retrieves the persistent local vector (e.g., lPsi, lUcat) for a given field name.

Parameters
userUser context containing the persistent vectors.
fieldNameName of the field ("Psi", "Ucat", etc.).
localVecOutput pointer to the vector.
Returns
PetscErrorCode

Definition at line 1484 of file interpolation.c.

1485{
1486 PetscFunctionBeginUser;
1487
1488 if (!user || !fieldName || !localVec)
1489 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Null input in GetPersistentLocalVector");
1490
1491 if (strcmp(fieldName, "Psi") == 0) {
1492 if (!user->lPsi) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "user->lPsi is not initialized");
1493 *localVec = user->lPsi;
1494 }
1495 else if (strcmp(fieldName, "Ucat") == 0) {
1496 if (!user->lUcat) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "user->lUcat is not initialized");
1497 *localVec = user->lUcat;
1498 }
1499 else if (strcmp(fieldName, "Ucont") == 0) {
1500 if (!user->lUcont) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "user->lUcont is not initialized");
1501 *localVec = user->lUcont;
1502 }
1503 else if (strcmp(fieldName, "Nvert") == 0) {
1504 if (!user->lNvert) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "user->lNvert is not initialized");
1505 *localVec = user->lNvert;
1506 }
1507 else {
1508 char msg[ERROR_MSG_BUFFER_SIZE];
1509 PetscSNPrintf(msg, sizeof(msg), "Field '%s' does not have a mapped persistent local vector.", fieldName);
1510 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, msg);
1511 }
1512
1513 PetscFunctionReturn(0);
1514}
Vec lNvert
Definition variables.h:755
Vec lPsi
Definition variables.h:801
Vec lUcont
Definition variables.h:755
Vec lUcat
Definition variables.h:755

◆ ScatterParticleFieldToEulerField_Internal()

static PetscErrorCode ScatterParticleFieldToEulerField_Internal ( UserCtx user,
const char *  particleFieldName,
DM  targetDM,
PetscInt  expected_dof,
Vec  eulerFieldAverageVec 
)
static

Internal helper function to orchestrate the scatter operation (accumulate + normalize).

Manages the temporary sum vector and calls the accumulation and normalization functions. Assumes caller determined target DM and DOF. Checks for particle field existence. NOTE: If DMSwarmGetField fails, the subsequent SETERRQ will overwrite the original error.

Parameters
[in]userPointer to UserCtx containing swarm, ParticleCount, da.
[in]particleFieldNameName of the field in the DMSwarm.
[in]targetDMThe DMDA where the final average and intermediate sum reside.
[in]expected_dofThe expected DOF (1 or 3) for the targetDM and field.
[in,out]eulerFieldAverageVecThe pre-created Vec associated with targetDM to store the result.
Returns
PetscErrorCode 0 on success. Errors if particle field doesn't exist or underlying helpers fail.

Definition at line 1924 of file interpolation.c.

1929{
1930 PetscErrorCode ierr;
1931 Vec globalsumVec = NULL;
1932 Vec localsumVec = NULL;
1933 char msg[ERROR_MSG_BUFFER_SIZE]; // Buffer for formatted error messages
1934
1935 PetscFunctionBeginUser;
1936
1938
1939 if (!user || !user->swarm || !user->ParticleCount || !particleFieldName || !targetDM || !eulerFieldAverageVec)
1940 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "NULL input provided to ScatterParticleFieldToEulerField_Internal.");
1941
1942 // --- Check if Particle Field Exists ---
1943 // Attempt a GetField call; if it fails, the field doesn't exist.
1944 // We let CHKERRQ handle the error directly if the field doesn't exist OR
1945 // we catch it specifically to provide a more tailored message.
1946
1947 /*
1948 LOG_ALLOW(GLOBAL,LOG_DEBUG,"Field %s being accessed to check existence \n",particleFieldName);
1949 ierr = DMSwarmGetField(user->swarm, particleFieldName, NULL, NULL, NULL);
1950 if (ierr) { // If GetField returns an error
1951 PetscSNPrintf(msg, sizeof(msg), "Particle field '%s' not found in DMSwarm for scattering.", particleFieldName);
1952 // Directly set the error, overwriting the one from GetField
1953 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, msg);
1954 }
1955 ierr = DMSwarmRestoreField(user->swarm, particleFieldName, NULL, NULL, NULL);
1956 */
1957
1958 // --- Setup Temporary Sum Vector ---
1959 ierr = VecDuplicate(eulerFieldAverageVec, &globalsumVec); CHKERRQ(ierr);
1960 ierr = VecSet(globalsumVec, 0.0); CHKERRQ(ierr);
1961 ierr = PetscSNPrintf(msg, sizeof(msg), "TempSum_%s", particleFieldName); CHKERRQ(ierr);
1962 ierr = PetscObjectSetName((PetscObject)globalsumVec, msg); CHKERRQ(ierr);
1963
1964 // create local vector for accumulation
1965 ierr = DMGetLocalVector(targetDM, &localsumVec); CHKERRQ(ierr);
1966 ierr = VecSet(localsumVec, 0.0); CHKERRQ(ierr); // Must be zeroed before accumulation
1967 ierr = PetscSNPrintf(msg, sizeof(msg), "LocalTempSum_%s", particleFieldName); CHKERRQ(ierr);
1968 ierr = PetscObjectSetName((PetscObject)localsumVec, msg); CHKERRQ(ierr);
1969
1970 // --- Accumulate ---
1971 // This will call DMSwarmGetField again. If it failed above, it will likely fail here too,
1972 // unless the error was cleared somehow between the check and here (unlikely).
1973 // If the check above was skipped (Option 1), this is where the error for non-existent
1974 // field will be caught by CHKERRQ.
1975 ierr = AccumulateParticleField(user->swarm, particleFieldName, targetDM, localsumVec); CHKERRQ(ierr);
1976
1977 // --- Local to Global Sum ---
1978 ierr = DMLocalToGlobalBegin(targetDM, localsumVec, ADD_VALUES, globalsumVec); CHKERRQ(ierr);
1979 ierr = DMLocalToGlobalEnd(targetDM, localsumVec, ADD_VALUES, globalsumVec); CHKERRQ(ierr);
1980 // Return local vector to DM
1981 ierr = DMRestoreLocalVector(targetDM, &localsumVec); CHKERRQ(ierr);
1982
1983 // Calculate the number of particles per cell.
1984 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
1985 // --- Normalize ---
1986 ierr = NormalizeGridVectorByCount(user->da, user->ParticleCount, targetDM, globalsumVec, eulerFieldAverageVec); CHKERRQ(ierr);
1987
1988 // --- Cleanup ---
1989 ierr = VecDestroy(&globalsumVec); CHKERRQ(ierr);
1990
1991
1993
1994 PetscFunctionReturn(0);
1995}
PetscErrorCode NormalizeGridVectorByCount(DM countDM, Vec countVec, DM dataDM, Vec sumVec, Vec avgVec)
Normalizes a grid vector of sums by a grid vector of counts to produce an average.
PetscErrorCode AccumulateParticleField(DM swarm, const char *particleFieldName, DM gridSumDM, Vec gridSumVec)
Accumulates a particle field (scalar or vector) into a target grid sum vector.
PetscErrorCode CalculateParticleCountPerCell(UserCtx *user)
Counts particles in each cell of the DMDA 'da' and stores the result in user->ParticleCount.
Vec ParticleCount
Definition variables.h:800
Here is the call graph for this function:
Here is the caller graph for this function: