PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Functions
test_runtime_kernels.c File Reference

C unit tests for runtime, particle, wall, and walltime-guard helpers. More...

#include "test_support.h"
#include "BC_Handlers.h"
#include "ParticleMotion.h"
#include "ParticlePhysics.h"
#include "ParticleSwarm.h"
#include "interpolation.h"
#include "initialcondition.h"
#include "les.h"
#include "runloop.h"
#include "setup.h"
#include "wallfunction.h"
#include "walkingsearch.h"
Include dependency graph for test_runtime_kernels.c:

Go to the source code of this file.

Functions

static PetscErrorCode SyncRuntimeFieldGhosts (UserCtx *user)
 Synchronizes the minimal runtime fixture's global fields into their persistent local ghosts.
 
static PetscErrorCode SeedSingleParticle (UserCtx *user, PetscInt ci, PetscInt cj, PetscInt ck, PetscReal x, PetscReal y, PetscReal z, PetscReal wx, PetscReal wy, PetscReal wz, PetscInt status_value)
 Seeds one localized swarm particle with the cell, position, weight, and status data used by runtime tests.
 
static PetscErrorCode TestDistributeParticlesRemainderHandling (void)
 Tests particle distribution remainder handling across ranks.
 
static PetscErrorCode TestIsParticleInsideBoundingBoxBasicCases (void)
 Tests basic particle-inside-bounding-box classification cases.
 
static PetscErrorCode TestUpdateParticleWeightsComputesExpectedRatios (void)
 Tests particle weight updates against expected ratios.
 
static PetscErrorCode TestUpdateParticlePositionWithoutBrownianContribution (void)
 Tests particle position updates without Brownian forcing.
 
static PetscErrorCode TestUpdateParticlePositionDiffusivityGradientOnly (void)
 Tests particle position updates driven only by diffusivity-gradient drift.
 
static PetscErrorCode TestUpdateParticleFieldIEMRelaxation (void)
 Tests IEM relaxation updates for particle-carried fields.
 
static PetscErrorCode TestSetInitialInteriorFieldIgnoresNonUcontRequest (void)
 Tests that non-Ucont requests do not modify interior field initialization.
 
static PetscErrorCode TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux (void)
 Tests cartesian Constant IC: Cart2Contra sets contravariant flux via metric dot product.
 
static PetscErrorCode TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection (void)
 Tests curvilinear Constant IC: flow_direction selects the streamwise axis.
 
static PetscErrorCode TestSetInitialInteriorFieldZeroClearsInterior (void)
 Tests zero IC clears physical-cell contravariant velocity.
 
static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleProfile (void)
 Tests Poiseuille IC is the product parabola that vanishes on the walls.
 
static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleUniformAlongPeriodicAxis (void)
 Tests Poiseuille IC is uniform along a periodic cross-stream axis.
 
static PetscErrorCode TestCart2ContraConvertsCartesianField (void)
 Tests spatially varying Cartesian-field conversion to contravariant fluxes.
 
static PetscErrorCode TestCart2ContraUsesFinalizedPeriodicUcat (void)
 Verifies periodic Ucat endpoints are repaired before Cart2Contra terminal faces.
 
static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcat (void)
 Tests loading a staged Ucat file IC and converting it to Ucont.
 
static PetscErrorCode TestWriteLESFieldsCopiesOwnedPeriodicValues (void)
 Tests LES output staging from local vectors on a multiply periodic DMDA.
 
static PetscErrorCode StagedFourierModeMaxDivergence (UserCtx *user, PetscInt mode_x, PetscInt mode_y, PetscInt mode_z, Cmpnts amplitude, const char *tmpdir, PetscReal *max_divergence)
 Stages a real Cartesian Fourier mode through the production file-IC path.
 
static PetscErrorCode TestStagedUcatFourierModesUsePicurvDiscreteSymbol (void)
 Cross-checks selected exact Fourier modes against PICurv's native discrete symbol.
 
static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcont (void)
 Tests loading a staged Ucont file IC without Cartesian conversion.
 
static PetscErrorCode TestInterpolateAllFieldsToSwarmConstantFields (void)
 Tests direct interpolation from Eulerian fields to one localized swarm particle.
 
static PetscErrorCode TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields (void)
 Tests the corner-averaged (legacy) interpolation path on constant fields.
 
static PetscErrorCode TestScatterAllParticleFieldsToEulerFieldsAveragesPsi (void)
 Tests particle-to-grid scattering using known cell occupancy and scalar values.
 
static PetscErrorCode TestCalculateParticleCountPerCellCountsGlobalCellIDs (void)
 Tests particle counting by geometric cell IDs using the production +1 storage shift.
 
static PetscErrorCode TestResetAllParticleStatusesLeavesLostParticlesUntouched (void)
 Tests localized particle-status reset behavior for restart of the location workflow.
 
static PetscErrorCode TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle (void)
 Tests direct removal of particles that leave every rank bounding box.
 
static PetscErrorCode TestCheckAndRemoveLostParticlesRemovesLostEntries (void)
 Tests direct removal of particles already marked LOST by the location workflow.
 
static PetscErrorCode TestCalculateBrownianDisplacementDeterministicSeed (void)
 Tests Brownian displacement generation against a duplicated seeded RNG stream.
 
static PetscErrorCode TestUpdateAllParticlePositionsMovesSwarmEntries (void)
 Tests swarm-wide particle position updates using the same transport path as the runtime loop.
 
static PetscErrorCode TestLocateAllParticlesInGridPriorCellFastPath (void)
 Tests the location orchestrator fast path when a particle already carries a valid prior cell.
 
static PetscErrorCode TestLocateAllParticlesInGridGuessPathResolvesLocalParticle (void)
 Tests the guess-then-verify orchestrator path for a local particle with an unknown prior cell.
 
static PetscErrorCode TestLocateParticleOrFindMigrationTargetCountsReSearch (void)
 Verifies that later settlement passes increment re-search metrics.
 
static PetscErrorCode TestWallNoSlipAndFreeSlipHelpers (void)
 Tests no-slip and free-slip wall helper kernels.
 
static PetscErrorCode TestWallModelScalarHelpers (void)
 Tests wall-model scalar helper kernels.
 
static PetscErrorCode TestWallModelVelocityHelpers (void)
 Tests closed-form and iterative wall-model velocity helpers against inverse reconstructions.
 
static PetscErrorCode TestWallFunctionVectorWrappers (void)
 Tests the vector wall-function wrappers on a tangential reference flow.
 
static PetscErrorCode TestValidateDrivenFlowConfigurationNoDrivenHandlers (void)
 Tests driven-flow validation when no driven handlers are present.
 
static PetscErrorCode TestMinimalFixtureMirrorsProductionDMLayout (void)
 Tests that the shared minimal fixture mirrors the production DA contract.
 
static PetscErrorCode TestMinimalFixtureRegistersProductionSwarmFields (void)
 Tests that the shared swarm fixture registers the production field set.
 
static PetscErrorCode TestUpdateSolverHistoryVectorsShiftsStates (void)
 Tests solver history-vector shifting between time levels.
 
static PetscErrorCode TestGetOwnedCellRangeSingleRankAccounting (void)
 Tests owned-cell range accounting on a single MPI rank.
 
static PetscErrorCode TestComputeAndStoreNeighborRanksSingleRank (void)
 Tests neighbor-rank discovery on a single MPI rank.
 
static PetscErrorCode TestRuntimeWalltimeGuardParsesPositiveSeconds (void)
 Tests parsing of positive runtime walltime metadata values.
 
static PetscErrorCode TestRuntimeWalltimeGuardEstimatorHelpers (void)
 Tests walltime-guard estimator helper calculations.
 
static PetscErrorCode TestRuntimeWalltimeGuardTriggerDecision (void)
 Tests runtime walltime-guard shutdown trigger decisions.
 
int main (int argc, char **argv)
 Runs the unit-runtime PETSc test binary.
 

Detailed Description

C unit tests for runtime, particle, wall, and walltime-guard helpers.

Definition in file test_runtime_kernels.c.

Function Documentation

◆ SyncRuntimeFieldGhosts()

static PetscErrorCode SyncRuntimeFieldGhosts ( UserCtx *  user)
static

Synchronizes the minimal runtime fixture's global fields into their persistent local ghosts.

Definition at line 23 of file test_runtime_kernels.c.

24{
25 PetscFunctionBeginUser;
26 PetscCall(DMGlobalToLocalBegin(user->da, user->P, INSERT_VALUES, user->lP));
27 PetscCall(DMGlobalToLocalEnd(user->da, user->P, INSERT_VALUES, user->lP));
28 PetscCall(DMGlobalToLocalBegin(user->da, user->Psi, INSERT_VALUES, user->lPsi));
29 PetscCall(DMGlobalToLocalEnd(user->da, user->Psi, INSERT_VALUES, user->lPsi));
30 PetscCall(DMGlobalToLocalBegin(user->da, user->Diffusivity, INSERT_VALUES, user->lDiffusivity));
31 PetscCall(DMGlobalToLocalEnd(user->da, user->Diffusivity, INSERT_VALUES, user->lDiffusivity));
32 PetscCall(DMGlobalToLocalBegin(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
33 PetscCall(DMGlobalToLocalEnd(user->fda, user->Ucat, INSERT_VALUES, user->lUcat));
34 PetscCall(DMGlobalToLocalBegin(user->fda, user->Ucont, INSERT_VALUES, user->lUcont));
35 PetscCall(DMGlobalToLocalEnd(user->fda, user->Ucont, INSERT_VALUES, user->lUcont));
36 PetscCall(DMGlobalToLocalBegin(user->fda, user->DiffusivityGradient, INSERT_VALUES, user->lDiffusivityGradient));
37 PetscCall(DMGlobalToLocalEnd(user->fda, user->DiffusivityGradient, INSERT_VALUES, user->lDiffusivityGradient));
38 PetscFunctionReturn(0);
39}
Vec lDiffusivityGradient
Definition variables.h:1117
Vec DiffusivityGradient
Definition variables.h:1117
Vec Ucont
Definition variables.h:1113
Vec lUcont
Definition variables.h:1113
Vec Diffusivity
Definition variables.h:1116
Vec lUcat
Definition variables.h:1113
Vec lDiffusivity
Definition variables.h:1116
Here is the caller graph for this function:

◆ SeedSingleParticle()

static PetscErrorCode SeedSingleParticle ( UserCtx *  user,
PetscInt  ci,
PetscInt  cj,
PetscInt  ck,
PetscReal  x,
PetscReal  y,
PetscReal  z,
PetscReal  wx,
PetscReal  wy,
PetscReal  wz,
PetscInt  status_value 
)
static

Seeds one localized swarm particle with the cell, position, weight, and status data used by runtime tests.

Definition at line 44 of file test_runtime_kernels.c.

55{
56 PetscReal *positions = NULL;
57 PetscReal *weights = NULL;
58 PetscInt *cell_ids = NULL;
59 PetscInt *status = NULL;
60
61 PetscFunctionBeginUser;
62 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
63 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
64 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
65 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
66
67 positions[0] = x;
68 positions[1] = y;
69 positions[2] = z;
70 weights[0] = wx;
71 weights[1] = wy;
72 weights[2] = wz;
73 cell_ids[0] = ci;
74 cell_ids[1] = cj;
75 cell_ids[2] = ck;
76 status[0] = status_value;
77
78 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
79 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
80 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
81 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
82 PetscFunctionReturn(0);
83}
Here is the caller graph for this function:

◆ TestDistributeParticlesRemainderHandling()

static PetscErrorCode TestDistributeParticlesRemainderHandling ( void  )
static

Tests particle distribution remainder handling across ranks.

Definition at line 88 of file test_runtime_kernels.c.

89{
90 PetscInt particles_per_rank = -1;
91 PetscInt remainder = -1;
92
93 PetscFunctionBeginUser;
94 PetscCall(DistributeParticles(10, 0, 3, &particles_per_rank, &remainder));
95 PetscCall(PicurvAssertIntEqual(4, particles_per_rank, "rank 0 should receive one remainder particle"));
96 PetscCall(PicurvAssertIntEqual(1, remainder, "remainder should be reported correctly"));
97
98 PetscCall(DistributeParticles(10, 2, 3, &particles_per_rank, &remainder));
99 PetscCall(PicurvAssertIntEqual(3, particles_per_rank, "last rank should receive base particle count"));
100 PetscCall(PicurvAssertIntEqual(1, remainder, "remainder should remain unchanged across ranks"));
101 PetscFunctionReturn(0);
102}
PetscErrorCode DistributeParticles(PetscInt numParticles, PetscMPIInt rank, PetscMPIInt size, PetscInt *particlesPerProcess, PetscInt *remainder)
Distributes particles evenly across MPI processes, handling any remainders.
PetscErrorCode PicurvAssertIntEqual(PetscInt expected, PetscInt actual, const char *context)
Asserts that two integer values are equal.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestIsParticleInsideBoundingBoxBasicCases()

static PetscErrorCode TestIsParticleInsideBoundingBoxBasicCases ( void  )
static

Tests basic particle-inside-bounding-box classification cases.

Definition at line 107 of file test_runtime_kernels.c.

108{
109 BoundingBox bbox;
110 Particle particle;
111
112 PetscFunctionBeginUser;
113 PetscCall(PetscMemzero(&bbox, sizeof(bbox)));
114 PetscCall(PetscMemzero(&particle, sizeof(particle)));
115
116 bbox.min_coords.x = 0.0;
117 bbox.min_coords.y = 0.0;
118 bbox.min_coords.z = 0.0;
119 bbox.max_coords.x = 1.0;
120 bbox.max_coords.y = 2.0;
121 bbox.max_coords.z = 3.0;
122
123 particle.loc.x = 0.25;
124 particle.loc.y = 1.0;
125 particle.loc.z = 2.5;
126 PetscCall(PicurvAssertBool(IsParticleInsideBoundingBox(&bbox, &particle), "particle should be inside bounding box"));
127
128 particle.loc.x = 1.5;
129 PetscCall(PicurvAssertBool((PetscBool)!IsParticleInsideBoundingBox(&bbox, &particle), "particle should be outside bounding box"));
130 PetscFunctionReturn(0);
131}
PetscBool IsParticleInsideBoundingBox(const BoundingBox *bbox, const Particle *particle)
Checks if a particle's location is within a specified bounding box.
PetscErrorCode PicurvAssertBool(PetscBool value, const char *context)
Asserts that one boolean condition is true.
Cmpnts max_coords
Maximum x, y, z coordinates of the bounding box.
Definition variables.h:199
Cmpnts min_coords
Minimum x, y, z coordinates of the bounding box.
Definition variables.h:198
PetscScalar x
Definition variables.h:122
Cmpnts loc
Definition variables.h:211
PetscScalar z
Definition variables.h:122
PetscScalar y
Definition variables.h:122
Defines a 3D axis-aligned bounding box.
Definition variables.h:197
Defines a particle's core properties for Lagrangian tracking.
Definition variables.h:208
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateParticleWeightsComputesExpectedRatios()

static PetscErrorCode TestUpdateParticleWeightsComputesExpectedRatios ( void  )
static

Tests particle weight updates against expected ratios.

Definition at line 136 of file test_runtime_kernels.c.

137{
138 Particle particle;
139 PetscReal distances[NUM_FACES] = {1.0, 3.0, 2.0, 2.0, 4.0, 1.0};
140 PetscReal clamped[NUM_FACES] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
141
142 PetscFunctionBeginUser;
143 PetscCall(PetscMemzero(&particle, sizeof(particle)));
144 PetscCall(UpdateParticleWeights(distances, &particle));
145 PetscCall(PicurvAssertRealNear(0.25, particle.weights.x, 1.0e-12, "x interpolation weight"));
146 PetscCall(PicurvAssertRealNear(0.5, particle.weights.y, 1.0e-12, "y interpolation weight"));
147 PetscCall(PicurvAssertRealNear(0.2, particle.weights.z, 1.0e-12, "z interpolation weight"));
148
149 PetscCall(UpdateParticleWeights(clamped, &particle));
150 PetscCall(PicurvAssertRealNear(0.5, particle.weights.x, 1.0e-12, "clamped x weight remains centered"));
151 PetscCall(PicurvAssertRealNear(0.5, particle.weights.y, 1.0e-12, "clamped y weight remains centered"));
152 PetscCall(PicurvAssertRealNear(0.5, particle.weights.z, 1.0e-12, "clamped z weight remains centered"));
153 PetscFunctionReturn(0);
154}
PetscErrorCode UpdateParticleWeights(PetscReal *d, Particle *particle)
Updates a particle's interpolation weights based on distances to cell faces.
PetscErrorCode PicurvAssertRealNear(PetscReal expected, PetscReal actual, PetscReal tol, const char *context)
Asserts that two real values agree within tolerance.
Cmpnts weights
Definition variables.h:213
@ NUM_FACES
Definition variables.h:173
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateParticlePositionWithoutBrownianContribution()

static PetscErrorCode TestUpdateParticlePositionWithoutBrownianContribution ( void  )
static

Tests particle position updates without Brownian forcing.

Definition at line 159 of file test_runtime_kernels.c.

160{
161 SimCtx *simCtx = NULL;
162 UserCtx *user = NULL;
163 Particle particle;
164
165 PetscFunctionBeginUser;
166 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
167 simCtx->dt = 0.25;
168
169 PetscCall(PetscMemzero(&particle, sizeof(particle)));
170 particle.loc.x = 1.0;
171 particle.loc.y = -2.0;
172 particle.loc.z = 3.0;
173 particle.vel.x = 0.5;
174 particle.vel.y = -1.0;
175 particle.vel.z = 2.0;
176 particle.diffusivitygradient.x = 0.1;
177 particle.diffusivitygradient.y = 0.2;
178 particle.diffusivitygradient.z = -0.3;
179 particle.diffusivity = 0.0;
180
181 PetscCall(UpdateParticlePosition(user, &particle));
182 PetscCall(PicurvAssertRealNear(1.15, particle.loc.x, 1.0e-12, "x position update"));
183 PetscCall(PicurvAssertRealNear(-2.2, particle.loc.y, 1.0e-12, "y position update"));
184 PetscCall(PicurvAssertRealNear(3.425, particle.loc.z, 1.0e-12, "z position update"));
185
186 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
187 PetscFunctionReturn(0);
188}
PetscErrorCode UpdateParticlePosition(UserCtx *user, Particle *particle)
Updates a particle's position based on its velocity and the timestep dt (stored in user->dt).
PetscErrorCode PicurvCreateMinimalContexts(SimCtx **simCtx_out, UserCtx **user_out, PetscInt mx, PetscInt my, PetscInt mz)
Builds minimal SimCtx and UserCtx fixtures for C unit tests.
PetscErrorCode PicurvDestroyMinimalContexts(SimCtx **simCtx_ptr, UserCtx **user_ptr)
Destroys minimal SimCtx/UserCtx fixtures and all owned PETSc objects.
Cmpnts vel
Definition variables.h:212
Cmpnts diffusivitygradient
Definition variables.h:217
PetscReal dt
Definition variables.h:874
PetscReal diffusivity
Definition variables.h:216
The master context for the entire simulation.
Definition variables.h:859
User-defined context containing data specific to a single computational grid level.
Definition variables.h:1074
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateParticlePositionDiffusivityGradientOnly()

static PetscErrorCode TestUpdateParticlePositionDiffusivityGradientOnly ( void  )
static

Tests particle position updates driven only by diffusivity-gradient drift.

Definition at line 193 of file test_runtime_kernels.c.

194{
195 SimCtx *simCtx = NULL;
196 UserCtx *user = NULL;
197 Particle particle;
198
199 PetscFunctionBeginUser;
200 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
201 simCtx->dt = 0.5;
202
203 PetscCall(PetscMemzero(&particle, sizeof(particle)));
204 particle.loc.x = 0.25;
205 particle.loc.y = 0.5;
206 particle.loc.z = 0.75;
207 particle.vel.x = 0.0;
208 particle.vel.y = 0.0;
209 particle.vel.z = 0.0;
210 particle.diffusivitygradient.x = 0.2;
211 particle.diffusivitygradient.y = -0.1;
212 particle.diffusivitygradient.z = 0.3;
213 particle.diffusivity = 0.0;
214
215 PetscCall(UpdateParticlePosition(user, &particle));
216 PetscCall(PicurvAssertRealNear(0.35, particle.loc.x, 1.0e-12, "drift-only x position update"));
217 PetscCall(PicurvAssertRealNear(0.45, particle.loc.y, 1.0e-12, "drift-only y position update"));
218 PetscCall(PicurvAssertRealNear(0.90, particle.loc.z, 1.0e-12, "drift-only z position update"));
219
220 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
221 PetscFunctionReturn(0);
222}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateParticleFieldIEMRelaxation()

static PetscErrorCode TestUpdateParticleFieldIEMRelaxation ( void  )
static

Tests IEM relaxation updates for particle-carried fields.

Definition at line 227 of file test_runtime_kernels.c.

228{
229 PetscReal psi = 1.0;
230 const PetscReal dt = 0.5;
231 const PetscReal diffusivity = 0.2;
232 const PetscReal mean_val = 3.0;
233 const PetscReal cell_vol = 8.0;
234 const PetscReal c_model = 2.0;
235 PetscReal unchanged = 7.0;
236
237 PetscFunctionBeginUser;
238 PetscCall(UpdateParticleField(PARTICLE_FIELD_ID_PSI, dt, &psi, diffusivity, mean_val, cell_vol, c_model));
239 PetscCall(PicurvAssertRealNear(
240 mean_val + (1.0 - mean_val) * PetscExpReal(-(c_model * diffusivity / PetscPowReal(cell_vol, 0.6666667)) * dt),
241 psi,
242 1.0e-12,
243 "IEM update should match analytical relaxation"));
244
245 PetscCall(UpdateParticleField(PARTICLE_FIELD_ID_VELOCITY, dt, &unchanged, diffusivity, mean_val, cell_vol, c_model));
246 PetscCall(PicurvAssertRealNear(7.0, unchanged, 1.0e-12, "unknown field should remain unchanged"));
247 PetscFunctionReturn(0);
248}
PetscErrorCode UpdateParticleField(ParticleFieldId field_id, PetscReal dt, PetscReal *psi_io, PetscReal diffusivity, PetscReal mean_val, PetscReal cell_vol, PetscReal C_model)
Updates a single particle's field based on its state and physics model.
@ PARTICLE_FIELD_ID_PSI
@ PARTICLE_FIELD_ID_VELOCITY
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldIgnoresNonUcontRequest()

static PetscErrorCode TestSetInitialInteriorFieldIgnoresNonUcontRequest ( void  )
static

Tests that non-Ucont requests do not modify interior field initialization.

Definition at line 253 of file test_runtime_kernels.c.

254{
255 SimCtx *simCtx = NULL;
256 UserCtx *user = NULL;
257
258 PetscFunctionBeginUser;
259 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
260 PetscCall(VecSet(user->Ucont, 7.0));
261
262 PetscCall(SetInitialInteriorField(user, FIELD_ID_P));
263 PetscCall(PicurvAssertVecConstant(user->Ucont, 7.0, 1.0e-12, "non-Ucont request should not modify Ucont"));
264
265 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
266 PetscFunctionReturn(0);
267}
@ FIELD_ID_P
PetscErrorCode SetInitialInteriorField(UserCtx *user, FieldId field_id)
Sets the initial values for the INTERIOR of a specified Eulerian field.
PetscErrorCode PicurvAssertVecConstant(Vec vec, PetscScalar expected, PetscReal tol, const char *context)
Asserts that a PETSc vector is spatially constant within tolerance.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux()

static PetscErrorCode TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux ( void  )
static

Tests cartesian Constant IC: Cart2Contra sets contravariant flux via metric dot product.

The minimal runtime fixture uses identity face metrics. UniformCart2Contra therefore maps (u,v,w)=(0,0,2) directly to a Zeta flux of 2.

Definition at line 274 of file test_runtime_kernels.c.

275{
276 SimCtx *simCtx = NULL;
277 UserCtx *user = NULL;
278 Cmpnts ***ucont = NULL;
279
280 PetscFunctionBeginUser;
281 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
283 simCtx->InitialConstantContra.x = 0.0;
284 simCtx->InitialConstantContra.y = 0.0;
285 simCtx->InitialConstantContra.z = 2.0;
286 PetscCall(VecSet(user->Ucont, 0.0));
287
288 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
289 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
290 PetscCall(PicurvAssertRealNear(0.0, ucont[1][1][1].x, 1.0e-10, "Xi flux is zero for pure-z velocity on Cartesian grid"));
291 PetscCall(PicurvAssertRealNear(0.0, ucont[1][1][1].y, 1.0e-10, "Eta flux is zero for pure-z velocity on Cartesian grid"));
292 PetscCall(PicurvAssertRealNear(2.0, ucont[1][1][1].z, 1.0e-10, "Zeta flux follows the identity fixture metric"));
293 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
294
295 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
296 PetscFunctionReturn(0);
297}
@ FIELD_ID_UCONT
InitialConditionMode initialConditionMode
Definition variables.h:916
@ IC_MODE_CONSTANT_CARTESIAN
Definition variables.h:179
Cmpnts InitialConstantContra
Definition variables.h:919
A 3D point or vector with PetscScalar components.
Definition variables.h:121
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection()

static PetscErrorCode TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection ( void  )
static

Tests curvilinear Constant IC: flow_direction selects the streamwise axis.

icVelocityPhysical=2.0, FLOW_DIR_POS_ZETA. The minimal runtime fixture uses identity face metrics, so ucont.z = 2.0. Xi and Eta components are left at zero regardless of InitialConstantContra.

Definition at line 306 of file test_runtime_kernels.c.

307{
308 SimCtx *simCtx = NULL;
309 UserCtx *user = NULL;
310 Cmpnts ***ucont = NULL;
311
312 PetscFunctionBeginUser;
313 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
315 simCtx->icVelocityPhysical = 2.0;
317 user->GridOrientation = 1;
318 /* InitialConstantContra intentionally non-zero to confirm only z-component is set */
319 simCtx->InitialConstantContra.x = 99.0;
320 simCtx->InitialConstantContra.y = 99.0;
321 simCtx->InitialConstantContra.z = 99.0;
322 PetscCall(VecSet(user->Ucont, 0.0));
323
324 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
325 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
326 PetscCall(PicurvAssertRealNear(0.0, ucont[1][1][1].x, 1.0e-10, "Xi flux is zero in curvilinear Zeta mode"));
327 PetscCall(PicurvAssertRealNear(0.0, ucont[1][1][1].y, 1.0e-10, "Eta flux is zero in curvilinear Zeta mode"));
328 PetscCall(PicurvAssertRealNear(2.0, ucont[1][1][1].z, 1.0e-10, "Zeta flux follows the identity fixture metric"));
329 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
330
331 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
332 PetscFunctionReturn(0);
333}
PetscReal icVelocityPhysical
Definition variables.h:921
FlowDirection flowDirection
Definition variables.h:920
@ FLOW_DIR_POS_ZETA
Definition variables.h:303
@ IC_MODE_CONSTANT_STREAMWISE
Definition variables.h:181
PetscInt GridOrientation
Definition variables.h:1092
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldZeroClearsInterior()

static PetscErrorCode TestSetInitialInteriorFieldZeroClearsInterior ( void  )
static

Tests zero IC clears physical-cell contravariant velocity.

Definition at line 338 of file test_runtime_kernels.c.

339{
340 SimCtx *simCtx = NULL;
341 UserCtx *user = NULL;
342 Cmpnts ***ucont = NULL;
343
344 PetscFunctionBeginUser;
345 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
347 PetscCall(VecSet(user->Ucont, 7.0));
348
349 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
350 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
351 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].x, 1.0e-12, "zero IC clears interior Xi flux"));
352 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].y, 1.0e-12, "zero IC clears interior Eta flux"));
353 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].z, 1.0e-12, "zero IC clears interior Zeta flux"));
354 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
355
356 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
357 PetscFunctionReturn(0);
358}
@ IC_MODE_ZERO
Definition variables.h:178
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldPoiseuilleProfile()

static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleProfile ( void  )
static

Tests Poiseuille IC is the product parabola that vanishes on the walls.

Four cells per cross-stream axis: cell centres sit at logical 0.5..3.5 with the walls at 0 and 4, so the normalized coordinate is -0.75, -0.25, 0.25, 0.75.

Definition at line 365 of file test_runtime_kernels.c.

366{
367 SimCtx *simCtx = NULL;
368 UserCtx *user = NULL;
369 Cmpnts ***ucont = NULL;
370
371 PetscFunctionBeginUser;
372 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
374 simCtx->icVelocityPhysical = 3.0;
376 user->GridOrientation = 1;
377 PetscCall(VecZeroEntries(user->Ucont));
378
379 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
380 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
381 PetscCall(PicurvAssertRealNear(3.0 * 225.0 / 256.0, ucont[2][2][2].z, 1.0e-12,
382 "Poiseuille IC follows the parabola at a centre-adjacent cell"));
383 PetscCall(PicurvAssertRealNear(3.0 * 49.0 / 256.0, ucont[2][1][1].z, 1.0e-12,
384 "Poiseuille IC vanishes on the wall, not at the first cell centre"));
385 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].x, 1.0e-12, "Poiseuille IC leaves Xi flux zero"));
386 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].y, 1.0e-12, "Poiseuille IC leaves Eta flux zero"));
387 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
388
389 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
390 PetscFunctionReturn(0);
391}
@ IC_MODE_POISEUILLE
Definition variables.h:180
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestSetInitialInteriorFieldPoiseuilleUniformAlongPeriodicAxis()

static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleUniformAlongPeriodicAxis ( void  )
static

Tests Poiseuille IC is uniform along a periodic cross-stream axis.

A channel periodic in i has walls only in j, so its start is the exact one-dimensional parabola in j.

Definition at line 398 of file test_runtime_kernels.c.

399{
400 SimCtx *simCtx = NULL;
401 UserCtx *user = NULL;
402 Cmpnts ***ucont = NULL;
403
404 PetscFunctionBeginUser;
405 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
407 simCtx->icVelocityPhysical = 3.0;
409 simCtx->i_periodic = 1;
410 user->GridOrientation = 1;
411 PetscCall(VecZeroEntries(user->Ucont));
412
413 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
414 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
415 PetscCall(PicurvAssertRealNear(3.0 * 15.0 / 16.0, ucont[2][2][1].z, 1.0e-12,
416 "periodic axis carries no parabola factor"));
417 PetscCall(PicurvAssertRealNear(ucont[2][2][1].z, ucont[2][2][3].z, 1.0e-12,
418 "profile is uniform along the periodic axis"));
419 PetscCall(PicurvAssertRealNear(3.0 * 7.0 / 16.0, ucont[2][1][2].z, 1.0e-12,
420 "wall-bounded axis keeps its parabola"));
421 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
422
423 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
424 PetscFunctionReturn(0);
425}
PetscInt i_periodic
Definition variables.h:953
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCart2ContraConvertsCartesianField()

static PetscErrorCode TestCart2ContraConvertsCartesianField ( void  )
static

Tests spatially varying Cartesian-field conversion to contravariant fluxes.

Definition at line 430 of file test_runtime_kernels.c.

431{
432 SimCtx *simCtx = NULL;
433 UserCtx *user = NULL;
434 Cmpnts ***ucat = NULL;
435 Cmpnts ***ucont = NULL;
436
437 PetscFunctionBeginUser;
438 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
439 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
440 for (PetscInt k = 0; k < 6; k++)
441 for (PetscInt j = 0; j < 6; j++)
442 for (PetscInt i = 0; i < 6; i++)
443 ucat[k][j][i] = (Cmpnts){(PetscReal)i, 2.0, 3.0};
444 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
445 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCAT));
446 PetscCall(Cart2Contra(user));
447
448 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
449 PetscCall(PicurvAssertRealNear(1.5, ucont[1][1][1].x, 1.0e-10,
450 "Xi flux uses face-interpolated Ucat"));
451 PetscCall(PicurvAssertRealNear(2.0, ucont[1][1][1].y, 1.0e-10,
452 "Eta flux uses Cartesian y velocity"));
453 PetscCall(PicurvAssertRealNear(3.0, ucont[1][1][1].z, 1.0e-10,
454 "Zeta flux uses Cartesian z velocity"));
455 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
456
457 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
458 PetscFunctionReturn(0);
459}
@ FIELD_ID_UCAT
PetscErrorCode UpdateLocalGhosts(UserCtx *user, FieldId field_id)
Updates the local vector (including ghost points) from its corresponding global vector.
Definition setup.c:2489
PetscErrorCode Cart2Contra(UserCtx *user)
Convert the ghosted Cartesian velocity field to contravariant face fluxes.
Definition setup.c:3435
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCart2ContraUsesFinalizedPeriodicUcat()

static PetscErrorCode TestCart2ContraUsesFinalizedPeriodicUcat ( void  )
static

Verifies periodic Ucat endpoints are repaired before Cart2Contra terminal faces.

Definition at line 462 of file test_runtime_kernels.c.

463{
464 SimCtx *simCtx=NULL; UserCtx *user=NULL; Cmpnts ***ucat=NULL,***ucont=NULL; PetscInt mx;
465 const FieldId cell_fields[] = {FIELD_ID_UCAT}, staggered_fields[] = {FIELD_ID_UCONT};
466 PetscFunctionBeginUser;
467 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(&simCtx,&user,4,4,4,PETSC_TRUE,PETSC_FALSE,PETSC_FALSE));
470 mx=user->info.mx;
471 PetscCall(VecSet(user->Ucat,0.0));
472 PetscCall(DMDAVecGetArray(user->fda,user->Ucat,&ucat));
473 for(PetscInt k=1;k<user->info.mz-1;k++) for(PetscInt j=1;j<user->info.my-1;j++)
474 for(PetscInt i=1;i<mx-1;i++) ucat[k][j][i]=(Cmpnts){10.0+(PetscReal)i,2.0,3.0};
475 ucat[2][2][0]=(Cmpnts){-1000.0,-1000.0,-1000.0};
476 ucat[2][2][mx-1]=(Cmpnts){-2000.0,-2000.0,-2000.0};
477 PetscCall(DMDAVecRestoreArray(user->fda,user->Ucat,&ucat));
478 PetscCall(SynchronizePeriodicCellFields(user,1,cell_fields));
479 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCAT));
480 PetscCall(Cart2Contra(user));
481 PetscCall(SynchronizePeriodicStaggeredFields(user,1,staggered_fields));
482 PetscCall(DMDAVecGetArrayRead(user->fda,user->Ucont,&ucont));
483 PetscCall(PicurvAssertRealNear(0.5*((10.0+mx-2)+(10.0+1)),ucont[2][2][mx-2].x,1e-12,"terminal Xi face uses corrected periodic Ucat endpoint"));
484 PetscCall(DMDAVecRestoreArrayRead(user->fda,user->Ucont,&ucont));
485 PetscCall(PicurvDestroyMinimalContexts(&simCtx,&user));
486 PetscFunctionReturn(0);
487}
PetscErrorCode SynchronizePeriodicStaggeredFields(UserCtx *user, PetscInt num_fields, const FieldId field_ids[])
Synchronizes persistent component-staggered vector fields.
PetscErrorCode SynchronizePeriodicCellFields(UserCtx *user, PetscInt num_fields, const FieldId field_ids[])
Synchronizes periodic endpoint cells for a list of cell-centered fields.
FieldId
Compile-time identity for a catalogued Eulerian field.
PetscErrorCode PicurvCreateMinimalContextsWithPeriodicity(SimCtx **simCtx_out, UserCtx **user_out, PetscInt mx, PetscInt my, PetscInt mz, PetscBool x_periodic, PetscBool y_periodic, PetscBool z_periodic)
Builds minimal SimCtx and UserCtx fixtures for C unit tests with configurable periodicity.
@ PERIODIC
Definition variables.h:318
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:1099
DMDALocalInfo info
Definition variables.h:1086
BCType mathematical_type
Definition variables.h:392
@ BC_FACE_NEG_X
Definition variables.h:288
@ BC_FACE_POS_X
Definition variables.h:288
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestPopulateInitialUcontLoadsStagedUcat()

static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcat ( void  )
static

Tests loading a staged Ucat file IC and converting it to Ucont.

Definition at line 492 of file test_runtime_kernels.c.

493{
494 SimCtx *simCtx = NULL;
495 UserCtx *user = NULL;
496 Cmpnts ***ucont = NULL;
497 char tmpdir[PETSC_MAX_PATH_LEN];
498
499 PetscFunctionBeginUser;
500 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
501 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
502 PetscCall(VecSet(user->Ucat, 2.5));
503 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
505 PetscCall(WriteFieldData(user, "ufield00000_0", user->Ucat, "dat"));
506 simCtx->current_io_directory = NULL;
507
508 PetscCall(VecZeroEntries(user->Ucat));
509 PetscCall(VecZeroEntries(user->Ucont));
512 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
513 PetscCall(PopulateInitialUcont(user));
514
515 PetscCall(PicurvAssertVecConstant(user->Ucat, 2.5, 1.0e-12, "file IC should restore Ucat"));
516 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
517 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].x, 1.0e-12, "file Ucat IC should populate interior Xi flux"));
518 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].y, 1.0e-12, "file Ucat IC should populate interior Eta flux"));
519 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].z, 1.0e-12, "file Ucat IC should populate interior Zeta flux"));
520 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
521 PetscCall(PicurvRemoveTempDir(tmpdir));
522 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
523 PetscFunctionReturn(0);
524}
PetscErrorCode PopulateInitialUcont(UserCtx *user)
Populate Ucont for one fresh-start block from the configured IC mode.
PetscErrorCode WriteFieldData(UserCtx *user, const char *field_name, Vec field_vec, const char *ext)
Writes data from a specific PETSc vector to a file.
Definition io.c:1966
PetscErrorCode PicurvMakeTempDir(char *path, size_t path_len)
Creates a unique temporary directory for one test case.
PetscErrorCode PicurvRemoveTempDir(const char *path)
Recursively removes a temporary directory created by PicurvMakeTempDir.
char * current_io_directory
Definition variables.h:885
char initialConditionDirectory[PETSC_MAX_PATH_LEN]
Definition variables.h:918
@ IC_MODE_FILE
Definition variables.h:182
@ IC_FIELD_UCAT
Definition variables.h:187
char _io_context_buffer[PETSC_MAX_PATH_LEN]
Definition variables.h:884
InitialConditionField initialConditionField
Definition variables.h:917
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestWriteLESFieldsCopiesOwnedPeriodicValues()

static PetscErrorCode TestWriteLESFieldsCopiesOwnedPeriodicValues ( void  )
static

Tests LES output staging from local vectors on a multiply periodic DMDA.

Definition at line 527 of file test_runtime_kernels.c.

528{
529 SimCtx *simCtx = NULL;
530 UserCtx *user = NULL;
531 char tmpdir[PETSC_MAX_PATH_LEN];
532 char euler_dir[PETSC_MAX_PATH_LEN];
533 char block_dir[PETSC_MAX_PATH_LEN];
534
535 PetscFunctionBeginUser;
537 &simCtx, &user, 4, 4, 4, PETSC_TRUE, PETSC_TRUE, PETSC_TRUE));
538 PetscCall(DMCreateGlobalVector(user->da, &user->CS));
539 PetscCall(DMCreateLocalVector(user->da, &user->lCs));
540 PetscCall(DMCreateGlobalVector(user->da, &user->Nu_t));
541 PetscCall(DMCreateLocalVector(user->da, &user->lNu_t));
542 PetscCall(VecSet(user->CS, 0.0));
543 PetscCall(VecSet(user->lCs, 2.5));
544 PetscCall(VecSet(user->Nu_t, 0.0));
545 PetscCall(VecSet(user->lNu_t, 7.5));
546 simCtx->les = DYNAMIC_SMAGORINSKY;
547
548 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
549 PetscCall(PetscSNPrintf(euler_dir, sizeof(euler_dir), "%s/eulerian", tmpdir));
550 PetscCall(PetscSNPrintf(block_dir, sizeof(block_dir), "%s/block_0000", euler_dir));
551 PetscCall(PicurvEnsureDir(euler_dir));
552 PetscCall(PicurvEnsureDir(block_dir));
553 PetscCall(WriteSimulationFields(user, tmpdir));
554
555 PetscCall(PicurvAssertVecConstant(user->CS, 2.5, 1.0e-12,
556 "checkpoint output should copy owned periodic lCs values"));
557 PetscCall(PicurvAssertVecConstant(user->Nu_t, 7.5, 1.0e-12,
558 "checkpoint output should copy owned periodic lNu_t values"));
559
560 PetscCall(PicurvRemoveTempDir(tmpdir));
561 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
562 PetscFunctionReturn(0);
563}
PetscErrorCode WriteSimulationFields(UserCtx *user, const char *checkpoint_directory)
Writes simulation fields to files.
Definition io.c:2021
PetscErrorCode PicurvEnsureDir(const char *path)
Ensures a directory exists for test output.
@ DYNAMIC_SMAGORINSKY
Definition variables.h:551
Vec lNu_t
Definition variables.h:1156
PetscInt les
Active LES closure; an LESModelType value.
Definition variables.h:984
Here is the call graph for this function:
Here is the caller graph for this function:

◆ StagedFourierModeMaxDivergence()

static PetscErrorCode StagedFourierModeMaxDivergence ( UserCtx *  user,
PetscInt  mode_x,
PetscInt  mode_y,
PetscInt  mode_z,
Cmpnts  amplitude,
const char *  tmpdir,
PetscReal *  max_divergence 
)
static

Stages a real Cartesian Fourier mode through the production file-IC path.

The returned maximum is the native face-interpolation/backward-difference divergence. On the uniform periodic fixture its symbol is (sin(theta_x), sin(theta_y), sin(theta_z)).

Definition at line 572 of file test_runtime_kernels.c.

579{
580 SimCtx *simCtx = user->simCtx;
581 Cmpnts ***ucat = NULL, ***ucont = NULL;
582 PetscInt n_x = user->info.mx - 2, n_y = user->info.my - 2, n_z = user->info.mz - 2;
583 const FieldId staggered_fields[] = {FIELD_ID_UCONT};
584
585 PetscFunctionBeginUser;
586 PetscCall(VecZeroEntries(user->Ucat));
587 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
588 for (PetscInt k = 0; k < user->info.mz; ++k) {
589 for (PetscInt j = 0; j < user->info.my; ++j) {
590 for (PetscInt i = 0; i < user->info.mx; ++i) {
591 PetscReal phase = 2.0 * PETSC_PI * (
592 (PetscReal)(mode_x * (i - 1)) / (PetscReal)n_x +
593 (PetscReal)(mode_y * (j - 1)) / (PetscReal)n_y +
594 (PetscReal)(mode_z * (k - 1)) / (PetscReal)n_z);
595 PetscReal wave = PetscCosReal(phase);
596 ucat[k][j][i] = (Cmpnts){amplitude.x * wave, amplitude.y * wave, amplitude.z * wave};
597 }
598 }
599 }
600 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
601
602 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
604 PetscCall(WriteFieldData(user, "ufield00000_0", user->Ucat, "dat"));
605 simCtx->current_io_directory = NULL;
606 PetscCall(VecZeroEntries(user->Ucat));
607 PetscCall(VecZeroEntries(user->Ucont));
608 PetscCall(PopulateInitialUcont(user));
609 PetscCall(SynchronizePeriodicStaggeredFields(user, 1, staggered_fields));
610 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCONT));
611
612 *max_divergence = 0.0;
613 PetscCall(DMDAVecGetArrayRead(user->fda, user->lUcont, &ucont));
614 for (PetscInt k = 1; k < user->info.mz - 1; ++k) {
615 for (PetscInt j = 1; j < user->info.my - 1; ++j) {
616 for (PetscInt i = 1; i < user->info.mx - 1; ++i) {
617 PetscReal divergence =
618 ucont[k][j][i].x - ucont[k][j][i - 1].x +
619 ucont[k][j][i].y - ucont[k][j - 1][i].y +
620 ucont[k][j][i].z - ucont[k - 1][j][i].z;
621 *max_divergence = PetscMax(*max_divergence, PetscAbsReal(divergence));
622 }
623 }
624 }
625 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->lUcont, &ucont));
626 PetscFunctionReturn(0);
627}
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:1077
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestStagedUcatFourierModesUsePicurvDiscreteSymbol()

static PetscErrorCode TestStagedUcatFourierModesUsePicurvDiscreteSymbol ( void  )
static

Cross-checks selected exact Fourier modes against PICurv's native discrete symbol.

Definition at line 630 of file test_runtime_kernels.c.

631{
632 SimCtx *simCtx = NULL;
633 UserCtx *user = NULL;
634 char tmpdir[PETSC_MAX_PATH_LEN];
635 PetscReal max_divergence = 0.0, sx, sy, sz;
636 PetscInt n;
637
638 PetscFunctionBeginUser;
640 &simCtx, &user, 9, 9, 9, PETSC_TRUE, PETSC_TRUE, PETSC_TRUE));
641 for (PetscInt face = 0; face < NUM_FACES; ++face)
643 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
646 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
647
649 user, 1, 0, 0, (Cmpnts){0.0, 1.0, 0.0}, tmpdir, &max_divergence));
650 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
651 "axis-aligned transverse staged mode"));
652
653 n = user->info.mx - 2;
654 sx = PetscSinReal(2.0 * PETSC_PI / (PetscReal)n);
655 sy = PetscSinReal(4.0 * PETSC_PI / (PetscReal)n);
656 sz = PetscSinReal(6.0 * PETSC_PI / (PetscReal)n);
658 user, 1, 2, 0, (Cmpnts){sy, -sx, 0.0}, tmpdir, &max_divergence));
659 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
660 "oblique first discrete transverse polarization"));
662 user, 1, 2, 3,
663 (Cmpnts){sz * sx, sz * sy, -(sx * sx + sy * sy)},
664 tmpdir, &max_divergence));
665 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
666 "oblique second discrete transverse polarization"));
667
668 PetscCall(PicurvRemoveTempDir(tmpdir));
669 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
670 PetscFunctionReturn(0);
671}
static PetscErrorCode StagedFourierModeMaxDivergence(UserCtx *user, PetscInt mode_x, PetscInt mode_y, PetscInt mode_z, Cmpnts amplitude, const char *tmpdir, PetscReal *max_divergence)
Stages a real Cartesian Fourier mode through the production file-IC path.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestPopulateInitialUcontLoadsStagedUcont()

static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcont ( void  )
static

Tests loading a staged Ucont file IC without Cartesian conversion.

Definition at line 676 of file test_runtime_kernels.c.

677{
678 SimCtx *simCtx = NULL;
679 UserCtx *user = NULL;
680 char tmpdir[PETSC_MAX_PATH_LEN];
681
682 PetscFunctionBeginUser;
683 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
684 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
685 PetscCall(VecSet(user->Ucont, 4.5));
686 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
688 PetscCall(WriteFieldData(user, "vfield00000_0", user->Ucont, "dat"));
689 simCtx->current_io_directory = NULL;
690
691 PetscCall(VecZeroEntries(user->Ucont));
694 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
695 PetscCall(PopulateInitialUcont(user));
696
697 PetscCall(PicurvAssertVecConstant(user->Ucont, 4.5, 1.0e-12, "file Ucont IC should restore Ucont directly"));
698 PetscCall(PicurvRemoveTempDir(tmpdir));
699 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
700 PetscFunctionReturn(0);
701}
@ IC_FIELD_UCONT
Definition variables.h:188
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestInterpolateAllFieldsToSwarmConstantFields()

static PetscErrorCode TestInterpolateAllFieldsToSwarmConstantFields ( void  )
static

Tests direct interpolation from Eulerian fields to one localized swarm particle.

Definition at line 706 of file test_runtime_kernels.c.

707{
708 SimCtx *simCtx = NULL;
709 UserCtx *user = NULL;
710 Cmpnts ***grad = NULL;
711 PetscReal *velocity = NULL;
712 PetscReal *diffusivity = NULL;
713 PetscReal *diffusivity_gradient = NULL;
714
715 PetscFunctionBeginUser;
716 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
717 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
718 PetscCall(VecSet(user->Ucat, 2.0));
719 PetscCall(VecSet(user->Diffusivity, 0.25));
720
721 PetscCall(DMDAVecGetArray(user->fda, user->DiffusivityGradient, &grad));
722 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
723 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
724 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
725 grad[k][j][i].x = 0.1;
726 grad[k][j][i].y = 0.2;
727 grad[k][j][i].z = 0.3;
728 }
729 }
730 }
731 PetscCall(DMDAVecRestoreArray(user->fda, user->DiffusivityGradient, &grad));
732 PetscCall(SyncRuntimeFieldGhosts(user));
733 PetscCall(SeedSingleParticle(user, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ACTIVE_AND_LOCATED));
734
735 PetscCall(InterpolateAllFieldsToSwarm(user));
736
737 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
738 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
739 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
740 PetscCall(PicurvAssertRealNear(2.0, velocity[0], 1.0e-12, "Interpolated velocity x should match constant Eulerian field"));
741 PetscCall(PicurvAssertRealNear(2.0, velocity[1], 1.0e-12, "Interpolated velocity y should match constant Eulerian field"));
742 PetscCall(PicurvAssertRealNear(2.0, velocity[2], 1.0e-12, "Interpolated velocity z should match constant Eulerian field"));
743 PetscCall(PicurvAssertRealNear(0.25, diffusivity[0], 1.0e-12, "Interpolated scalar diffusivity should match constant Eulerian field"));
744 PetscCall(PicurvAssertRealNear(0.1, diffusivity_gradient[0], 1.0e-12, "Interpolated diffusivity-gradient x component"));
745 PetscCall(PicurvAssertRealNear(0.2, diffusivity_gradient[1], 1.0e-12, "Interpolated diffusivity-gradient y component"));
746 PetscCall(PicurvAssertRealNear(0.3, diffusivity_gradient[2], 1.0e-12, "Interpolated diffusivity-gradient z component"));
747 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
748 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
749 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
750
751 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
752 PetscFunctionReturn(0);
753}
PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
static PetscErrorCode SyncRuntimeFieldGhosts(UserCtx *user)
Synchronizes the minimal runtime fixture's global fields into their persistent local ghosts.
static PetscErrorCode SeedSingleParticle(UserCtx *user, PetscInt ci, PetscInt cj, PetscInt ck, PetscReal x, PetscReal y, PetscReal z, PetscReal wx, PetscReal wy, PetscReal wz, PetscInt status_value)
Seeds one localized swarm particle with the cell, position, weight, and status data used by runtime t...
PetscErrorCode PicurvCreateSwarmPair(UserCtx *user, PetscInt nlocal, const char *post_field_name)
Creates matched solver and post-processing swarms for tests.
@ ACTIVE_AND_LOCATED
Definition variables.h:165
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields()

static PetscErrorCode TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields ( void  )
static

Tests the corner-averaged (legacy) interpolation path on constant fields.

Definition at line 758 of file test_runtime_kernels.c.

759{
760 SimCtx *simCtx = NULL;
761 UserCtx *user = NULL;
762 Cmpnts ***grad = NULL;
763 PetscReal *velocity = NULL;
764 PetscReal *diffusivity = NULL;
765 PetscReal *diffusivity_gradient = NULL;
766
767 PetscFunctionBeginUser;
768 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
770 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
771 PetscCall(VecSet(user->Ucat, 2.0));
772 PetscCall(VecSet(user->Diffusivity, 0.25));
773
774 PetscCall(DMDAVecGetArray(user->fda, user->DiffusivityGradient, &grad));
775 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
776 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
777 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
778 grad[k][j][i].x = 0.1;
779 grad[k][j][i].y = 0.2;
780 grad[k][j][i].z = 0.3;
781 }
782 }
783 }
784 PetscCall(DMDAVecRestoreArray(user->fda, user->DiffusivityGradient, &grad));
785 PetscCall(SyncRuntimeFieldGhosts(user));
786 PetscCall(SeedSingleParticle(user, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ACTIVE_AND_LOCATED));
787
788 PetscCall(InterpolateAllFieldsToSwarm(user));
789
790 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
791 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
792 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
793 PetscCall(PicurvAssertRealNear(2.0, velocity[0], 1.0e-12, "CornerAveraged: interpolated velocity x should match constant Eulerian field"));
794 PetscCall(PicurvAssertRealNear(2.0, velocity[1], 1.0e-12, "CornerAveraged: interpolated velocity y should match constant Eulerian field"));
795 PetscCall(PicurvAssertRealNear(2.0, velocity[2], 1.0e-12, "CornerAveraged: interpolated velocity z should match constant Eulerian field"));
796 PetscCall(PicurvAssertRealNear(0.25, diffusivity[0], 1.0e-12, "CornerAveraged: interpolated scalar diffusivity should match constant Eulerian field"));
797 PetscCall(PicurvAssertRealNear(0.1, diffusivity_gradient[0], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient x component"));
798 PetscCall(PicurvAssertRealNear(0.2, diffusivity_gradient[1], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient y component"));
799 PetscCall(PicurvAssertRealNear(0.3, diffusivity_gradient[2], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient z component"));
800 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
801 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
802 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
803
804 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
805 PetscFunctionReturn(0);
806}
InterpolationMethod interpolationMethod
Definition variables.h:995
@ INTERP_CORNER_AVERAGED
Definition variables.h:724
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestScatterAllParticleFieldsToEulerFieldsAveragesPsi()

static PetscErrorCode TestScatterAllParticleFieldsToEulerFieldsAveragesPsi ( void  )
static

Tests particle-to-grid scattering using known cell occupancy and scalar values.

Definition at line 811 of file test_runtime_kernels.c.

812{
813 SimCtx *simCtx = NULL;
814 UserCtx *user = NULL;
815 PetscInt *cell_ids = NULL;
816 PetscReal *psi = NULL;
817 PetscReal ***psi_grid = NULL;
818
819 PetscFunctionBeginUser;
820 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
821 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
822
823 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
824 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
825 cell_ids[3] = 0; cell_ids[4] = 0; cell_ids[5] = 0;
826 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
827
828 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
829 psi[0] = 1.0;
830 psi[1] = 3.0;
831 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
832
834
835 PetscCall(DMDAVecGetArrayRead(user->da, user->Psi, &psi_grid));
836 PetscCall(PicurvAssertRealNear(2.0, psi_grid[1][1][1], 1.0e-12, "Scatter should average particle Psi values into the owning cell"));
837 PetscCall(DMDAVecRestoreArrayRead(user->da, user->Psi, &psi_grid));
838
839 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
840 PetscFunctionReturn(0);
841}
PetscErrorCode ScatterAllParticleFieldsToEulerFields(UserCtx *user)
Scatters a predefined set of particle fields to their corresponding Eulerian fields.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCalculateParticleCountPerCellCountsGlobalCellIDs()

static PetscErrorCode TestCalculateParticleCountPerCellCountsGlobalCellIDs ( void  )
static

Tests particle counting by geometric cell IDs using the production +1 storage shift.

Definition at line 846 of file test_runtime_kernels.c.

847{
848 SimCtx *simCtx = NULL;
849 UserCtx *user = NULL;
850 PetscInt *cell_ids = NULL;
851 PetscReal ***counts = NULL;
852
853 PetscFunctionBeginUser;
854 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
855 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
856
857 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
858 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
859 cell_ids[3] = 0; cell_ids[4] = 0; cell_ids[5] = 0;
860 cell_ids[6] = 1; cell_ids[7] = 0; cell_ids[8] = 0;
861 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
862
863 PetscCall(CalculateParticleCountPerCell(user));
864
865 PetscCall(DMDAVecGetArrayRead(user->da, user->ParticleCount, &counts));
866 PetscCall(PicurvAssertRealNear(2.0, counts[1][1][1], 1.0e-12, "Two particles in cell (0,0,0) should accumulate at shifted index (1,1,1)"));
867 PetscCall(PicurvAssertRealNear(1.0, counts[1][1][2], 1.0e-12, "One particle in cell (1,0,0) should accumulate at shifted index (2,1,1)"));
868 PetscCall(DMDAVecRestoreArrayRead(user->da, user->ParticleCount, &counts));
869
870 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
871 PetscFunctionReturn(0);
872}
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:1171
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestResetAllParticleStatusesLeavesLostParticlesUntouched()

static PetscErrorCode TestResetAllParticleStatusesLeavesLostParticlesUntouched ( void  )
static

Tests localized particle-status reset behavior for restart of the location workflow.

Definition at line 877 of file test_runtime_kernels.c.

878{
879 SimCtx *simCtx = NULL;
880 UserCtx *user = NULL;
881 PetscInt *status = NULL;
882
883 PetscFunctionBeginUser;
884 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
885 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
886
887 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
888 status[0] = ACTIVE_AND_LOCATED;
889 status[1] = LOST;
890 status[2] = NEEDS_LOCATION;
891 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
892
893 PetscCall(ResetAllParticleStatuses(user));
894
895 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
896 PetscCall(PicurvAssertIntEqual(NEEDS_LOCATION, status[0], "ACTIVE_AND_LOCATED particles should be reset to NEEDS_LOCATION"));
897 PetscCall(PicurvAssertIntEqual(LOST, status[1], "LOST particles should remain LOST"));
898 PetscCall(PicurvAssertIntEqual(NEEDS_LOCATION, status[2], "NEEDS_LOCATION particles should remain unchanged"));
899 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
900
901 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
902 PetscFunctionReturn(0);
903}
PetscErrorCode ResetAllParticleStatuses(UserCtx *user)
Marks all local particles as NEEDS_LOCATION for the next settlement pass.
@ LOST
Definition variables.h:167
@ NEEDS_LOCATION
Definition variables.h:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle()

static PetscErrorCode TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle ( void  )
static

Tests direct removal of particles that leave every rank bounding box.

Definition at line 908 of file test_runtime_kernels.c.

909{
910 SimCtx *simCtx = NULL;
911 UserCtx *user = NULL;
912 PetscReal *positions = NULL;
913 PetscInt removed_local = 0;
914 PetscInt removed_global = 0;
915 PetscInt nlocal = 0;
916
917 PetscFunctionBeginUser;
918 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
919 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
920
921 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
922 positions[0] = 0.5; positions[1] = 0.5; positions[2] = 0.5;
923 positions[3] = 9.0; positions[4] = 9.0; positions[5] = 9.0;
924 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
925
926 PetscCall(CheckAndRemoveOutOfBoundsParticles(user, &removed_local, &removed_global, simCtx->bboxlist));
927 PetscCall(DMSwarmGetLocalSize(user->swarm, &nlocal));
928 PetscCall(PicurvAssertIntEqual(1, removed_local, "Exactly one particle should be removed as out-of-bounds on a single rank"));
929 PetscCall(PicurvAssertIntEqual(1, removed_global, "Global out-of-bounds removal count should match the local single-rank result"));
930 PetscCall(PicurvAssertIntEqual(1, nlocal, "One in-bounds particle should remain after out-of-bounds removal"));
931
932 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
933 PetscFunctionReturn(0);
934}
PetscErrorCode CheckAndRemoveOutOfBoundsParticles(UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal, const BoundingBox *bboxlist)
Checks for particles outside the physical domain boundaries and removes them using DMSwarmRemovePoint...
BoundingBox * bboxlist
Definition variables.h:993
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCheckAndRemoveLostParticlesRemovesLostEntries()

static PetscErrorCode TestCheckAndRemoveLostParticlesRemovesLostEntries ( void  )
static

Tests direct removal of particles already marked LOST by the location workflow.

Definition at line 939 of file test_runtime_kernels.c.

940{
941 SimCtx *simCtx = NULL;
942 UserCtx *user = NULL;
943 PetscInt *status = NULL;
944 PetscInt removed_local = 0;
945 PetscInt removed_global = 0;
946 PetscInt nlocal = 0;
947 PetscReal *psi = NULL;
948 PetscReal removed_psi = 0.0;
949
950 PetscFunctionBeginUser;
951 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
952 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
953 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
954 psi[0] = 0.5;
955 psi[1] = 2.0;
956 psi[2] = 3.0;
957 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
958
959 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
960 status[0] = ACTIVE_AND_LOCATED;
961 status[1] = LOST;
962 status[2] = LOST;
963 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
964
965 PetscCall(CheckAndRemoveLostParticles(user, &removed_local, &removed_global, &removed_psi));
966 PetscCall(DMSwarmGetLocalSize(user->swarm, &nlocal));
967 PetscCall(PicurvAssertRealNear(5.0, removed_psi, 0.0, "the removed particles carried Psi 2 and 3"));
968 PetscCall(PicurvAssertIntEqual(2, removed_local, "Two LOST particles should be removed locally"));
969 PetscCall(PicurvAssertIntEqual(2, removed_global, "Global LOST-particle removal count should match the local single-rank result"));
970 PetscCall(PicurvAssertIntEqual(1, nlocal, "One non-LOST particle should remain"));
971
972 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
973 PetscFunctionReturn(0);
974}
PetscErrorCode CheckAndRemoveLostParticles(UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal, PetscReal *removedScalarSumGlobal)
Removes particles that have been definitively flagged as LOST by the location algorithm.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCalculateBrownianDisplacementDeterministicSeed()

static PetscErrorCode TestCalculateBrownianDisplacementDeterministicSeed ( void  )
static

Tests Brownian displacement generation against a duplicated seeded RNG stream.

Definition at line 979 of file test_runtime_kernels.c.

980{
981 SimCtx *simCtx = NULL;
982 UserCtx *user = NULL;
983 char tmpdir[PETSC_MAX_PATH_LEN];
984 Cmpnts first;
985 Cmpnts second;
986
987 PetscFunctionBeginUser;
988 PetscCall(PicurvBuildTinyRuntimeContext(NULL, PETSC_FALSE, &simCtx, &user, tmpdir, sizeof(tmpdir)));
989 simCtx->dt = 0.25;
990 PetscCall(PicurvAssertBool((PetscBool)(simCtx->BrownianMotionRNG != NULL),
991 "runtime setup path should initialize the Brownian RNG"));
992
993 PetscCall(PetscRandomSetSeed(simCtx->BrownianMotionRNG, 12345));
994 PetscCall(PetscRandomSeed(simCtx->BrownianMotionRNG));
995
996 PetscCall(CalculateBrownianDisplacement(user, 0.5, &first));
997 PetscCall(PetscRandomSetSeed(simCtx->BrownianMotionRNG, 12345));
998 PetscCall(PetscRandomSeed(simCtx->BrownianMotionRNG));
999 PetscCall(CalculateBrownianDisplacement(user, 0.5, &second));
1000
1001 PetscCall(PicurvAssertRealNear(first.x, second.x, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the x displacement"));
1002 PetscCall(PicurvAssertRealNear(first.y, second.y, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the y displacement"));
1003 PetscCall(PicurvAssertRealNear(first.z, second.z, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the z displacement"));
1004
1005 PetscCall(PicurvDestroyRuntimeContext(&simCtx));
1006 PetscCall(PicurvRemoveTempDir(tmpdir));
1007 PetscFunctionReturn(0);
1008}
PetscErrorCode CalculateBrownianDisplacement(UserCtx *user, PetscReal diff_eff, Cmpnts *displacement)
Calculates the stochastic displacement vector (Brownian motion) for a single particle.
PetscErrorCode PicurvDestroyRuntimeContext(SimCtx **simCtx_ptr)
Finalizes and frees a runtime context built by PicurvBuildTinyRuntimeContext.
PetscErrorCode PicurvBuildTinyRuntimeContext(const char *bcs_contents, PetscBool enable_particles, SimCtx **simCtx_out, UserCtx **user_out, char *tmpdir, size_t tmpdir_len)
Builds a tiny runtime context through the real setup path for behavior-level tests.
PetscRandom BrownianMotionRNG
Definition variables.h:1006
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateAllParticlePositionsMovesSwarmEntries()

static PetscErrorCode TestUpdateAllParticlePositionsMovesSwarmEntries ( void  )
static

Tests swarm-wide particle position updates using the same transport path as the runtime loop.

Definition at line 1012 of file test_runtime_kernels.c.

1013{
1014 SimCtx *simCtx = NULL;
1015 UserCtx *user = NULL;
1016 PetscReal *positions = NULL;
1017 PetscReal *velocities = NULL;
1018 PetscReal *diffusivity = NULL;
1019 Cmpnts *diffusivity_gradient = NULL;
1020 PetscReal *psi = NULL;
1021 PetscReal *weights = NULL;
1022 PetscInt *cell_ids = NULL;
1023 PetscInt *status = NULL;
1024 PetscInt64 *pid = NULL;
1025
1026 PetscFunctionBeginUser;
1027 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1028 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
1029 simCtx->dt = 0.25;
1030
1031 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1032 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocities));
1033 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
1034 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
1035 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
1036 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1037 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1038 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1039 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1040
1041 positions[0] = 0.20; positions[1] = 0.30; positions[2] = 0.40;
1042 velocities[0] = 0.40; velocities[1] = -0.20; velocities[2] = 0.10;
1043 diffusivity[0] = 0.0;
1044 diffusivity_gradient[0].x = 0.10;
1045 diffusivity_gradient[0].y = 0.20;
1046 diffusivity_gradient[0].z = -0.10;
1047 psi[0] = 0.5;
1048 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1049 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
1050 status[0] = ACTIVE_AND_LOCATED;
1051 pid[0] = 7;
1052
1053 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1054 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1055 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1056 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1057 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
1058 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
1059 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
1060 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocities));
1061 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1062
1063 PetscCall(UpdateAllParticlePositions(user));
1064
1065 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1066 PetscCall(PicurvAssertRealNear(0.325, positions[0], 1.0e-12, "UpdateAllParticlePositions should advect x"));
1067 PetscCall(PicurvAssertRealNear(0.300, positions[1], 1.0e-12, "UpdateAllParticlePositions should advect y"));
1068 PetscCall(PicurvAssertRealNear(0.400, positions[2], 1.0e-12, "UpdateAllParticlePositions should advect z"));
1069 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1070
1071 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1072 PetscFunctionReturn(0);
1073}
PetscErrorCode UpdateAllParticlePositions(UserCtx *user)
Loops over all local particles in the DMSwarm, updating their positions based on velocity and the glo...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestLocateAllParticlesInGridPriorCellFastPath()

static PetscErrorCode TestLocateAllParticlesInGridPriorCellFastPath ( void  )
static

Tests the location orchestrator fast path when a particle already carries a valid prior cell.

Definition at line 1077 of file test_runtime_kernels.c.

1078{
1079 SimCtx *simCtx = NULL;
1080 UserCtx *user = NULL;
1081 PetscReal *positions = NULL;
1082 PetscReal *weights = NULL;
1083 PetscInt *cell_ids = NULL;
1084 PetscInt *status = NULL;
1085 PetscInt64 *pid = NULL;
1086
1087 PetscFunctionBeginUser;
1088 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1089 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1090 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1091 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1092 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1093 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
1094
1095 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1096 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1097 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1098 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1099 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1100 positions[0] = 0.375; positions[1] = 0.375; positions[2] = 0.375;
1101 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1102 cell_ids[0] = 1; cell_ids[1] = 1; cell_ids[2] = 1;
1103 status[0] = NEEDS_LOCATION;
1104 pid[0] = 11;
1105 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1106 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1107 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1108 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1109 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1110
1111 PetscCall(LocateAllParticlesInGrid(user, simCtx->bboxlist));
1112
1113 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1114 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1115 PetscCall(PicurvAssertIntEqual(1, cell_ids[0], "prior-cell fast path should preserve the i cell id"));
1116 PetscCall(PicurvAssertIntEqual(1, cell_ids[1], "prior-cell fast path should preserve the j cell id"));
1117 PetscCall(PicurvAssertIntEqual(1, cell_ids[2], "prior-cell fast path should preserve the k cell id"));
1118 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status[0], "prior-cell fast path should mark the particle ACTIVE_AND_LOCATED"));
1119 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.searchAttempts, "prior-cell fast path should record one search attempt"));
1120 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchPopulation, "prior-cell fast path should record one input particle"));
1121 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchLocatedCount, "prior-cell fast path should count one located particle"));
1122 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.searchLostCount, "prior-cell fast path should not lose the particle"));
1123 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.reSearchCount, "prior-cell fast path should not re-search on later passes"));
1124 PetscCall(PicurvAssertBool((PetscBool)(simCtx->searchMetrics.traversalStepsSum > 0), "prior-cell fast path should accumulate traversal steps"));
1125 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.maxParticlePassDepth, "prior-cell fast path should report one settlement pass"));
1126 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1127 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1128
1129 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1130 PetscFunctionReturn(0);
1131}
PetscErrorCode LocateAllParticlesInGrid(UserCtx *user, BoundingBox *bboxlist)
Orchestrates the complete particle location and migration process for one timestep.
PetscErrorCode GetOwnedCellRange(const DMDALocalInfo *info_nodes, PetscInt dim, PetscInt *xs_cell_global_out, PetscInt *xm_cell_local_out)
Determines the global starting index and number of CELLS owned by the current processor in a specifie...
Definition setup.c:2936
PetscInt ys_cell
Definition variables.h:230
PetscInt xs_cell
Definition variables.h:230
PetscInt64 searchLocatedCount
Definition variables.h:267
PetscInt64 searchLostCount
Definition variables.h:268
PetscInt64 traversalStepsSum
Definition variables.h:269
PetscInt zm_cell
Definition variables.h:231
PetscInt zs_cell
Definition variables.h:230
PetscInt64 searchPopulation
Definition variables.h:266
PetscInt64 reSearchCount
Definition variables.h:270
PetscInt xm_cell
Definition variables.h:231
RankCellInfo * RankCellInfoMap
Definition variables.h:1170
PetscInt ym_cell
Definition variables.h:231
PetscInt64 maxParticlePassDepth
Definition variables.h:277
SearchMetricsState searchMetrics
Definition variables.h:1005
PetscMPIInt size
Definition variables.h:863
PetscInt64 searchAttempts
Definition variables.h:265
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestLocateAllParticlesInGridGuessPathResolvesLocalParticle()

static PetscErrorCode TestLocateAllParticlesInGridGuessPathResolvesLocalParticle ( void  )
static

Tests the guess-then-verify orchestrator path for a local particle with an unknown prior cell.

Definition at line 1135 of file test_runtime_kernels.c.

1136{
1137 SimCtx *simCtx = NULL;
1138 UserCtx *user = NULL;
1139 PetscReal *positions = NULL;
1140 PetscReal *weights = NULL;
1141 PetscInt *cell_ids = NULL;
1142 PetscInt *status = NULL;
1143 PetscInt64 *pid = NULL;
1144
1145 PetscFunctionBeginUser;
1146 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1147 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1148 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1149 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1150 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1151 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
1152
1153 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1154 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1155 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1156 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1157 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1158 positions[0] = 0.625; positions[1] = 0.625; positions[2] = 0.625;
1159 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1160 cell_ids[0] = -1; cell_ids[1] = -1; cell_ids[2] = -1;
1161 status[0] = NEEDS_LOCATION;
1162 pid[0] = 22;
1163 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1164 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1165 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1166 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1167 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1168
1169 PetscCall(LocateAllParticlesInGrid(user, simCtx->bboxlist));
1170
1171 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1172 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1173 PetscCall(PicurvAssertIntEqual(2, cell_ids[0], "guess-path location should resolve the i cell id"));
1174 PetscCall(PicurvAssertIntEqual(2, cell_ids[1], "guess-path location should resolve the j cell id"));
1175 PetscCall(PicurvAssertIntEqual(2, cell_ids[2], "guess-path location should resolve the k cell id"));
1176 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status[0], "guess-path location should mark the particle ACTIVE_AND_LOCATED"));
1177 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.searchAttempts, "guess-path location should perform one robust search"));
1178 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchPopulation, "guess-path location should count one input particle"));
1179 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchLocatedCount, "guess-path location should count one located particle"));
1180 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.searchLostCount, "guess-path location should not lose the particle"));
1181 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.reSearchCount, "guess-path location should not count later-pass re-searches"));
1182 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.bboxGuessFallbackCount, "guess-path location should record one bbox fallback"));
1183 PetscCall(PicurvAssertIntEqual(0, simCtx->searchMetrics.bboxGuessSuccessCount, "guess-path local resolution should not count as remote bbox success"));
1184 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1185 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1186
1187 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1188 PetscFunctionReturn(0);
1189}
PetscInt64 bboxGuessFallbackCount
Definition variables.h:276
PetscInt64 bboxGuessSuccessCount
Definition variables.h:275
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestLocateParticleOrFindMigrationTargetCountsReSearch()

static PetscErrorCode TestLocateParticleOrFindMigrationTargetCountsReSearch ( void  )
static

Verifies that later settlement passes increment re-search metrics.

Definition at line 1193 of file test_runtime_kernels.c.

1194{
1195 SimCtx *simCtx = NULL;
1196 UserCtx *user = NULL;
1197 Particle particle;
1199
1200 PetscFunctionBeginUser;
1201 PetscCall(PetscMemzero(&particle, sizeof(particle)));
1202 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1203 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1204 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1205 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1206 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1207
1209 particle.PID = 33;
1210 particle.cell[0] = 1;
1211 particle.cell[1] = 1;
1212 particle.cell[2] = 1;
1213 particle.loc.x = 0.375;
1214 particle.loc.y = 0.375;
1215 particle.loc.z = 0.375;
1216 particle.weights.x = 0.5;
1217 particle.weights.y = 0.5;
1218 particle.weights.z = 0.5;
1219
1220 PetscCall(LocateParticleOrFindMigrationTarget(user, &particle, &status));
1221
1222 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status, "direct re-search test should locate the particle"));
1223 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchAttempts, "direct re-search test should record one robust walk"));
1224 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.reSearchCount, "direct re-search test should increment re_search_count on later passes"));
1225 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.maxTraversalFailCount, "direct re-search test should not hit MAX_TRAVERSAL"));
1226
1227 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1228 PetscFunctionReturn(0);
1229}
PetscInt cell[3]
Definition variables.h:210
ParticleLocationStatus
Defines the state of a particle with respect to its location and migration status during the iterativ...
Definition variables.h:163
PetscInt currentSettlementPass
Definition variables.h:278
PetscInt64 PID
Definition variables.h:209
PetscInt64 maxTraversalFailCount
Definition variables.h:272
PetscErrorCode LocateParticleOrFindMigrationTarget(UserCtx *user, Particle *particle, ParticleLocationStatus *status_out)
Locates a particle's host cell or identifies its migration target using a robust walk search.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestWallNoSlipAndFreeSlipHelpers()

static PetscErrorCode TestWallNoSlipAndFreeSlipHelpers ( void  )
static

Tests no-slip and free-slip wall helper kernels.

Definition at line 1234 of file test_runtime_kernels.c.

1235{
1236 Cmpnts wall_velocity = {0.0, 0.0, 0.0};
1237 Cmpnts reference_velocity = {2.0, 4.0, 6.0};
1238 Cmpnts boundary_velocity = {0.0, 0.0, 0.0};
1239 Cmpnts free_slip_reference = {2.0, 3.0, 4.0};
1240
1241 PetscFunctionBeginUser;
1242 noslip(NULL, 2.0, 1.0, wall_velocity, reference_velocity, &boundary_velocity, 1.0, 0.0, 0.0);
1243 PetscCall(PicurvAssertRealNear(1.0, boundary_velocity.x, 1.0e-12, "no-slip interpolated x"));
1244 PetscCall(PicurvAssertRealNear(2.0, boundary_velocity.y, 1.0e-12, "no-slip interpolated y"));
1245 PetscCall(PicurvAssertRealNear(3.0, boundary_velocity.z, 1.0e-12, "no-slip interpolated z"));
1246
1247 freeslip(NULL, 2.0, 1.0, wall_velocity, free_slip_reference, &boundary_velocity, 1.0, 0.0, 0.0);
1248 PetscCall(PicurvAssertRealNear(1.0, boundary_velocity.x, 1.0e-12, "free-slip interpolated normal component"));
1249 PetscCall(PicurvAssertRealNear(3.0, boundary_velocity.y, 1.0e-12, "free-slip tangential y preserved"));
1250 PetscCall(PicurvAssertRealNear(4.0, boundary_velocity.z, 1.0e-12, "free-slip tangential z preserved"));
1251 PetscFunctionReturn(0);
1252}
void noslip(UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, double normal_x, double normal_y, double normal_z)
Applies no-slip wall boundary condition with linear interpolation.
void freeslip(UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, double normal_x, double normal_y, double normal_z)
Applies free-slip wall boundary condition.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestWallModelScalarHelpers()

static PetscErrorCode TestWallModelScalarHelpers ( void  )
static

Tests wall-model scalar helper kernels.

Definition at line 1257 of file test_runtime_kernels.c.

1258{
1259 const PetscReal expected_smooth_e = PetscExpReal(0.41 * 5.5);
1260 PetscReal e_coeff = 0.0;
1261 PetscReal utau = 0.0;
1262 PetscReal residual = 0.0;
1263
1264 PetscFunctionBeginUser;
1265 e_coeff = E_coeff(0.1, 0.0, 1.0e-3);
1266 PetscCall(PicurvAssertRealNear(expected_smooth_e, e_coeff, 1.0e-10, "smooth-wall E coefficient"));
1267
1268 utau = find_utau_hydset(1.0e-3, 1.0, 1.0e-2, 0.1, 0.0);
1269 PetscCall(PicurvAssertBool((PetscBool)(utau > 0.0), "friction velocity should remain positive"));
1270 residual = f_hydset(1.0e-3, 1.0, 1.0e-2, utau, 0.0);
1271 PetscCall(PicurvAssertBool((PetscBool)(PetscAbsReal(residual) < 1.0e-5), "Newton solve residual should be small"));
1272
1273 PetscCall(PicurvAssertRealNear(0.0, nu_t(0.0), 1.0e-12, "eddy viscosity ratio at wall"));
1274 PetscCall(PicurvAssertBool((PetscBool)(integrate_1(1.0e-3, 1.0e-2, 0.1, 0) > 0.0), "integral helper should be positive"));
1275 PetscFunctionReturn(0);
1276}
double find_utau_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double initial_guess, double roughness_height)
Solves for friction velocity using Newton-Raphson iteration.
double integrate_1(double kinematic_viscosity, double wall_distance, double friction_velocity, int integration_mode)
Integrates eddy viscosity profile from wall to distance y.
double f_hydset(double kinematic_viscosity, double known_velocity, double wall_distance, double friction_velocity_guess, double roughness_height)
Residual function for friction velocity equation (log-law with roughness)
double E_coeff(double friction_velocity, double roughness_height, double kinematic_viscosity)
Computes roughness-modified log-law coefficient E.
double nu_t(double yplus)
Computes turbulent eddy viscosity ratio (ν_t / ν)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestWallModelVelocityHelpers()

static PetscErrorCode TestWallModelVelocityHelpers ( void  )
static

Tests closed-form and iterative wall-model velocity helpers against inverse reconstructions.

Definition at line 1281 of file test_runtime_kernels.c.

1282{
1283 const PetscReal kinematic_viscosity = 1.0e-3;
1284 const PetscReal wall_distance = 2.0e-2;
1285 const PetscReal target_velocity = 1.0;
1286 const PetscReal roughness_length = 1.0e-4;
1287 PetscReal utau_loglaw = 0.0;
1288 PetscReal utau_werner = 0.0;
1289 PetscReal utau_cabot = 0.0;
1290 PetscReal wall_shear_velocity = 0.0;
1291 PetscReal wall_shear_normal = 0.0;
1292
1293 PetscFunctionBeginUser;
1294 utau_loglaw = find_utau_loglaw(target_velocity, wall_distance, roughness_length);
1295 PetscCall(PicurvAssertRealNear(target_velocity, u_loglaw(wall_distance, utau_loglaw, roughness_length), 1.0e-12,
1296 "simple log-law inversion should reconstruct the target velocity"));
1297
1298 utau_werner = find_utau_Werner(kinematic_viscosity, target_velocity, wall_distance, 0.1);
1299 PetscCall(PicurvAssertBool((PetscBool)(utau_werner > 0.0), "Werner-Wengle friction velocity should remain positive"));
1300 PetscCall(PicurvAssertRealNear(target_velocity, u_Werner(kinematic_viscosity, wall_distance, utau_werner), 1.0e-12,
1301 "Werner-Wengle inversion should reconstruct the target velocity"));
1302
1303 /* The pointwise pair the solver uses must invert exactly on BOTH sides of
1304 y+ = 11.81. The previous inverse round-tripped only in the sublayer, which is the
1305 one range the sample above happens to sit in, and so passed over the mismatch. */
1306 {
1307 const PetscReal yplus[5] = {2.0, 11.0, 11.81, 30.0, 500.0};
1308 const PetscReal u_tau = 0.05;
1309 const PetscReal nu = kinematic_viscosity;
1310
1311 for (PetscInt i = 0; i < 5; ++i) {
1312 const PetscReal y = yplus[i] * nu / u_tau;
1313 const PetscReal u = u_Werner(nu, y, u_tau);
1314 PetscCall(PicurvAssertRealNear(u_tau, find_utau_Werner(nu, u, y, 0.0), 1.0e-12 * u_tau,
1315 "find_utau_Werner must invert u_Werner exactly on both branches"));
1316 }
1317 }
1318
1319 /* The cell-integral pair: correct for a cell-averaged input, not wired into the
1320 solver. Its round trip must still hold on both sides of its own switch. */
1321 {
1322 const PetscReal A = 8.3, Bexp = 1.0 / 7.0;
1323 const PetscReal u_m = 0.5 * kinematic_viscosity / wall_distance *
1324 PetscPowReal(A, 2.0 / (1.0 - Bexp));
1325 const PetscReal samples[2] = {0.25 * u_m, 4.0 * u_m};
1326
1327 for (PetscInt i = 0; i < 2; ++i) {
1328 const PetscReal tau = taw_Werner(kinematic_viscosity, samples[i], wall_distance);
1329
1330 PetscCall(PicurvAssertBool((PetscBool)(tau > 0.0),
1331 "the explicit Werner-Wengle stress must be positive"));
1332 PetscCall(PicurvAssertRealNear(
1333 samples[i], u_Werner_explicit(kinematic_viscosity, wall_distance, tau),
1334 1.0e-9 + 1.0e-9 * samples[i],
1335 "the explicit Werner-Wengle pair must round-trip on both branches"));
1336 }
1337
1338 /* The branches meet at the switch, so approaching it from either side must give
1339 the same stress. A threshold written through the friction velocity, as the
1340 iterative residual's is, cannot satisfy this. */
1341 PetscCall(PicurvAssertRealNear(
1342 taw_Werner(kinematic_viscosity, u_m * (1.0 - 1.0e-9), wall_distance),
1343 taw_Werner(kinematic_viscosity, u_m * (1.0 + 1.0e-9), wall_distance), 1.0e-9,
1344 "the Werner-Wengle branches must be continuous at the transition speed"));
1345
1346 /* Nearer the wall is slower, whatever the branch. This is the property the
1347 previous mismatched pairing violated. */
1348 {
1349 const PetscReal tau = taw_Werner(kinematic_viscosity, 4.0 * u_m, wall_distance);
1350
1351 PetscCall(PicurvAssertBool(
1352 (PetscBool)(u_Werner_explicit(kinematic_viscosity, 0.5 * wall_distance, tau) <
1353 u_Werner_explicit(kinematic_viscosity, wall_distance, tau)),
1354 "a cell nearer the wall must be assigned the slower speed"));
1355 }
1356 }
1357
1358 find_utau_Cabot(kinematic_viscosity, target_velocity, wall_distance, 0.1, 0.0, 0.0,
1359 &utau_cabot, &wall_shear_velocity, &wall_shear_normal);
1360 PetscCall(PicurvAssertBool((PetscBool)(utau_cabot > 0.0), "Cabot friction velocity should remain positive"));
1361 PetscCall(PicurvAssertRealNear(target_velocity, u_Cabot(kinematic_viscosity, wall_distance, utau_cabot, 0.0, wall_shear_velocity), 1.0e-6,
1362 "Cabot inversion should reconstruct the target velocity when pressure gradient is zero"));
1363 PetscCall(PicurvAssertRealNear(0.0, wall_shear_normal, 1.0e-10,
1364 "zero normal pressure gradient should keep Cabot normal wall shear at zero"));
1365 PetscFunctionReturn(0);
1366}
double find_utau_loglaw(double velocity, double wall_distance, double roughness_length)
Solves for friction velocity using simple log-law (explicit formula)
double u_Werner(double kinematic_viscosity, double wall_distance, double friction_velocity)
Computes velocity using Werner-Wengle wall function.
double u_Werner_explicit(double kinematic_viscosity, double wall_distance, double wall_shear_stress)
Wall-parallel velocity at a distance, from the Werner-Wengle wall stress.
double u_Cabot(double kinematic_viscosity, double wall_distance, double friction_velocity, double pressure_gradient_tangent, double wall_shear_stress)
Computes velocity using Cabot wall function.
double u_loglaw(double wall_distance, double friction_velocity, double roughness_length)
Computes velocity using simple log-law (smooth wall with roughness offset)
void find_utau_Cabot(double kinematic_viscosity, double velocity, double wall_distance, double initial_guess, double pressure_gradient_tangent, double pressure_gradient_normal, double *friction_velocity, double *wall_shear_velocity, double *wall_shear_normal)
Solves for friction velocity using Cabot wall function.
double taw_Werner(double kinematic_viscosity, double velocity, double wall_distance)
Wall shear stress from the cell-integrated Werner-Wengle relation.
double find_utau_Werner(double kinematic_viscosity, double velocity, double wall_distance, double initial_guess)
Friction velocity from a point velocity, inverting u_Werner() exactly.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestWallFunctionVectorWrappers()

static PetscErrorCode TestWallFunctionVectorWrappers ( void  )
static

Tests the vector wall-function wrappers on a tangential reference flow.

Definition at line 1370 of file test_runtime_kernels.c.

1371{
1372 SimCtx *simCtx = NULL;
1373 UserCtx *user = NULL;
1374 Cmpnts wall_velocity = {0.0, 0.0, 0.0};
1375 Cmpnts reference_velocity = {0.0, 1.0, 0.0};
1376 Cmpnts boundary_velocity = {0.0, 0.0, 0.0};
1377 PetscReal friction_velocity = 0.0;
1378
1379 PetscFunctionBeginUser;
1380 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1381 simCtx->ren = 1000.0;
1382
1383 wall_function(user, 2.0e-2, 1.0e-2, wall_velocity, reference_velocity, &boundary_velocity, &friction_velocity, 1.0, 0.0, 0.0);
1384 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "Werner wall function should preserve zero normal velocity"));
1385 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y < 1.0), "Werner wall function should damp tangential velocity"));
1386 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "Werner wall function should compute positive friction velocity"));
1387
1388 /* A reference speed taken from the pointwise profile itself must return that
1389 profile's friction velocity, and the boundary cell must land on the same profile.
1390 The reference sits in the power-law branch (y+ = 20), the boundary cell in the
1391 sublayer (y+ = 10), so both branches are exercised. The cell-integral relation
1392 read this point value as a cell average and returned u_tau 14% high. */
1393 {
1394 const PetscReal nu = 1.0 / simCtx->ren, u_tau = 1.0;
1395 Cmpnts profile_reference = {0.0, (PetscReal)u_Werner(nu, 2.0e-2, u_tau), 0.0};
1396
1397 wall_function(user, 2.0e-2, 1.0e-2, wall_velocity, profile_reference, &boundary_velocity, &friction_velocity, 1.0, 0.0, 0.0);
1398 PetscCall(PicurvAssertRealNear(u_tau, friction_velocity, 1.0e-12,
1399 "Werner wall function must return the friction velocity of the profile it is given"));
1400 PetscCall(PicurvAssertRealNear(u_Werner(nu, 1.0e-2, u_tau), boundary_velocity.y, 1.0e-12,
1401 "Werner wall function must put the boundary cell on the same pointwise profile"));
1402 }
1403
1404 wall_function_loglaw(user, 1.0e-4, 2.0e-2, 1.0e-2, wall_velocity, reference_velocity, &boundary_velocity, &friction_velocity, 1.0, 0.0, 0.0);
1405 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "log-law wall function should preserve zero normal velocity"));
1406 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y <= 1.0), "log-law wall function should keep tangential velocity bounded"));
1407 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "log-law wall function should compute positive friction velocity"));
1408
1409 wall_function_Cabot(user, 1.0e-4, 2.0e-2, 1.0e-2, wall_velocity, reference_velocity, &boundary_velocity, &friction_velocity,
1410 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10);
1411 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "Cabot wall function should preserve zero normal velocity"));
1412 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y <= 1.0), "Cabot wall function should keep tangential velocity bounded"));
1413 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "Cabot wall function should compute positive friction velocity"));
1414
1415 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1416 PetscFunctionReturn(0);
1417}
PetscReal ren
Definition variables.h:906
void wall_function_loglaw(UserCtx *user, double roughness_height, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z)
Applies log-law wall function with roughness correction.
void wall_function(UserCtx *user, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z)
Applies standard wall function with Werner-Wengle model.
void wall_function_Cabot(UserCtx *user, double roughness_height, double distance_reference, double distance_boundary, Cmpnts velocity_wall, Cmpnts velocity_reference, Cmpnts *velocity_boundary, PetscReal *friction_velocity, double normal_x, double normal_y, double normal_z, double pressure_gradient_x, double pressure_gradient_y, double pressure_gradient_z, int iteration_count)
Applies Cabot non-equilibrium wall function with pressure gradients.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestValidateDrivenFlowConfigurationNoDrivenHandlers()

static PetscErrorCode TestValidateDrivenFlowConfigurationNoDrivenHandlers ( void  )
static

Tests driven-flow validation when no driven handlers are present.

Definition at line 1422 of file test_runtime_kernels.c.

1423{
1424 SimCtx *simCtx = NULL;
1425 UserCtx *user = NULL;
1426
1427 PetscFunctionBeginUser;
1428 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1429 PetscCall(Validate_DrivenFlowConfiguration(user));
1430 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1431 PetscFunctionReturn(0);
1432}
PetscErrorCode Validate_DrivenFlowConfiguration(UserCtx *user)
(Private) Validates all consistency rules for a driven flow (channel/pipe) setup.
Definition BC_Handlers.c:15
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMinimalFixtureMirrorsProductionDMLayout()

static PetscErrorCode TestMinimalFixtureMirrorsProductionDMLayout ( void  )
static

Tests that the shared minimal fixture mirrors the production DA contract.

Definition at line 1437 of file test_runtime_kernels.c.

1438{
1439 SimCtx *simCtx = NULL;
1440 UserCtx *user = NULL;
1441 DM coord_dm = NULL;
1442 PetscInt mx = 0, my = 0, mz = 0;
1443
1444 PetscFunctionBeginUser;
1445 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 6, 4));
1446
1447 PetscCall(DMDAGetInfo(user->da, NULL, &mx, &my, &mz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
1448 PetscCall(PicurvAssertIntEqual(user->IM + 1, mx, "minimal fixture should size da with IM+1 nodes"));
1449 PetscCall(PicurvAssertIntEqual(user->JM + 1, my, "minimal fixture should size da with JM+1 nodes"));
1450 PetscCall(PicurvAssertIntEqual(user->KM + 1, mz, "minimal fixture should size da with KM+1 nodes"));
1451 PetscCall(PicurvAssertIntEqual(mx, user->info.mx, "user->info should be sourced from the production da"));
1452 PetscCall(PicurvAssertIntEqual(my, user->info.my, "user->info my should match the da dimensions"));
1453 PetscCall(PicurvAssertIntEqual(mz, user->info.mz, "user->info mz should match the da dimensions"));
1454
1455 PetscCall(DMGetCoordinateDM(user->da, &coord_dm));
1456 PetscCall(PicurvAssertBool((PetscBool)(coord_dm == user->fda),
1457 "minimal fixture should derive fda from the coordinate-DM path"));
1458
1459 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1460 PetscFunctionReturn(0);
1461}
PetscInt KM
Definition variables.h:1088
PetscInt JM
Definition variables.h:1088
PetscInt IM
Definition variables.h:1088
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestMinimalFixtureRegistersProductionSwarmFields()

static PetscErrorCode TestMinimalFixtureRegistersProductionSwarmFields ( void  )
static

Tests that the shared swarm fixture registers the production field set.

Definition at line 1466 of file test_runtime_kernels.c.

1467{
1468 SimCtx *simCtx = NULL;
1469 UserCtx *user = NULL;
1470 PetscInt bs = 0;
1471 void *field_ptr = NULL;
1472
1473 PetscFunctionBeginUser;
1474 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1475 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
1476
1477 PetscCall(DMSwarmGetField(user->swarm, "position", &bs, NULL, &field_ptr));
1478 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle position"));
1479 PetscCall(PicurvAssertBool((PetscBool)(field_ptr != NULL), "position field should be retrievable"));
1480 PetscCall(DMSwarmRestoreField(user->swarm, "position", &bs, NULL, &field_ptr));
1481
1482 PetscCall(DMSwarmGetField(user->swarm, "velocity", &bs, NULL, &field_ptr));
1483 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle velocity"));
1484 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", &bs, NULL, &field_ptr));
1485
1486 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", &bs, NULL, &field_ptr));
1487 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register DMSwarm_CellID"));
1488 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", &bs, NULL, &field_ptr));
1489
1490 PetscCall(DMSwarmGetField(user->swarm, "weight", &bs, NULL, &field_ptr));
1491 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle weight"));
1492 PetscCall(DMSwarmRestoreField(user->swarm, "weight", &bs, NULL, &field_ptr));
1493
1494 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", &bs, NULL, &field_ptr));
1495 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle diffusivity"));
1496 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", &bs, NULL, &field_ptr));
1497
1498 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", &bs, NULL, &field_ptr));
1499 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle diffusivity gradients"));
1500 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", &bs, NULL, &field_ptr));
1501
1502 PetscCall(DMSwarmGetField(user->swarm, "Psi", &bs, NULL, &field_ptr));
1503 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle scalar Psi"));
1504 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", &bs, NULL, &field_ptr));
1505
1506 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", &bs, NULL, &field_ptr));
1507 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle location status"));
1508 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", &bs, NULL, &field_ptr));
1509
1510 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1511 PetscFunctionReturn(0);
1512}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestUpdateSolverHistoryVectorsShiftsStates()

static PetscErrorCode TestUpdateSolverHistoryVectorsShiftsStates ( void  )
static

Tests solver history-vector shifting between time levels.

Definition at line 1517 of file test_runtime_kernels.c.

1518{
1519 SimCtx *simCtx = NULL;
1520 UserCtx *user = NULL;
1521
1522 PetscFunctionBeginUser;
1523 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
1524
1525 PetscCall(VecSet(user->Ucont, 11.0));
1526 PetscCall(VecSet(user->Ucont_o, 7.0));
1527 PetscCall(VecSet(user->Ucont_rm1, 3.0));
1528 PetscCall(VecSet(user->Ucat, 5.0));
1529 PetscCall(VecSet(user->Ucat_o, -1.0));
1530 PetscCall(VecSet(user->P, 9.0));
1531 PetscCall(VecSet(user->P_o, -2.0));
1532
1533 PetscCall(UpdateSolverHistoryVectors(user, PETSC_FALSE));
1534
1535 PetscCall(PicurvAssertVecConstant(user->Ucont_o, 11.0, 1.0e-12, "Ucont_o should receive current Ucont"));
1536 PetscCall(PicurvAssertVecConstant(user->Ucont_rm1, 7.0, 1.0e-12, "Ucont_rm1 should receive prior Ucont_o"));
1537 PetscCall(PicurvAssertVecConstant(user->Ucat_o, 5.0, 1.0e-12, "Ucat_o should receive current Ucat"));
1538 PetscCall(PicurvAssertVecConstant(user->P_o, 9.0, 1.0e-12, "P_o should receive current P"));
1539 PetscCall(PicurvAssertVecConstant(user->lUcont_o, 11.0, 1.0e-12, "lUcont_o ghost sync should match Ucont_o"));
1540 PetscCall(PicurvAssertVecConstant(user->lUcont_rm1, 7.0, 1.0e-12, "lUcont_rm1 ghost sync should match Ucont_rm1"));
1541
1542 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1543 PetscFunctionReturn(0);
1544}
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user, PetscBool preserve_previous_state)
Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o,...
Definition runloop.c:314
Vec lUcont_rm1
Definition variables.h:1121
Vec lUcont_o
Definition variables.h:1120
Vec Ucat_o
Definition variables.h:1120
Vec Ucont_o
Definition variables.h:1120
Vec Ucont_rm1
Definition variables.h:1121
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestGetOwnedCellRangeSingleRankAccounting()

static PetscErrorCode TestGetOwnedCellRangeSingleRankAccounting ( void  )
static

Tests owned-cell range accounting on a single MPI rank.

Definition at line 1549 of file test_runtime_kernels.c.

1550{
1551 SimCtx *simCtx = NULL;
1552 UserCtx *user = NULL;
1553 PetscInt xs = -1, ys = -1, zs = -1;
1554 PetscInt xm = -1, ym = -1, zm = -1;
1555
1556 PetscFunctionBeginUser;
1557 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 6, 4));
1558
1559 PetscCall(GetOwnedCellRange(&user->info, 0, &xs, &xm));
1560 PetscCall(GetOwnedCellRange(&user->info, 1, &ys, &ym));
1561 PetscCall(GetOwnedCellRange(&user->info, 2, &zs, &zm));
1562
1563 PetscCall(PicurvAssertIntEqual(0, xs, "single-rank x cell-start index"));
1564 PetscCall(PicurvAssertIntEqual(0, ys, "single-rank y cell-start index"));
1565 PetscCall(PicurvAssertIntEqual(0, zs, "single-rank z cell-start index"));
1566 PetscCall(PicurvAssertIntEqual(user->info.mx - 2, xm, "single-rank x owned cell count"));
1567 PetscCall(PicurvAssertIntEqual(user->info.my - 2, ym, "single-rank y owned cell count"));
1568 PetscCall(PicurvAssertIntEqual(user->info.mz - 2, zm, "single-rank z owned cell count"));
1569
1570 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1571 PetscFunctionReturn(0);
1572}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestComputeAndStoreNeighborRanksSingleRank()

static PetscErrorCode TestComputeAndStoreNeighborRanksSingleRank ( void  )
static

Tests neighbor-rank discovery on a single MPI rank.

Definition at line 1577 of file test_runtime_kernels.c.

1578{
1579 SimCtx *simCtx = NULL;
1580 UserCtx *user = NULL;
1581
1582 PetscFunctionBeginUser;
1583 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 6, 6, 6));
1584 PetscCall(ComputeAndStoreNeighborRanks(user));
1585
1586 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_xm, "single-rank xm neighbor should be null"));
1587 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_xp, "single-rank xp neighbor should be null"));
1588 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_ym, "single-rank ym neighbor should be null"));
1589 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_yp, "single-rank yp neighbor should be null"));
1590 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_zm, "single-rank zm neighbor should be null"));
1591 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_zp, "single-rank zp neighbor should be null"));
1592
1593 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1594 PetscFunctionReturn(0);
1595}
PetscErrorCode ComputeAndStoreNeighborRanks(UserCtx *user)
Computes and stores the Cartesian neighbor ranks for the DMDA decomposition.
Definition setup.c:3033
PetscMPIInt rank_zm
Definition variables.h:225
PetscMPIInt rank_yp
Definition variables.h:224
PetscMPIInt rank_ym
Definition variables.h:224
PetscMPIInt rank_xp
Definition variables.h:223
RankNeighbors neighbors
Definition variables.h:1091
PetscMPIInt rank_xm
Definition variables.h:223
PetscMPIInt rank_zp
Definition variables.h:225
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestRuntimeWalltimeGuardParsesPositiveSeconds()

static PetscErrorCode TestRuntimeWalltimeGuardParsesPositiveSeconds ( void  )
static

Tests parsing of positive runtime walltime metadata values.

Definition at line 1600 of file test_runtime_kernels.c.

1601{
1602 PetscReal seconds = 0.0;
1603
1604 PetscFunctionBeginUser;
1605 PetscCall(PicurvAssertBool(RuntimeWalltimeGuardParsePositiveSeconds("300", &seconds), "plain positive seconds should parse"));
1606 PetscCall(PicurvAssertRealNear(300.0, seconds, 1.0e-12, "parsed walltime seconds"));
1607 PetscCall(PicurvAssertBool(RuntimeWalltimeGuardParsePositiveSeconds(" 42.5 ", &seconds), "whitespace-wrapped decimal seconds should parse"));
1608 PetscCall(PicurvAssertRealNear(42.5, seconds, 1.0e-12, "parsed decimal walltime seconds"));
1609 PetscCall(PicurvAssertBool((PetscBool)!RuntimeWalltimeGuardParsePositiveSeconds("nope", &seconds), "non-numeric metadata should fail parsing"));
1610 PetscCall(PicurvAssertBool((PetscBool)!RuntimeWalltimeGuardParsePositiveSeconds("-10", &seconds), "negative metadata should fail parsing"));
1611 PetscFunctionReturn(0);
1612}
PetscBool RuntimeWalltimeGuardParsePositiveSeconds(const char *text, PetscReal *seconds_out)
Parse a positive floating-point seconds value from runtime metadata.
Definition setup.c:67
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestRuntimeWalltimeGuardEstimatorHelpers()

static PetscErrorCode TestRuntimeWalltimeGuardEstimatorHelpers ( void  )
static

Tests walltime-guard estimator helper calculations.

Definition at line 1617 of file test_runtime_kernels.c.

1618{
1619 PetscReal ewma_fast = 0.0;
1620 PetscReal ewma_slow = 0.0;
1621 PetscReal conservative_fast = 0.0;
1622 PetscReal conservative_slow = 0.0;
1623 PetscReal required_headroom = 0.0;
1624
1625 PetscFunctionBeginUser;
1626 ewma_fast = RuntimeWalltimeGuardUpdateEWMA(PETSC_TRUE, 4.0, 6.0, 0.5);
1627 ewma_slow = RuntimeWalltimeGuardUpdateEWMA(PETSC_TRUE, ewma_fast, 12.0, 0.5);
1628 conservative_fast = RuntimeWalltimeGuardConservativeEstimate(5.0, ewma_fast, 6.0);
1629 conservative_slow = RuntimeWalltimeGuardConservativeEstimate(5.0, ewma_slow, 12.0);
1630 required_headroom = RuntimeWalltimeGuardRequiredHeadroom(8.0, 2.0, conservative_slow);
1631
1632 PetscCall(PicurvAssertRealNear(5.0, ewma_fast, 1.0e-12, "EWMA after moderate step"));
1633 PetscCall(PicurvAssertRealNear(8.5, ewma_slow, 1.0e-12, "EWMA after newer slow step"));
1634 PetscCall(PicurvAssertRealNear(6.0, conservative_fast, 1.0e-12, "conservative estimate tracks latest moderate step"));
1635 PetscCall(PicurvAssertRealNear(12.0, conservative_slow, 1.0e-12, "conservative estimate tracks newest slow step"));
1636 PetscCall(PicurvAssertRealNear(24.0, required_headroom, 1.0e-12, "required headroom scales with conservative estimate"));
1637 PetscFunctionReturn(0);
1638}
PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
Update an EWMA estimate for timestep wall-clock duration.
Definition runloop.c:153
PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
Return the conservative timestep estimate used by the walltime guard.
Definition runloop.c:165
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Compute the required shutdown headroom from timestep estimate and floor.
Definition runloop.c:176
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestRuntimeWalltimeGuardTriggerDecision()

static PetscErrorCode TestRuntimeWalltimeGuardTriggerDecision ( void  )
static

Tests runtime walltime-guard shutdown trigger decisions.

Definition at line 1643 of file test_runtime_kernels.c.

1644{
1645 PetscBool should_trigger = PETSC_FALSE;
1646 PetscReal required_headroom = 0.0;
1647
1648 PetscFunctionBeginUser;
1649 should_trigger = RuntimeWalltimeGuardShouldTrigger(9, 10, 15.0, 5.0, 2.0, 6.0, 6.0, 6.0, &required_headroom);
1650 PetscCall(PicurvAssertBool((PetscBool)!should_trigger, "guard should not trigger before warmup completes"));
1651
1652 should_trigger = RuntimeWalltimeGuardShouldTrigger(10, 10, 40.0, 5.0, 2.0, 10.0, 12.0, 14.0, &required_headroom);
1653 PetscCall(PicurvAssertBool((PetscBool)!should_trigger, "guard should not trigger when remaining walltime exceeds required headroom"));
1654 PetscCall(PicurvAssertRealNear(28.0, required_headroom, 1.0e-12, "required headroom after warmup"));
1655
1656 should_trigger = RuntimeWalltimeGuardShouldTrigger(10, 10, 28.0, 5.0, 2.0, 10.0, 12.0, 14.0, &required_headroom);
1657 PetscCall(PicurvAssertBool(should_trigger, "guard should trigger when remaining walltime reaches required headroom"));
1658 PetscCall(PicurvAssertRealNear(28.0, required_headroom, 1.0e-12, "required headroom remains unchanged at trigger threshold"));
1659 PetscFunctionReturn(0);
1660}
PetscBool RuntimeWalltimeGuardShouldTrigger(PetscInt completed_steps, PetscInt warmup_steps, PetscReal remaining_seconds, PetscReal min_seconds, PetscReal multiplier, PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds, PetscReal *required_headroom_seconds_out)
Decide whether the runtime walltime guard should stop before another step.
Definition runloop.c:187
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Runs the unit-runtime PETSc test binary.

Definition at line 1665 of file test_runtime_kernels.c.

1666{
1667 PetscErrorCode ierr;
1668 const PicurvTestCase cases[] = {
1669 {"distribute-particles-remainder-handling", TestDistributeParticlesRemainderHandling},
1670 {"is-particle-inside-bbox-basic-cases", TestIsParticleInsideBoundingBoxBasicCases},
1671 {"update-particle-weights-computes-expected-ratios", TestUpdateParticleWeightsComputesExpectedRatios},
1672 {"update-particle-position-without-brownian-contribution", TestUpdateParticlePositionWithoutBrownianContribution},
1673 {"update-particle-position-diffusivity-gradient-only", TestUpdateParticlePositionDiffusivityGradientOnly},
1674 {"update-particle-field-iem-relaxation", TestUpdateParticleFieldIEMRelaxation},
1675 {"set-initial-interior-field-ignores-non-ucont-request", TestSetInitialInteriorFieldIgnoresNonUcontRequest},
1676 {"set-initial-interior-field-cartesian-constant-sets-contravariant-flux", TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux},
1677 {"set-initial-interior-field-curvilinear-constant-via-flow-direction", TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection},
1678 {"set-initial-interior-field-zero-clears-interior", TestSetInitialInteriorFieldZeroClearsInterior},
1679 {"set-initial-interior-field-poiseuille-profile", TestSetInitialInteriorFieldPoiseuilleProfile},
1680 {"set-initial-interior-field-poiseuille-uniform-along-periodic-axis", TestSetInitialInteriorFieldPoiseuilleUniformAlongPeriodicAxis},
1681 {"cart2contra-converts-cartesian-field", TestCart2ContraConvertsCartesianField},
1682 {"cart2contra-uses-finalized-periodic-ucat", TestCart2ContraUsesFinalizedPeriodicUcat},
1683 {"populate-initial-ucont-loads-staged-ucat", TestPopulateInitialUcontLoadsStagedUcat},
1684 {"write-les-fields-copies-owned-periodic-values", TestWriteLESFieldsCopiesOwnedPeriodicValues},
1685 {"staged-ucat-fourier-modes-use-picurv-discrete-symbol", TestStagedUcatFourierModesUsePicurvDiscreteSymbol},
1686 {"populate-initial-ucont-loads-staged-ucont", TestPopulateInitialUcontLoadsStagedUcont},
1687 {"interpolate-all-fields-to-swarm-constant-fields", TestInterpolateAllFieldsToSwarmConstantFields},
1688 {"interpolate-all-fields-to-swarm-corner-averaged-constant-fields", TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields},
1689 {"scatter-all-particle-fields-to-euler-fields-averages-psi", TestScatterAllParticleFieldsToEulerFieldsAveragesPsi},
1690 {"calculate-particle-count-per-cell-counts-global-cell-ids", TestCalculateParticleCountPerCellCountsGlobalCellIDs},
1691 {"reset-all-particle-statuses-leaves-lost-particles-untouched", TestResetAllParticleStatusesLeavesLostParticlesUntouched},
1692 {"check-and-remove-out-of-bounds-particles-removes-escaped-particle", TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle},
1693 {"check-and-remove-lost-particles-removes-lost-entries", TestCheckAndRemoveLostParticlesRemovesLostEntries},
1694 {"calculate-brownian-displacement-deterministic-seed", TestCalculateBrownianDisplacementDeterministicSeed},
1695 {"update-all-particle-positions-moves-swarm-entries", TestUpdateAllParticlePositionsMovesSwarmEntries},
1696 {"locate-all-particles-in-grid-prior-cell-fast-path", TestLocateAllParticlesInGridPriorCellFastPath},
1697 {"locate-all-particles-in-grid-guess-path-resolves-local-particle", TestLocateAllParticlesInGridGuessPathResolvesLocalParticle},
1698 {"locate-particle-or-find-migration-target-counts-research", TestLocateParticleOrFindMigrationTargetCountsReSearch},
1699 {"wall-noslip-and-freeslip-helpers", TestWallNoSlipAndFreeSlipHelpers},
1700 {"wall-model-scalar-helpers", TestWallModelScalarHelpers},
1701 {"wall-model-velocity-helpers", TestWallModelVelocityHelpers},
1702 {"wall-function-vector-wrappers", TestWallFunctionVectorWrappers},
1703 {"validate-driven-flow-configuration-no-driven-handlers", TestValidateDrivenFlowConfigurationNoDrivenHandlers},
1704 {"minimal-fixture-mirrors-production-dm-layout", TestMinimalFixtureMirrorsProductionDMLayout},
1705 {"minimal-fixture-registers-production-swarm-fields", TestMinimalFixtureRegistersProductionSwarmFields},
1706 {"update-solver-history-vectors-shifts-states", TestUpdateSolverHistoryVectorsShiftsStates},
1707 {"get-owned-cell-range-single-rank-accounting", TestGetOwnedCellRangeSingleRankAccounting},
1708 {"compute-and-store-neighbor-ranks-single-rank", TestComputeAndStoreNeighborRanksSingleRank},
1709 {"runtime-walltime-guard-parses-positive-seconds", TestRuntimeWalltimeGuardParsesPositiveSeconds},
1710 {"runtime-walltime-guard-estimator-helpers", TestRuntimeWalltimeGuardEstimatorHelpers},
1711 {"runtime-walltime-guard-trigger-decision", TestRuntimeWalltimeGuardTriggerDecision},
1712 };
1713
1714 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv runtime-kernel tests");
1715 if (ierr) {
1716 return (int)ierr;
1717 }
1718
1719 ierr = PicurvRunTests("unit-runtime", cases, sizeof(cases) / sizeof(cases[0]));
1720 if (ierr) {
1721 PetscFinalize();
1722 return (int)ierr;
1723 }
1724
1725 ierr = PetscFinalize();
1726 return (int)ierr;
1727}
static PetscErrorCode TestUpdateParticleFieldIEMRelaxation(void)
Tests IEM relaxation updates for particle-carried fields.
static PetscErrorCode TestMinimalFixtureMirrorsProductionDMLayout(void)
Tests that the shared minimal fixture mirrors the production DA contract.
static PetscErrorCode TestUpdateParticlePositionDiffusivityGradientOnly(void)
Tests particle position updates driven only by diffusivity-gradient drift.
static PetscErrorCode TestLocateAllParticlesInGridGuessPathResolvesLocalParticle(void)
Tests the guess-then-verify orchestrator path for a local particle with an unknown prior cell.
static PetscErrorCode TestWallModelVelocityHelpers(void)
Tests closed-form and iterative wall-model velocity helpers against inverse reconstructions.
static PetscErrorCode TestSetInitialInteriorFieldIgnoresNonUcontRequest(void)
Tests that non-Ucont requests do not modify interior field initialization.
static PetscErrorCode TestLocateParticleOrFindMigrationTargetCountsReSearch(void)
Verifies that later settlement passes increment re-search metrics.
static PetscErrorCode TestRuntimeWalltimeGuardParsesPositiveSeconds(void)
Tests parsing of positive runtime walltime metadata values.
static PetscErrorCode TestCart2ContraUsesFinalizedPeriodicUcat(void)
Verifies periodic Ucat endpoints are repaired before Cart2Contra terminal faces.
static PetscErrorCode TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection(void)
Tests curvilinear Constant IC: flow_direction selects the streamwise axis.
static PetscErrorCode TestInterpolateAllFieldsToSwarmConstantFields(void)
Tests direct interpolation from Eulerian fields to one localized swarm particle.
static PetscErrorCode TestStagedUcatFourierModesUsePicurvDiscreteSymbol(void)
Cross-checks selected exact Fourier modes against PICurv's native discrete symbol.
static PetscErrorCode TestDistributeParticlesRemainderHandling(void)
Tests particle distribution remainder handling across ranks.
static PetscErrorCode TestResetAllParticleStatusesLeavesLostParticlesUntouched(void)
Tests localized particle-status reset behavior for restart of the location workflow.
static PetscErrorCode TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux(void)
Tests cartesian Constant IC: Cart2Contra sets contravariant flux via metric dot product.
static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcat(void)
Tests loading a staged Ucat file IC and converting it to Ucont.
static PetscErrorCode TestPopulateInitialUcontLoadsStagedUcont(void)
Tests loading a staged Ucont file IC without Cartesian conversion.
static PetscErrorCode TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields(void)
Tests the corner-averaged (legacy) interpolation path on constant fields.
static PetscErrorCode TestGetOwnedCellRangeSingleRankAccounting(void)
Tests owned-cell range accounting on a single MPI rank.
static PetscErrorCode TestUpdateParticlePositionWithoutBrownianContribution(void)
Tests particle position updates without Brownian forcing.
static PetscErrorCode TestComputeAndStoreNeighborRanksSingleRank(void)
Tests neighbor-rank discovery on a single MPI rank.
static PetscErrorCode TestCalculateParticleCountPerCellCountsGlobalCellIDs(void)
Tests particle counting by geometric cell IDs using the production +1 storage shift.
static PetscErrorCode TestWriteLESFieldsCopiesOwnedPeriodicValues(void)
Tests LES output staging from local vectors on a multiply periodic DMDA.
static PetscErrorCode TestValidateDrivenFlowConfigurationNoDrivenHandlers(void)
Tests driven-flow validation when no driven handlers are present.
static PetscErrorCode TestWallNoSlipAndFreeSlipHelpers(void)
Tests no-slip and free-slip wall helper kernels.
static PetscErrorCode TestMinimalFixtureRegistersProductionSwarmFields(void)
Tests that the shared swarm fixture registers the production field set.
static PetscErrorCode TestWallFunctionVectorWrappers(void)
Tests the vector wall-function wrappers on a tangential reference flow.
static PetscErrorCode TestSetInitialInteriorFieldZeroClearsInterior(void)
Tests zero IC clears physical-cell contravariant velocity.
static PetscErrorCode TestLocateAllParticlesInGridPriorCellFastPath(void)
Tests the location orchestrator fast path when a particle already carries a valid prior cell.
static PetscErrorCode TestCalculateBrownianDisplacementDeterministicSeed(void)
Tests Brownian displacement generation against a duplicated seeded RNG stream.
static PetscErrorCode TestScatterAllParticleFieldsToEulerFieldsAveragesPsi(void)
Tests particle-to-grid scattering using known cell occupancy and scalar values.
static PetscErrorCode TestUpdateSolverHistoryVectorsShiftsStates(void)
Tests solver history-vector shifting between time levels.
static PetscErrorCode TestUpdateParticleWeightsComputesExpectedRatios(void)
Tests particle weight updates against expected ratios.
static PetscErrorCode TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle(void)
Tests direct removal of particles that leave every rank bounding box.
static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleProfile(void)
Tests Poiseuille IC is the product parabola that vanishes on the walls.
static PetscErrorCode TestSetInitialInteriorFieldPoiseuilleUniformAlongPeriodicAxis(void)
Tests Poiseuille IC is uniform along a periodic cross-stream axis.
static PetscErrorCode TestCart2ContraConvertsCartesianField(void)
Tests spatially varying Cartesian-field conversion to contravariant fluxes.
static PetscErrorCode TestCheckAndRemoveLostParticlesRemovesLostEntries(void)
Tests direct removal of particles already marked LOST by the location workflow.
static PetscErrorCode TestRuntimeWalltimeGuardEstimatorHelpers(void)
Tests walltime-guard estimator helper calculations.
static PetscErrorCode TestIsParticleInsideBoundingBoxBasicCases(void)
Tests basic particle-inside-bounding-box classification cases.
static PetscErrorCode TestRuntimeWalltimeGuardTriggerDecision(void)
Tests runtime walltime-guard shutdown trigger decisions.
static PetscErrorCode TestUpdateAllParticlePositionsMovesSwarmEntries(void)
Tests swarm-wide particle position updates using the same transport path as the runtime loop.
static PetscErrorCode TestWallModelScalarHelpers(void)
Tests wall-model scalar helper kernels.
PetscErrorCode PicurvRunTests(const char *suite_name, const PicurvTestCase *cases, size_t case_count)
Runs a named C test suite and prints pass/fail progress markers.
Named test case descriptor consumed by PicurvRunTests.
Here is the call graph for this function: