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 follows the discrete cross-stream profile and reaches zero at edges.
 
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 TestComputeSmagorinskyConstantConstantModel (void)
 Tests the constant Smagorinsky model helper path.
 
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:943
Vec lPsi
Definition variables.h:997
Vec DiffusivityGradient
Definition variables.h:943
Vec Ucont
Definition variables.h:939
Vec Ucat
Definition variables.h:939
Vec lUcont
Definition variables.h:939
Vec Diffusivity
Definition variables.h:942
Vec lUcat
Definition variables.h:939
Vec lDiffusivity
Definition variables.h:942
Vec Psi
Definition variables.h:997
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:173
Cmpnts min_coords
Minimum x, y, z coordinates of the bounding box.
Definition variables.h:172
PetscScalar x
Definition variables.h:103
Cmpnts loc
Definition variables.h:185
PetscScalar z
Definition variables.h:103
PetscScalar y
Definition variables.h:103
Defines a 3D axis-aligned bounding box.
Definition variables.h:171
Defines a particle's core properties for Lagrangian tracking.
Definition variables.h:182
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:187
@ NUM_FACES
Definition variables.h:147
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:186
Cmpnts diffusivitygradient
Definition variables.h:191
PetscReal dt
Definition variables.h:710
PetscReal diffusivity
Definition variables.h:190
The master context for the entire simulation.
Definition variables.h:695
User-defined context containing data specific to a single computational grid level.
Definition variables.h:906
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:754
@ IC_MODE_CONSTANT_CARTESIAN
Definition variables.h:153
Cmpnts InitialConstantContra
Definition variables.h:757
A 3D point or vector with PetscScalar components.
Definition variables.h:102
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:759
FlowDirection flowDirection
Definition variables.h:758
@ FLOW_DIR_POS_ZETA
Definition variables.h:277
@ IC_MODE_CONSTANT_STREAMWISE
Definition variables.h:155
PetscInt GridOrientation
Definition variables.h:924
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:152
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 follows the discrete cross-stream profile and reaches zero at edges.

Definition at line 363 of file test_runtime_kernels.c.

364{
365 SimCtx *simCtx = NULL;
366 UserCtx *user = NULL;
367 Cmpnts ***ucont = NULL;
368
369 PetscFunctionBeginUser;
370 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
372 simCtx->icVelocityPhysical = 3.0;
374 user->GridOrientation = 1;
375 PetscCall(VecZeroEntries(user->Ucont));
376
377 PetscCall(SetInitialInteriorField(user, FIELD_ID_UCONT));
378 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
379 PetscCall(PicurvAssertRealNear(3.0 * 64.0 / 81.0, ucont[2][2][2].z, 1.0e-12,
380 "Poiseuille IC follows the discrete center-adjacent profile value"));
381 PetscCall(PicurvAssertRealNear(0.0, ucont[2][1][1].z, 1.0e-12, "Poiseuille IC is zero at cross-stream edge"));
382 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].x, 1.0e-12, "Poiseuille IC leaves Xi flux zero"));
383 PetscCall(PicurvAssertRealNear(0.0, ucont[2][2][2].y, 1.0e-12, "Poiseuille IC leaves Eta flux zero"));
384 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
385
386 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
387 PetscFunctionReturn(0);
388}
@ IC_MODE_POISEUILLE
Definition variables.h:154
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 393 of file test_runtime_kernels.c.

394{
395 SimCtx *simCtx = NULL;
396 UserCtx *user = NULL;
397 Cmpnts ***ucat = NULL;
398 Cmpnts ***ucont = NULL;
399
400 PetscFunctionBeginUser;
401 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
402 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
403 for (PetscInt k = 0; k < 6; k++)
404 for (PetscInt j = 0; j < 6; j++)
405 for (PetscInt i = 0; i < 6; i++)
406 ucat[k][j][i] = (Cmpnts){(PetscReal)i, 2.0, 3.0};
407 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
408 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCAT));
409 PetscCall(Cart2Contra(user));
410
411 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
412 PetscCall(PicurvAssertRealNear(1.5, ucont[1][1][1].x, 1.0e-10,
413 "Xi flux uses face-interpolated Ucat"));
414 PetscCall(PicurvAssertRealNear(2.0, ucont[1][1][1].y, 1.0e-10,
415 "Eta flux uses Cartesian y velocity"));
416 PetscCall(PicurvAssertRealNear(3.0, ucont[1][1][1].z, 1.0e-10,
417 "Zeta flux uses Cartesian z velocity"));
418 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
419
420 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
421 PetscFunctionReturn(0);
422}
@ 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:1838
PetscErrorCode Cart2Contra(UserCtx *user)
Convert the ghosted Cartesian velocity field to contravariant face fluxes.
Definition setup.c:2784
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 425 of file test_runtime_kernels.c.

426{
427 SimCtx *simCtx=NULL; UserCtx *user=NULL; Cmpnts ***ucat=NULL,***ucont=NULL; PetscInt mx;
428 const FieldId cell_fields[] = {FIELD_ID_UCAT}, staggered_fields[] = {FIELD_ID_UCONT};
429 PetscFunctionBeginUser;
430 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(&simCtx,&user,4,4,4,PETSC_TRUE,PETSC_FALSE,PETSC_FALSE));
433 mx=user->info.mx;
434 PetscCall(VecSet(user->Ucat,0.0));
435 PetscCall(DMDAVecGetArray(user->fda,user->Ucat,&ucat));
436 for(PetscInt k=1;k<user->info.mz-1;k++) for(PetscInt j=1;j<user->info.my-1;j++)
437 for(PetscInt i=1;i<mx-1;i++) ucat[k][j][i]=(Cmpnts){10.0+(PetscReal)i,2.0,3.0};
438 ucat[2][2][0]=(Cmpnts){-1000.0,-1000.0,-1000.0};
439 ucat[2][2][mx-1]=(Cmpnts){-2000.0,-2000.0,-2000.0};
440 PetscCall(DMDAVecRestoreArray(user->fda,user->Ucat,&ucat));
441 PetscCall(SynchronizePeriodicCellFields(user,1,cell_fields));
442 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCAT));
443 PetscCall(Cart2Contra(user));
444 PetscCall(SynchronizePeriodicStaggeredFields(user,1,staggered_fields));
445 PetscCall(DMDAVecGetArrayRead(user->fda,user->Ucont,&ucont));
446 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"));
447 PetscCall(DMDAVecRestoreArrayRead(user->fda,user->Ucont,&ucont));
448 PetscCall(PicurvDestroyMinimalContexts(&simCtx,&user));
449 PetscFunctionReturn(0);
450}
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:292
BoundaryFaceConfig boundary_faces[6]
Definition variables.h:931
DMDALocalInfo info
Definition variables.h:918
BCType mathematical_type
Definition variables.h:368
@ BC_FACE_NEG_X
Definition variables.h:262
@ BC_FACE_POS_X
Definition variables.h:262
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 455 of file test_runtime_kernels.c.

456{
457 SimCtx *simCtx = NULL;
458 UserCtx *user = NULL;
459 Cmpnts ***ucont = NULL;
460 char tmpdir[PETSC_MAX_PATH_LEN];
461
462 PetscFunctionBeginUser;
463 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
464 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
465 PetscCall(VecSet(user->Ucat, 2.5));
466 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
468 PetscCall(WriteFieldData(user, "ufield00000_0", user->Ucat, "dat"));
469 simCtx->current_io_directory = NULL;
470
471 PetscCall(VecZeroEntries(user->Ucat));
472 PetscCall(VecZeroEntries(user->Ucont));
475 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
476 PetscCall(PopulateInitialUcont(user));
477
478 PetscCall(PicurvAssertVecConstant(user->Ucat, 2.5, 1.0e-12, "file IC should restore Ucat"));
479 PetscCall(DMDAVecGetArrayRead(user->fda, user->Ucont, &ucont));
480 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].x, 1.0e-12, "file Ucat IC should populate interior Xi flux"));
481 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].y, 1.0e-12, "file Ucat IC should populate interior Eta flux"));
482 PetscCall(PicurvAssertRealNear(2.5, ucont[1][1][1].z, 1.0e-12, "file Ucat IC should populate interior Zeta flux"));
483 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->Ucont, &ucont));
484 PetscCall(PicurvRemoveTempDir(tmpdir));
485 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
486 PetscFunctionReturn(0);
487}
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:1947
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:720
char initialConditionDirectory[PETSC_MAX_PATH_LEN]
Definition variables.h:756
@ IC_MODE_FILE
Definition variables.h:156
@ IC_FIELD_UCAT
Definition variables.h:161
char _io_context_buffer[PETSC_MAX_PATH_LEN]
Definition variables.h:719
InitialConditionField initialConditionField
Definition variables.h:755
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 490 of file test_runtime_kernels.c.

491{
492 SimCtx *simCtx = NULL;
493 UserCtx *user = NULL;
494 char tmpdir[PETSC_MAX_PATH_LEN];
495 char euler_dir[PETSC_MAX_PATH_LEN];
496 char block_dir[PETSC_MAX_PATH_LEN];
497
498 PetscFunctionBeginUser;
500 &simCtx, &user, 4, 4, 4, PETSC_TRUE, PETSC_TRUE, PETSC_TRUE));
501 PetscCall(DMCreateGlobalVector(user->da, &user->CS));
502 PetscCall(DMCreateLocalVector(user->da, &user->lCs));
503 PetscCall(DMCreateGlobalVector(user->da, &user->Nu_t));
504 PetscCall(DMCreateLocalVector(user->da, &user->lNu_t));
505 PetscCall(VecSet(user->CS, 0.0));
506 PetscCall(VecSet(user->lCs, 2.5));
507 PetscCall(VecSet(user->Nu_t, 0.0));
508 PetscCall(VecSet(user->lNu_t, 7.5));
509 simCtx->les = 1;
510
511 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
512 PetscCall(PetscSNPrintf(euler_dir, sizeof(euler_dir), "%s/eulerian", tmpdir));
513 PetscCall(PetscSNPrintf(block_dir, sizeof(block_dir), "%s/block_0000", euler_dir));
514 PetscCall(PicurvEnsureDir(euler_dir));
515 PetscCall(PicurvEnsureDir(block_dir));
516 PetscCall(WriteSimulationFields(user, tmpdir));
517
518 PetscCall(PicurvAssertVecConstant(user->CS, 2.5, 1.0e-12,
519 "checkpoint output should copy owned periodic lCs values"));
520 PetscCall(PicurvAssertVecConstant(user->Nu_t, 7.5, 1.0e-12,
521 "checkpoint output should copy owned periodic lNu_t values"));
522
523 PetscCall(PicurvRemoveTempDir(tmpdir));
524 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
525 PetscFunctionReturn(0);
526}
PetscErrorCode WriteSimulationFields(UserCtx *user, const char *checkpoint_directory)
Writes simulation fields to files.
Definition io.c:2002
PetscErrorCode PicurvEnsureDir(const char *path)
Ensures a directory exists for test output.
Vec lCs
Definition variables.h:982
Vec lNu_t
Definition variables.h:982
Vec Nu_t
Definition variables.h:982
PetscInt les
Definition variables.h:821
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 535 of file test_runtime_kernels.c.

542{
543 SimCtx *simCtx = user->simCtx;
544 Cmpnts ***ucat = NULL, ***ucont = NULL;
545 PetscInt n_x = user->info.mx - 2, n_y = user->info.my - 2, n_z = user->info.mz - 2;
546 const FieldId staggered_fields[] = {FIELD_ID_UCONT};
547
548 PetscFunctionBeginUser;
549 PetscCall(VecZeroEntries(user->Ucat));
550 PetscCall(DMDAVecGetArray(user->fda, user->Ucat, &ucat));
551 for (PetscInt k = 0; k < user->info.mz; ++k) {
552 for (PetscInt j = 0; j < user->info.my; ++j) {
553 for (PetscInt i = 0; i < user->info.mx; ++i) {
554 PetscReal phase = 2.0 * PETSC_PI * (
555 (PetscReal)(mode_x * (i - 1)) / (PetscReal)n_x +
556 (PetscReal)(mode_y * (j - 1)) / (PetscReal)n_y +
557 (PetscReal)(mode_z * (k - 1)) / (PetscReal)n_z);
558 PetscReal wave = PetscCosReal(phase);
559 ucat[k][j][i] = (Cmpnts){amplitude.x * wave, amplitude.y * wave, amplitude.z * wave};
560 }
561 }
562 }
563 PetscCall(DMDAVecRestoreArray(user->fda, user->Ucat, &ucat));
564
565 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
567 PetscCall(WriteFieldData(user, "ufield00000_0", user->Ucat, "dat"));
568 simCtx->current_io_directory = NULL;
569 PetscCall(VecZeroEntries(user->Ucat));
570 PetscCall(VecZeroEntries(user->Ucont));
571 PetscCall(PopulateInitialUcont(user));
572 PetscCall(SynchronizePeriodicStaggeredFields(user, 1, staggered_fields));
573 PetscCall(UpdateLocalGhosts(user, FIELD_ID_UCONT));
574
575 *max_divergence = 0.0;
576 PetscCall(DMDAVecGetArrayRead(user->fda, user->lUcont, &ucont));
577 for (PetscInt k = 1; k < user->info.mz - 1; ++k) {
578 for (PetscInt j = 1; j < user->info.my - 1; ++j) {
579 for (PetscInt i = 1; i < user->info.mx - 1; ++i) {
580 PetscReal divergence =
581 ucont[k][j][i].x - ucont[k][j][i - 1].x +
582 ucont[k][j][i].y - ucont[k][j - 1][i].y +
583 ucont[k][j][i].z - ucont[k - 1][j][i].z;
584 *max_divergence = PetscMax(*max_divergence, PetscAbsReal(divergence));
585 }
586 }
587 }
588 PetscCall(DMDAVecRestoreArrayRead(user->fda, user->lUcont, &ucont));
589 PetscFunctionReturn(0);
590}
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:909
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 593 of file test_runtime_kernels.c.

594{
595 SimCtx *simCtx = NULL;
596 UserCtx *user = NULL;
597 char tmpdir[PETSC_MAX_PATH_LEN];
598 PetscReal max_divergence = 0.0, sx, sy, sz;
599 PetscInt n;
600
601 PetscFunctionBeginUser;
603 &simCtx, &user, 9, 9, 9, PETSC_TRUE, PETSC_TRUE, PETSC_TRUE));
604 for (PetscInt face = 0; face < NUM_FACES; ++face)
606 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
609 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
610
612 user, 1, 0, 0, (Cmpnts){0.0, 1.0, 0.0}, tmpdir, &max_divergence));
613 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
614 "axis-aligned transverse staged mode"));
615
616 n = user->info.mx - 2;
617 sx = PetscSinReal(2.0 * PETSC_PI / (PetscReal)n);
618 sy = PetscSinReal(4.0 * PETSC_PI / (PetscReal)n);
619 sz = PetscSinReal(6.0 * PETSC_PI / (PetscReal)n);
621 user, 1, 2, 0, (Cmpnts){sy, -sx, 0.0}, tmpdir, &max_divergence));
622 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
623 "oblique first discrete transverse polarization"));
625 user, 1, 2, 3,
626 (Cmpnts){sz * sx, sz * sy, -(sx * sx + sy * sy)},
627 tmpdir, &max_divergence));
628 PetscCall(PicurvAssertRealNear(0.0, max_divergence, 1.0e-12,
629 "oblique second discrete transverse polarization"));
630
631 PetscCall(PicurvRemoveTempDir(tmpdir));
632 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
633 PetscFunctionReturn(0);
634}
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 639 of file test_runtime_kernels.c.

640{
641 SimCtx *simCtx = NULL;
642 UserCtx *user = NULL;
643 char tmpdir[PETSC_MAX_PATH_LEN];
644
645 PetscFunctionBeginUser;
646 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
647 PetscCall(PicurvMakeTempDir(tmpdir, sizeof(tmpdir)));
648 PetscCall(VecSet(user->Ucont, 4.5));
649 PetscCall(PetscStrncpy(simCtx->_io_context_buffer, tmpdir, sizeof(simCtx->_io_context_buffer)));
651 PetscCall(WriteFieldData(user, "vfield00000_0", user->Ucont, "dat"));
652 simCtx->current_io_directory = NULL;
653
654 PetscCall(VecZeroEntries(user->Ucont));
657 PetscCall(PetscStrncpy(simCtx->initialConditionDirectory, tmpdir, sizeof(simCtx->initialConditionDirectory)));
658 PetscCall(PopulateInitialUcont(user));
659
660 PetscCall(PicurvAssertVecConstant(user->Ucont, 4.5, 1.0e-12, "file Ucont IC should restore Ucont directly"));
661 PetscCall(PicurvRemoveTempDir(tmpdir));
662 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
663 PetscFunctionReturn(0);
664}
@ IC_FIELD_UCONT
Definition variables.h:162
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 669 of file test_runtime_kernels.c.

670{
671 SimCtx *simCtx = NULL;
672 UserCtx *user = NULL;
673 Cmpnts ***grad = NULL;
674 PetscReal *velocity = NULL;
675 PetscReal *diffusivity = NULL;
676 PetscReal *diffusivity_gradient = NULL;
677
678 PetscFunctionBeginUser;
679 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
680 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
681 PetscCall(VecSet(user->Ucat, 2.0));
682 PetscCall(VecSet(user->Diffusivity, 0.25));
683
684 PetscCall(DMDAVecGetArray(user->fda, user->DiffusivityGradient, &grad));
685 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
686 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
687 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
688 grad[k][j][i].x = 0.1;
689 grad[k][j][i].y = 0.2;
690 grad[k][j][i].z = 0.3;
691 }
692 }
693 }
694 PetscCall(DMDAVecRestoreArray(user->fda, user->DiffusivityGradient, &grad));
695 PetscCall(SyncRuntimeFieldGhosts(user));
696 PetscCall(SeedSingleParticle(user, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ACTIVE_AND_LOCATED));
697
698 PetscCall(InterpolateAllFieldsToSwarm(user));
699
700 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
701 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
702 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
703 PetscCall(PicurvAssertRealNear(2.0, velocity[0], 1.0e-12, "Interpolated velocity x should match constant Eulerian field"));
704 PetscCall(PicurvAssertRealNear(2.0, velocity[1], 1.0e-12, "Interpolated velocity y should match constant Eulerian field"));
705 PetscCall(PicurvAssertRealNear(2.0, velocity[2], 1.0e-12, "Interpolated velocity z should match constant Eulerian field"));
706 PetscCall(PicurvAssertRealNear(0.25, diffusivity[0], 1.0e-12, "Interpolated scalar diffusivity should match constant Eulerian field"));
707 PetscCall(PicurvAssertRealNear(0.1, diffusivity_gradient[0], 1.0e-12, "Interpolated diffusivity-gradient x component"));
708 PetscCall(PicurvAssertRealNear(0.2, diffusivity_gradient[1], 1.0e-12, "Interpolated diffusivity-gradient y component"));
709 PetscCall(PicurvAssertRealNear(0.3, diffusivity_gradient[2], 1.0e-12, "Interpolated diffusivity-gradient z component"));
710 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
711 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
712 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
713
714 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
715 PetscFunctionReturn(0);
716}
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:139
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 721 of file test_runtime_kernels.c.

722{
723 SimCtx *simCtx = NULL;
724 UserCtx *user = NULL;
725 Cmpnts ***grad = NULL;
726 PetscReal *velocity = NULL;
727 PetscReal *diffusivity = NULL;
728 PetscReal *diffusivity_gradient = NULL;
729
730 PetscFunctionBeginUser;
731 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
733 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
734 PetscCall(VecSet(user->Ucat, 2.0));
735 PetscCall(VecSet(user->Diffusivity, 0.25));
736
737 PetscCall(DMDAVecGetArray(user->fda, user->DiffusivityGradient, &grad));
738 for (PetscInt k = user->info.zs; k < user->info.zs + user->info.zm; ++k) {
739 for (PetscInt j = user->info.ys; j < user->info.ys + user->info.ym; ++j) {
740 for (PetscInt i = user->info.xs; i < user->info.xs + user->info.xm; ++i) {
741 grad[k][j][i].x = 0.1;
742 grad[k][j][i].y = 0.2;
743 grad[k][j][i].z = 0.3;
744 }
745 }
746 }
747 PetscCall(DMDAVecRestoreArray(user->fda, user->DiffusivityGradient, &grad));
748 PetscCall(SyncRuntimeFieldGhosts(user));
749 PetscCall(SeedSingleParticle(user, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ACTIVE_AND_LOCATED));
750
751 PetscCall(InterpolateAllFieldsToSwarm(user));
752
753 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
754 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
755 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
756 PetscCall(PicurvAssertRealNear(2.0, velocity[0], 1.0e-12, "CornerAveraged: interpolated velocity x should match constant Eulerian field"));
757 PetscCall(PicurvAssertRealNear(2.0, velocity[1], 1.0e-12, "CornerAveraged: interpolated velocity y should match constant Eulerian field"));
758 PetscCall(PicurvAssertRealNear(2.0, velocity[2], 1.0e-12, "CornerAveraged: interpolated velocity z should match constant Eulerian field"));
759 PetscCall(PicurvAssertRealNear(0.25, diffusivity[0], 1.0e-12, "CornerAveraged: interpolated scalar diffusivity should match constant Eulerian field"));
760 PetscCall(PicurvAssertRealNear(0.1, diffusivity_gradient[0], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient x component"));
761 PetscCall(PicurvAssertRealNear(0.2, diffusivity_gradient[1], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient y component"));
762 PetscCall(PicurvAssertRealNear(0.3, diffusivity_gradient[2], 1.0e-12, "CornerAveraged: interpolated diffusivity-gradient z component"));
763 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
764 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
765 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocity));
766
767 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
768 PetscFunctionReturn(0);
769}
InterpolationMethod interpolationMethod
Definition variables.h:832
@ INTERP_CORNER_AVERAGED
Definition variables.h:566
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 774 of file test_runtime_kernels.c.

775{
776 SimCtx *simCtx = NULL;
777 UserCtx *user = NULL;
778 PetscInt *cell_ids = NULL;
779 PetscReal *psi = NULL;
780 PetscReal ***psi_grid = NULL;
781
782 PetscFunctionBeginUser;
783 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
784 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
785
786 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
787 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
788 cell_ids[3] = 0; cell_ids[4] = 0; cell_ids[5] = 0;
789 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
790
791 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
792 psi[0] = 1.0;
793 psi[1] = 3.0;
794 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
795
797
798 PetscCall(DMDAVecGetArrayRead(user->da, user->Psi, &psi_grid));
799 PetscCall(PicurvAssertRealNear(2.0, psi_grid[1][1][1], 1.0e-12, "Scatter should average particle Psi values into the owning cell"));
800 PetscCall(DMDAVecRestoreArrayRead(user->da, user->Psi, &psi_grid));
801
802 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
803 PetscFunctionReturn(0);
804}
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 809 of file test_runtime_kernels.c.

810{
811 SimCtx *simCtx = NULL;
812 UserCtx *user = NULL;
813 PetscInt *cell_ids = NULL;
814 PetscReal ***counts = NULL;
815
816 PetscFunctionBeginUser;
817 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
818 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
819
820 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
821 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
822 cell_ids[3] = 0; cell_ids[4] = 0; cell_ids[5] = 0;
823 cell_ids[6] = 1; cell_ids[7] = 0; cell_ids[8] = 0;
824 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
825
826 PetscCall(CalculateParticleCountPerCell(user));
827
828 PetscCall(DMDAVecGetArrayRead(user->da, user->ParticleCount, &counts));
829 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)"));
830 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)"));
831 PetscCall(DMDAVecRestoreArrayRead(user->da, user->ParticleCount, &counts));
832
833 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
834 PetscFunctionReturn(0);
835}
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:996
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 840 of file test_runtime_kernels.c.

841{
842 SimCtx *simCtx = NULL;
843 UserCtx *user = NULL;
844 PetscInt *status = NULL;
845
846 PetscFunctionBeginUser;
847 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
848 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
849
850 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
851 status[0] = ACTIVE_AND_LOCATED;
852 status[1] = LOST;
853 status[2] = NEEDS_LOCATION;
854 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
855
856 PetscCall(ResetAllParticleStatuses(user));
857
858 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
859 PetscCall(PicurvAssertIntEqual(NEEDS_LOCATION, status[0], "ACTIVE_AND_LOCATED particles should be reset to NEEDS_LOCATION"));
860 PetscCall(PicurvAssertIntEqual(LOST, status[1], "LOST particles should remain LOST"));
861 PetscCall(PicurvAssertIntEqual(NEEDS_LOCATION, status[2], "NEEDS_LOCATION particles should remain unchanged"));
862 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
863
864 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
865 PetscFunctionReturn(0);
866}
PetscErrorCode ResetAllParticleStatuses(UserCtx *user)
Marks all local particles as NEEDS_LOCATION for the next settlement pass.
@ LOST
Definition variables.h:141
@ NEEDS_LOCATION
Definition variables.h:138
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 871 of file test_runtime_kernels.c.

872{
873 SimCtx *simCtx = NULL;
874 UserCtx *user = NULL;
875 PetscReal *positions = NULL;
876 PetscInt removed_local = 0;
877 PetscInt removed_global = 0;
878 PetscInt nlocal = 0;
879
880 PetscFunctionBeginUser;
881 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
882 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
883
884 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
885 positions[0] = 0.5; positions[1] = 0.5; positions[2] = 0.5;
886 positions[3] = 9.0; positions[4] = 9.0; positions[5] = 9.0;
887 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
888
889 PetscCall(CheckAndRemoveOutOfBoundsParticles(user, &removed_local, &removed_global, simCtx->bboxlist));
890 PetscCall(DMSwarmGetLocalSize(user->swarm, &nlocal));
891 PetscCall(PicurvAssertIntEqual(1, removed_local, "Exactly one particle should be removed as out-of-bounds on a single rank"));
892 PetscCall(PicurvAssertIntEqual(1, removed_global, "Global out-of-bounds removal count should match the local single-rank result"));
893 PetscCall(PicurvAssertIntEqual(1, nlocal, "One in-bounds particle should remain after out-of-bounds removal"));
894
895 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
896 PetscFunctionReturn(0);
897}
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:830
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 902 of file test_runtime_kernels.c.

903{
904 SimCtx *simCtx = NULL;
905 UserCtx *user = NULL;
906 PetscInt *status = NULL;
907 PetscInt removed_local = 0;
908 PetscInt removed_global = 0;
909 PetscInt nlocal = 0;
910
911 PetscFunctionBeginUser;
912 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
913 PetscCall(PicurvCreateSwarmPair(user, 3, "ske"));
914
915 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
916 status[0] = ACTIVE_AND_LOCATED;
917 status[1] = LOST;
918 status[2] = LOST;
919 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
920
921 PetscCall(CheckAndRemoveLostParticles(user, &removed_local, &removed_global));
922 PetscCall(DMSwarmGetLocalSize(user->swarm, &nlocal));
923 PetscCall(PicurvAssertIntEqual(2, removed_local, "Two LOST particles should be removed locally"));
924 PetscCall(PicurvAssertIntEqual(2, removed_global, "Global LOST-particle removal count should match the local single-rank result"));
925 PetscCall(PicurvAssertIntEqual(1, nlocal, "One non-LOST particle should remain"));
926
927 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
928 PetscFunctionReturn(0);
929}
PetscErrorCode CheckAndRemoveLostParticles(UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal)
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 934 of file test_runtime_kernels.c.

935{
936 SimCtx *simCtx = NULL;
937 UserCtx *user = NULL;
938 char tmpdir[PETSC_MAX_PATH_LEN];
939 Cmpnts first;
940 Cmpnts second;
941
942 PetscFunctionBeginUser;
943 PetscCall(PicurvBuildTinyRuntimeContext(NULL, PETSC_FALSE, &simCtx, &user, tmpdir, sizeof(tmpdir)));
944 simCtx->dt = 0.25;
945 PetscCall(PicurvAssertBool((PetscBool)(simCtx->BrownianMotionRNG != NULL),
946 "runtime setup path should initialize the Brownian RNG"));
947
948 PetscCall(PetscRandomSetSeed(simCtx->BrownianMotionRNG, 12345));
949 PetscCall(PetscRandomSeed(simCtx->BrownianMotionRNG));
950
951 PetscCall(CalculateBrownianDisplacement(user, 0.5, &first));
952 PetscCall(PetscRandomSetSeed(simCtx->BrownianMotionRNG, 12345));
953 PetscCall(PetscRandomSeed(simCtx->BrownianMotionRNG));
954 PetscCall(CalculateBrownianDisplacement(user, 0.5, &second));
955
956 PetscCall(PicurvAssertRealNear(first.x, second.x, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the x displacement"));
957 PetscCall(PicurvAssertRealNear(first.y, second.y, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the y displacement"));
958 PetscCall(PicurvAssertRealNear(first.z, second.z, 1.0e-12, "Resetting the Brownian RNG seed should reproduce the z displacement"));
959
960 PetscCall(PicurvDestroyRuntimeContext(&simCtx));
961 PetscCall(PicurvRemoveTempDir(tmpdir));
962 PetscFunctionReturn(0);
963}
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:841
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 967 of file test_runtime_kernels.c.

968{
969 SimCtx *simCtx = NULL;
970 UserCtx *user = NULL;
971 PetscReal *positions = NULL;
972 PetscReal *velocities = NULL;
973 PetscReal *diffusivity = NULL;
974 Cmpnts *diffusivity_gradient = NULL;
975 PetscReal *psi = NULL;
976 PetscReal *weights = NULL;
977 PetscInt *cell_ids = NULL;
978 PetscInt *status = NULL;
979 PetscInt64 *pid = NULL;
980
981 PetscFunctionBeginUser;
982 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
983 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
984 simCtx->dt = 0.25;
985
986 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
987 PetscCall(DMSwarmGetField(user->swarm, "velocity", NULL, NULL, (void **)&velocities));
988 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
989 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
990 PetscCall(DMSwarmGetField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
991 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
992 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
993 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
994 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
995
996 positions[0] = 0.20; positions[1] = 0.30; positions[2] = 0.40;
997 velocities[0] = 0.40; velocities[1] = -0.20; velocities[2] = 0.10;
998 diffusivity[0] = 0.0;
999 diffusivity_gradient[0].x = 0.10;
1000 diffusivity_gradient[0].y = 0.20;
1001 diffusivity_gradient[0].z = -0.10;
1002 psi[0] = 0.5;
1003 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1004 cell_ids[0] = 0; cell_ids[1] = 0; cell_ids[2] = 0;
1005 status[0] = ACTIVE_AND_LOCATED;
1006 pid[0] = 7;
1007
1008 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1009 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1010 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1011 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1012 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", NULL, NULL, (void **)&psi));
1013 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", NULL, NULL, (void **)&diffusivity_gradient));
1014 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", NULL, NULL, (void **)&diffusivity));
1015 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", NULL, NULL, (void **)&velocities));
1016 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1017
1018 PetscCall(UpdateAllParticlePositions(user));
1019
1020 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1021 PetscCall(PicurvAssertRealNear(0.325, positions[0], 1.0e-12, "UpdateAllParticlePositions should advect x"));
1022 PetscCall(PicurvAssertRealNear(0.300, positions[1], 1.0e-12, "UpdateAllParticlePositions should advect y"));
1023 PetscCall(PicurvAssertRealNear(0.400, positions[2], 1.0e-12, "UpdateAllParticlePositions should advect z"));
1024 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1025
1026 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1027 PetscFunctionReturn(0);
1028}
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 1032 of file test_runtime_kernels.c.

1033{
1034 SimCtx *simCtx = NULL;
1035 UserCtx *user = NULL;
1036 PetscReal *positions = NULL;
1037 PetscReal *weights = NULL;
1038 PetscInt *cell_ids = NULL;
1039 PetscInt *status = NULL;
1040 PetscInt64 *pid = NULL;
1041
1042 PetscFunctionBeginUser;
1043 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1044 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1045 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1046 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1047 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1048 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
1049
1050 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1051 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1052 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1053 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1054 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1055 positions[0] = 0.375; positions[1] = 0.375; positions[2] = 0.375;
1056 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1057 cell_ids[0] = 1; cell_ids[1] = 1; cell_ids[2] = 1;
1058 status[0] = NEEDS_LOCATION;
1059 pid[0] = 11;
1060 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1061 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1062 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1063 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1064 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1065
1066 PetscCall(LocateAllParticlesInGrid(user, simCtx->bboxlist));
1067
1068 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1069 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1070 PetscCall(PicurvAssertIntEqual(1, cell_ids[0], "prior-cell fast path should preserve the i cell id"));
1071 PetscCall(PicurvAssertIntEqual(1, cell_ids[1], "prior-cell fast path should preserve the j cell id"));
1072 PetscCall(PicurvAssertIntEqual(1, cell_ids[2], "prior-cell fast path should preserve the k cell id"));
1073 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status[0], "prior-cell fast path should mark the particle ACTIVE_AND_LOCATED"));
1074 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.searchAttempts, "prior-cell fast path should record one search attempt"));
1075 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchPopulation, "prior-cell fast path should record one input particle"));
1076 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchLocatedCount, "prior-cell fast path should count one located particle"));
1077 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.searchLostCount, "prior-cell fast path should not lose the particle"));
1078 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.reSearchCount, "prior-cell fast path should not re-search on later passes"));
1079 PetscCall(PicurvAssertBool((PetscBool)(simCtx->searchMetrics.traversalStepsSum > 0), "prior-cell fast path should accumulate traversal steps"));
1080 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.maxParticlePassDepth, "prior-cell fast path should report one settlement pass"));
1081 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1082 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1083
1084 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1085 PetscFunctionReturn(0);
1086}
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:2285
PetscInt ys_cell
Definition variables.h:204
PetscInt xs_cell
Definition variables.h:204
PetscInt64 searchLocatedCount
Definition variables.h:241
PetscInt64 searchLostCount
Definition variables.h:242
PetscInt64 traversalStepsSum
Definition variables.h:243
PetscInt zm_cell
Definition variables.h:205
PetscInt zs_cell
Definition variables.h:204
PetscInt64 searchPopulation
Definition variables.h:240
PetscInt64 reSearchCount
Definition variables.h:244
PetscInt xm_cell
Definition variables.h:205
RankCellInfo * RankCellInfoMap
Definition variables.h:995
PetscInt ym_cell
Definition variables.h:205
PetscInt64 maxParticlePassDepth
Definition variables.h:251
SearchMetricsState searchMetrics
Definition variables.h:840
PetscMPIInt size
Definition variables.h:699
PetscInt64 searchAttempts
Definition variables.h:239
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 1090 of file test_runtime_kernels.c.

1091{
1092 SimCtx *simCtx = NULL;
1093 UserCtx *user = NULL;
1094 PetscReal *positions = NULL;
1095 PetscReal *weights = NULL;
1096 PetscInt *cell_ids = NULL;
1097 PetscInt *status = NULL;
1098 PetscInt64 *pid = NULL;
1099
1100 PetscFunctionBeginUser;
1101 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1102 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1103 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1104 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1105 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1106 PetscCall(PicurvCreateSwarmPair(user, 1, "ske"));
1107
1108 PetscCall(DMSwarmGetField(user->swarm, "position", NULL, NULL, (void **)&positions));
1109 PetscCall(DMSwarmGetField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1110 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1111 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1112 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1113 positions[0] = 0.625; positions[1] = 0.625; positions[2] = 0.625;
1114 weights[0] = 0.5; weights[1] = 0.5; weights[2] = 0.5;
1115 cell_ids[0] = -1; cell_ids[1] = -1; cell_ids[2] = -1;
1116 status[0] = NEEDS_LOCATION;
1117 pid[0] = 22;
1118 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_pid", NULL, NULL, (void **)&pid));
1119 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1120 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1121 PetscCall(DMSwarmRestoreField(user->swarm, "weight", NULL, NULL, (void **)&weights));
1122 PetscCall(DMSwarmRestoreField(user->swarm, "position", NULL, NULL, (void **)&positions));
1123
1124 PetscCall(LocateAllParticlesInGrid(user, simCtx->bboxlist));
1125
1126 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1127 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1128 PetscCall(PicurvAssertIntEqual(2, cell_ids[0], "guess-path location should resolve the i cell id"));
1129 PetscCall(PicurvAssertIntEqual(2, cell_ids[1], "guess-path location should resolve the j cell id"));
1130 PetscCall(PicurvAssertIntEqual(2, cell_ids[2], "guess-path location should resolve the k cell id"));
1131 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status[0], "guess-path location should mark the particle ACTIVE_AND_LOCATED"));
1132 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.searchAttempts, "guess-path location should perform one robust search"));
1133 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchPopulation, "guess-path location should count one input particle"));
1134 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchLocatedCount, "guess-path location should count one located particle"));
1135 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.searchLostCount, "guess-path location should not lose the particle"));
1136 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.reSearchCount, "guess-path location should not count later-pass re-searches"));
1137 PetscCall(PicurvAssertIntEqual(1, simCtx->searchMetrics.bboxGuessFallbackCount, "guess-path location should record one bbox fallback"));
1138 PetscCall(PicurvAssertIntEqual(0, simCtx->searchMetrics.bboxGuessSuccessCount, "guess-path local resolution should not count as remote bbox success"));
1139 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", NULL, NULL, (void **)&status));
1140 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", NULL, NULL, (void **)&cell_ids));
1141
1142 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1143 PetscFunctionReturn(0);
1144}
PetscInt64 bboxGuessFallbackCount
Definition variables.h:250
PetscInt64 bboxGuessSuccessCount
Definition variables.h:249
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 1148 of file test_runtime_kernels.c.

1149{
1150 SimCtx *simCtx = NULL;
1151 UserCtx *user = NULL;
1152 Particle particle;
1154
1155 PetscFunctionBeginUser;
1156 PetscCall(PetscMemzero(&particle, sizeof(particle)));
1157 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1158 PetscCall(PetscMalloc1(simCtx->size, &user->RankCellInfoMap));
1159 PetscCall(GetOwnedCellRange(&user->info, 0, &user->RankCellInfoMap[0].xs_cell, &user->RankCellInfoMap[0].xm_cell));
1160 PetscCall(GetOwnedCellRange(&user->info, 1, &user->RankCellInfoMap[0].ys_cell, &user->RankCellInfoMap[0].ym_cell));
1161 PetscCall(GetOwnedCellRange(&user->info, 2, &user->RankCellInfoMap[0].zs_cell, &user->RankCellInfoMap[0].zm_cell));
1162
1164 particle.PID = 33;
1165 particle.cell[0] = 1;
1166 particle.cell[1] = 1;
1167 particle.cell[2] = 1;
1168 particle.loc.x = 0.375;
1169 particle.loc.y = 0.375;
1170 particle.loc.z = 0.375;
1171 particle.weights.x = 0.5;
1172 particle.weights.y = 0.5;
1173 particle.weights.z = 0.5;
1174
1175 PetscCall(LocateParticleOrFindMigrationTarget(user, &particle, &status));
1176
1177 PetscCall(PicurvAssertIntEqual(ACTIVE_AND_LOCATED, status, "direct re-search test should locate the particle"));
1178 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.searchAttempts, "direct re-search test should record one robust walk"));
1179 PetscCall(PicurvAssertIntEqual(1, (PetscInt)simCtx->searchMetrics.reSearchCount, "direct re-search test should increment re_search_count on later passes"));
1180 PetscCall(PicurvAssertIntEqual(0, (PetscInt)simCtx->searchMetrics.maxTraversalFailCount, "direct re-search test should not hit MAX_TRAVERSAL"));
1181
1182 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1183 PetscFunctionReturn(0);
1184}
PetscInt cell[3]
Definition variables.h:184
ParticleLocationStatus
Defines the state of a particle with respect to its location and migration status during the iterativ...
Definition variables.h:137
PetscInt currentSettlementPass
Definition variables.h:252
PetscInt64 PID
Definition variables.h:183
PetscInt64 maxTraversalFailCount
Definition variables.h:246
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 1189 of file test_runtime_kernels.c.

1190{
1191 Cmpnts wall_velocity = {0.0, 0.0, 0.0};
1192 Cmpnts reference_velocity = {2.0, 4.0, 6.0};
1193 Cmpnts boundary_velocity = {0.0, 0.0, 0.0};
1194 Cmpnts free_slip_reference = {2.0, 3.0, 4.0};
1195
1196 PetscFunctionBeginUser;
1197 noslip(NULL, 2.0, 1.0, wall_velocity, reference_velocity, &boundary_velocity, 1.0, 0.0, 0.0);
1198 PetscCall(PicurvAssertRealNear(1.0, boundary_velocity.x, 1.0e-12, "no-slip interpolated x"));
1199 PetscCall(PicurvAssertRealNear(2.0, boundary_velocity.y, 1.0e-12, "no-slip interpolated y"));
1200 PetscCall(PicurvAssertRealNear(3.0, boundary_velocity.z, 1.0e-12, "no-slip interpolated z"));
1201
1202 freeslip(NULL, 2.0, 1.0, wall_velocity, free_slip_reference, &boundary_velocity, 1.0, 0.0, 0.0);
1203 PetscCall(PicurvAssertRealNear(1.0, boundary_velocity.x, 1.0e-12, "free-slip interpolated normal component"));
1204 PetscCall(PicurvAssertRealNear(3.0, boundary_velocity.y, 1.0e-12, "free-slip tangential y preserved"));
1205 PetscCall(PicurvAssertRealNear(4.0, boundary_velocity.z, 1.0e-12, "free-slip tangential z preserved"));
1206 PetscFunctionReturn(0);
1207}
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 1212 of file test_runtime_kernels.c.

1213{
1214 const PetscReal expected_smooth_e = PetscExpReal(0.41 * 5.5);
1215 PetscReal e_coeff = 0.0;
1216 PetscReal utau = 0.0;
1217 PetscReal residual = 0.0;
1218
1219 PetscFunctionBeginUser;
1220 e_coeff = E_coeff(0.1, 0.0, 1.0e-3);
1221 PetscCall(PicurvAssertRealNear(expected_smooth_e, e_coeff, 1.0e-10, "smooth-wall E coefficient"));
1222
1223 utau = find_utau_hydset(1.0e-3, 1.0, 1.0e-2, 0.1, 0.0);
1224 PetscCall(PicurvAssertBool((PetscBool)(utau > 0.0), "friction velocity should remain positive"));
1225 residual = f_hydset(1.0e-3, 1.0, 1.0e-2, utau, 0.0);
1226 PetscCall(PicurvAssertBool((PetscBool)(PetscAbsReal(residual) < 1.0e-5), "Newton solve residual should be small"));
1227
1228 PetscCall(PicurvAssertRealNear(0.0, nu_t(0.0), 1.0e-12, "eddy viscosity ratio at wall"));
1229 PetscCall(PicurvAssertBool((PetscBool)(integrate_1(1.0e-3, 1.0e-2, 0.1, 0) > 0.0), "integral helper should be positive"));
1230 PetscFunctionReturn(0);
1231}
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 1236 of file test_runtime_kernels.c.

1237{
1238 const PetscReal kinematic_viscosity = 1.0e-3;
1239 const PetscReal wall_distance = 2.0e-2;
1240 const PetscReal target_velocity = 1.0;
1241 const PetscReal roughness_length = 1.0e-4;
1242 PetscReal utau_loglaw = 0.0;
1243 PetscReal utau_werner = 0.0;
1244 PetscReal utau_cabot = 0.0;
1245 PetscReal wall_shear_velocity = 0.0;
1246 PetscReal wall_shear_normal = 0.0;
1247
1248 PetscFunctionBeginUser;
1249 utau_loglaw = find_utau_loglaw(target_velocity, wall_distance, roughness_length);
1250 PetscCall(PicurvAssertRealNear(target_velocity, u_loglaw(wall_distance, utau_loglaw, roughness_length), 1.0e-12,
1251 "simple log-law inversion should reconstruct the target velocity"));
1252
1253 utau_werner = find_utau_Werner(kinematic_viscosity, target_velocity, wall_distance, 0.1);
1254 PetscCall(PicurvAssertBool((PetscBool)(utau_werner > 0.0), "Werner-Wengle friction velocity should remain positive"));
1255 PetscCall(PicurvAssertRealNear(target_velocity, u_Werner(kinematic_viscosity, wall_distance, utau_werner), 1.0e-6,
1256 "Werner-Wengle inversion should reconstruct the target velocity"));
1257
1258 find_utau_Cabot(kinematic_viscosity, target_velocity, wall_distance, 0.1, 0.0, 0.0,
1259 &utau_cabot, &wall_shear_velocity, &wall_shear_normal);
1260 PetscCall(PicurvAssertBool((PetscBool)(utau_cabot > 0.0), "Cabot friction velocity should remain positive"));
1261 PetscCall(PicurvAssertRealNear(target_velocity, u_Cabot(kinematic_viscosity, wall_distance, utau_cabot, 0.0, wall_shear_velocity), 1.0e-6,
1262 "Cabot inversion should reconstruct the target velocity when pressure gradient is zero"));
1263 PetscCall(PicurvAssertRealNear(0.0, wall_shear_normal, 1.0e-10,
1264 "zero normal pressure gradient should keep Cabot normal wall shear at zero"));
1265 PetscFunctionReturn(0);
1266}
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_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 find_utau_Werner(double kinematic_viscosity, double velocity, double wall_distance, double initial_guess)
Solves for friction velocity using Werner-Wengle wall function.
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 1270 of file test_runtime_kernels.c.

1271{
1272 SimCtx *simCtx = NULL;
1273 UserCtx *user = NULL;
1274 Cmpnts wall_velocity = {0.0, 0.0, 0.0};
1275 Cmpnts reference_velocity = {0.0, 1.0, 0.0};
1276 Cmpnts boundary_velocity = {0.0, 0.0, 0.0};
1277 PetscReal friction_velocity = 0.0;
1278
1279 PetscFunctionBeginUser;
1280 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1281 simCtx->ren = 1000.0;
1282
1283 wall_function(user, 2.0e-2, 1.0e-2, wall_velocity, reference_velocity, &boundary_velocity, &friction_velocity, 1.0, 0.0, 0.0);
1284 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "Werner wall function should preserve zero normal velocity"));
1285 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y < 1.0), "Werner wall function should damp tangential velocity"));
1286 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "Werner wall function should compute positive friction velocity"));
1287
1288 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);
1289 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "log-law wall function should preserve zero normal velocity"));
1290 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y <= 1.0), "log-law wall function should keep tangential velocity bounded"));
1291 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "log-law wall function should compute positive friction velocity"));
1292
1293 wall_function_Cabot(user, 1.0e-4, 2.0e-2, 1.0e-2, wall_velocity, reference_velocity, &boundary_velocity, &friction_velocity,
1294 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10);
1295 PetscCall(PicurvAssertRealNear(0.0, boundary_velocity.x, 1.0e-12, "Cabot wall function should preserve zero normal velocity"));
1296 PetscCall(PicurvAssertBool((PetscBool)(boundary_velocity.y > 0.0 && boundary_velocity.y <= 1.0), "Cabot wall function should keep tangential velocity bounded"));
1297 PetscCall(PicurvAssertBool((PetscBool)(friction_velocity > 0.0), "Cabot wall function should compute positive friction velocity"));
1298
1299 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1300 PetscFunctionReturn(0);
1301}
PetscReal ren
Definition variables.h:744
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 1306 of file test_runtime_kernels.c.

1307{
1308 SimCtx *simCtx = NULL;
1309 UserCtx *user = NULL;
1310
1311 PetscFunctionBeginUser;
1312 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1313 PetscCall(Validate_DrivenFlowConfiguration(user));
1314 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1315 PetscFunctionReturn(0);
1316}
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:

◆ TestComputeSmagorinskyConstantConstantModel()

static PetscErrorCode TestComputeSmagorinskyConstantConstantModel ( void  )
static

Tests the constant Smagorinsky model helper path.

Definition at line 1321 of file test_runtime_kernels.c.

1322{
1323 SimCtx *simCtx = NULL;
1324 UserCtx *user = NULL;
1325 PetscReal ***lcs = NULL;
1326
1327 PetscFunctionBeginUser;
1328 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1329 PetscCall(DMCreateGlobalVector(user->da, &user->CS));
1330 PetscCall(DMCreateLocalVector(user->da, &user->lCs));
1331 simCtx->step = 2;
1332 simCtx->StartStep = 0;
1333 simCtx->les = CONSTANT_SMAGORINSKY;
1334 simCtx->Const_CS = 0.17;
1335
1336 PetscCall(ComputeSmagorinskyConstant(user));
1337 PetscCall(PicurvAssertVecConstant(user->CS, 0.17, 1.0e-12, "constant Smagorinsky branch should fill CS"));
1338 PetscCall(DMDAVecGetArrayRead(user->da, user->lCs, &lcs));
1339 PetscCall(PicurvAssertRealNear(0.17, lcs[2][2][2], 1.0e-12,
1340 "constant Smagorinsky branch should refresh local CS"));
1341 PetscCall(DMDAVecRestoreArrayRead(user->da, user->lCs, &lcs));
1342
1343 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1344 PetscFunctionReturn(0);
1345}
PetscErrorCode ComputeSmagorinskyConstant(UserCtx *user)
Computes the dynamic Smagorinsky constant (Cs) for the LES model.
Definition les.c:42
@ CONSTANT_SMAGORINSKY
Definition variables.h:522
PetscInt StartStep
Definition variables.h:705
PetscReal Const_CS
Definition variables.h:823
PetscInt step
Definition variables.h:703
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 1350 of file test_runtime_kernels.c.

1351{
1352 SimCtx *simCtx = NULL;
1353 UserCtx *user = NULL;
1354 DM coord_dm = NULL;
1355 PetscInt mx = 0, my = 0, mz = 0;
1356
1357 PetscFunctionBeginUser;
1358 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 6, 4));
1359
1360 PetscCall(DMDAGetInfo(user->da, NULL, &mx, &my, &mz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
1361 PetscCall(PicurvAssertIntEqual(user->IM + 1, mx, "minimal fixture should size da with IM+1 nodes"));
1362 PetscCall(PicurvAssertIntEqual(user->JM + 1, my, "minimal fixture should size da with JM+1 nodes"));
1363 PetscCall(PicurvAssertIntEqual(user->KM + 1, mz, "minimal fixture should size da with KM+1 nodes"));
1364 PetscCall(PicurvAssertIntEqual(mx, user->info.mx, "user->info should be sourced from the production da"));
1365 PetscCall(PicurvAssertIntEqual(my, user->info.my, "user->info my should match the da dimensions"));
1366 PetscCall(PicurvAssertIntEqual(mz, user->info.mz, "user->info mz should match the da dimensions"));
1367
1368 PetscCall(DMGetCoordinateDM(user->da, &coord_dm));
1369 PetscCall(PicurvAssertBool((PetscBool)(coord_dm == user->fda),
1370 "minimal fixture should derive fda from the coordinate-DM path"));
1371
1372 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1373 PetscFunctionReturn(0);
1374}
PetscInt KM
Definition variables.h:920
PetscInt JM
Definition variables.h:920
PetscInt IM
Definition variables.h:920
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 1379 of file test_runtime_kernels.c.

1380{
1381 SimCtx *simCtx = NULL;
1382 UserCtx *user = NULL;
1383 PetscInt bs = 0;
1384 void *field_ptr = NULL;
1385
1386 PetscFunctionBeginUser;
1387 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 4, 4, 4));
1388 PetscCall(PicurvCreateSwarmPair(user, 2, "ske"));
1389
1390 PetscCall(DMSwarmGetField(user->swarm, "position", &bs, NULL, &field_ptr));
1391 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle position"));
1392 PetscCall(PicurvAssertBool((PetscBool)(field_ptr != NULL), "position field should be retrievable"));
1393 PetscCall(DMSwarmRestoreField(user->swarm, "position", &bs, NULL, &field_ptr));
1394
1395 PetscCall(DMSwarmGetField(user->swarm, "velocity", &bs, NULL, &field_ptr));
1396 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle velocity"));
1397 PetscCall(DMSwarmRestoreField(user->swarm, "velocity", &bs, NULL, &field_ptr));
1398
1399 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_CellID", &bs, NULL, &field_ptr));
1400 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register DMSwarm_CellID"));
1401 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_CellID", &bs, NULL, &field_ptr));
1402
1403 PetscCall(DMSwarmGetField(user->swarm, "weight", &bs, NULL, &field_ptr));
1404 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle weight"));
1405 PetscCall(DMSwarmRestoreField(user->swarm, "weight", &bs, NULL, &field_ptr));
1406
1407 PetscCall(DMSwarmGetField(user->swarm, "Diffusivity", &bs, NULL, &field_ptr));
1408 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle diffusivity"));
1409 PetscCall(DMSwarmRestoreField(user->swarm, "Diffusivity", &bs, NULL, &field_ptr));
1410
1411 PetscCall(DMSwarmGetField(user->swarm, "DiffusivityGradient", &bs, NULL, &field_ptr));
1412 PetscCall(PicurvAssertIntEqual(3, bs, "solver swarm should register particle diffusivity gradients"));
1413 PetscCall(DMSwarmRestoreField(user->swarm, "DiffusivityGradient", &bs, NULL, &field_ptr));
1414
1415 PetscCall(DMSwarmGetField(user->swarm, "Psi", &bs, NULL, &field_ptr));
1416 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle scalar Psi"));
1417 PetscCall(DMSwarmRestoreField(user->swarm, "Psi", &bs, NULL, &field_ptr));
1418
1419 PetscCall(DMSwarmGetField(user->swarm, "DMSwarm_location_status", &bs, NULL, &field_ptr));
1420 PetscCall(PicurvAssertIntEqual(1, bs, "solver swarm should register particle location status"));
1421 PetscCall(DMSwarmRestoreField(user->swarm, "DMSwarm_location_status", &bs, NULL, &field_ptr));
1422
1423 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1424 PetscFunctionReturn(0);
1425}
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 1430 of file test_runtime_kernels.c.

1431{
1432 SimCtx *simCtx = NULL;
1433 UserCtx *user = NULL;
1434
1435 PetscFunctionBeginUser;
1436 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 5, 5, 5));
1437
1438 PetscCall(VecSet(user->Ucont, 11.0));
1439 PetscCall(VecSet(user->Ucont_o, 7.0));
1440 PetscCall(VecSet(user->Ucont_rm1, 3.0));
1441 PetscCall(VecSet(user->Ucat, 5.0));
1442 PetscCall(VecSet(user->Ucat_o, -1.0));
1443 PetscCall(VecSet(user->P, 9.0));
1444 PetscCall(VecSet(user->P_o, -2.0));
1445
1446 PetscCall(UpdateSolverHistoryVectors(user, PETSC_FALSE));
1447
1448 PetscCall(PicurvAssertVecConstant(user->Ucont_o, 11.0, 1.0e-12, "Ucont_o should receive current Ucont"));
1449 PetscCall(PicurvAssertVecConstant(user->Ucont_rm1, 7.0, 1.0e-12, "Ucont_rm1 should receive prior Ucont_o"));
1450 PetscCall(PicurvAssertVecConstant(user->Ucat_o, 5.0, 1.0e-12, "Ucat_o should receive current Ucat"));
1451 PetscCall(PicurvAssertVecConstant(user->P_o, 9.0, 1.0e-12, "P_o should receive current P"));
1452 PetscCall(PicurvAssertVecConstant(user->lUcont_o, 11.0, 1.0e-12, "lUcont_o ghost sync should match Ucont_o"));
1453 PetscCall(PicurvAssertVecConstant(user->lUcont_rm1, 7.0, 1.0e-12, "lUcont_rm1 ghost sync should match Ucont_rm1"));
1454
1455 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1456 PetscFunctionReturn(0);
1457}
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:306
Vec lUcont_rm1
Definition variables.h:947
Vec lUcont_o
Definition variables.h:946
Vec Ucat_o
Definition variables.h:946
Vec Ucont_o
Definition variables.h:946
Vec Ucont_rm1
Definition variables.h:947
Vec P_o
Definition variables.h:946
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 1462 of file test_runtime_kernels.c.

1463{
1464 SimCtx *simCtx = NULL;
1465 UserCtx *user = NULL;
1466 PetscInt xs = -1, ys = -1, zs = -1;
1467 PetscInt xm = -1, ym = -1, zm = -1;
1468
1469 PetscFunctionBeginUser;
1470 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 8, 6, 4));
1471
1472 PetscCall(GetOwnedCellRange(&user->info, 0, &xs, &xm));
1473 PetscCall(GetOwnedCellRange(&user->info, 1, &ys, &ym));
1474 PetscCall(GetOwnedCellRange(&user->info, 2, &zs, &zm));
1475
1476 PetscCall(PicurvAssertIntEqual(0, xs, "single-rank x cell-start index"));
1477 PetscCall(PicurvAssertIntEqual(0, ys, "single-rank y cell-start index"));
1478 PetscCall(PicurvAssertIntEqual(0, zs, "single-rank z cell-start index"));
1479 PetscCall(PicurvAssertIntEqual(user->info.mx - 2, xm, "single-rank x owned cell count"));
1480 PetscCall(PicurvAssertIntEqual(user->info.my - 2, ym, "single-rank y owned cell count"));
1481 PetscCall(PicurvAssertIntEqual(user->info.mz - 2, zm, "single-rank z owned cell count"));
1482
1483 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1484 PetscFunctionReturn(0);
1485}
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 1490 of file test_runtime_kernels.c.

1491{
1492 SimCtx *simCtx = NULL;
1493 UserCtx *user = NULL;
1494
1495 PetscFunctionBeginUser;
1496 PetscCall(PicurvCreateMinimalContexts(&simCtx, &user, 6, 6, 6));
1497 PetscCall(ComputeAndStoreNeighborRanks(user));
1498
1499 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_xm, "single-rank xm neighbor should be null"));
1500 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_xp, "single-rank xp neighbor should be null"));
1501 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_ym, "single-rank ym neighbor should be null"));
1502 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_yp, "single-rank yp neighbor should be null"));
1503 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_zm, "single-rank zm neighbor should be null"));
1504 PetscCall(PicurvAssertIntEqual(MPI_PROC_NULL, user->neighbors.rank_zp, "single-rank zp neighbor should be null"));
1505
1506 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
1507 PetscFunctionReturn(0);
1508}
PetscErrorCode ComputeAndStoreNeighborRanks(UserCtx *user)
Computes and stores the Cartesian neighbor ranks for the DMDA decomposition.
Definition setup.c:2382
PetscMPIInt rank_zm
Definition variables.h:199
PetscMPIInt rank_yp
Definition variables.h:198
PetscMPIInt rank_ym
Definition variables.h:198
PetscMPIInt rank_xp
Definition variables.h:197
RankNeighbors neighbors
Definition variables.h:923
PetscMPIInt rank_xm
Definition variables.h:197
PetscMPIInt rank_zp
Definition variables.h:199
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 1513 of file test_runtime_kernels.c.

1514{
1515 PetscReal seconds = 0.0;
1516
1517 PetscFunctionBeginUser;
1518 PetscCall(PicurvAssertBool(RuntimeWalltimeGuardParsePositiveSeconds("300", &seconds), "plain positive seconds should parse"));
1519 PetscCall(PicurvAssertRealNear(300.0, seconds, 1.0e-12, "parsed walltime seconds"));
1520 PetscCall(PicurvAssertBool(RuntimeWalltimeGuardParsePositiveSeconds(" 42.5 ", &seconds), "whitespace-wrapped decimal seconds should parse"));
1521 PetscCall(PicurvAssertRealNear(42.5, seconds, 1.0e-12, "parsed decimal walltime seconds"));
1522 PetscCall(PicurvAssertBool((PetscBool)!RuntimeWalltimeGuardParsePositiveSeconds("nope", &seconds), "non-numeric metadata should fail parsing"));
1523 PetscCall(PicurvAssertBool((PetscBool)!RuntimeWalltimeGuardParsePositiveSeconds("-10", &seconds), "negative metadata should fail parsing"));
1524 PetscFunctionReturn(0);
1525}
PetscBool RuntimeWalltimeGuardParsePositiveSeconds(const char *text, PetscReal *seconds_out)
Parse a positive floating-point seconds value from runtime metadata.
Definition setup.c:20
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 1530 of file test_runtime_kernels.c.

1531{
1532 PetscReal ewma_fast = 0.0;
1533 PetscReal ewma_slow = 0.0;
1534 PetscReal conservative_fast = 0.0;
1535 PetscReal conservative_slow = 0.0;
1536 PetscReal required_headroom = 0.0;
1537
1538 PetscFunctionBeginUser;
1539 ewma_fast = RuntimeWalltimeGuardUpdateEWMA(PETSC_TRUE, 4.0, 6.0, 0.5);
1540 ewma_slow = RuntimeWalltimeGuardUpdateEWMA(PETSC_TRUE, ewma_fast, 12.0, 0.5);
1541 conservative_fast = RuntimeWalltimeGuardConservativeEstimate(5.0, ewma_fast, 6.0);
1542 conservative_slow = RuntimeWalltimeGuardConservativeEstimate(5.0, ewma_slow, 12.0);
1543 required_headroom = RuntimeWalltimeGuardRequiredHeadroom(8.0, 2.0, conservative_slow);
1544
1545 PetscCall(PicurvAssertRealNear(5.0, ewma_fast, 1.0e-12, "EWMA after moderate step"));
1546 PetscCall(PicurvAssertRealNear(8.5, ewma_slow, 1.0e-12, "EWMA after newer slow step"));
1547 PetscCall(PicurvAssertRealNear(6.0, conservative_fast, 1.0e-12, "conservative estimate tracks latest moderate step"));
1548 PetscCall(PicurvAssertRealNear(12.0, conservative_slow, 1.0e-12, "conservative estimate tracks newest slow step"));
1549 PetscCall(PicurvAssertRealNear(24.0, required_headroom, 1.0e-12, "required headroom scales with conservative estimate"));
1550 PetscFunctionReturn(0);
1551}
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:145
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:157
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Compute the required shutdown headroom from timestep estimate and floor.
Definition runloop.c:168
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 1556 of file test_runtime_kernels.c.

1557{
1558 PetscBool should_trigger = PETSC_FALSE;
1559 PetscReal required_headroom = 0.0;
1560
1561 PetscFunctionBeginUser;
1562 should_trigger = RuntimeWalltimeGuardShouldTrigger(9, 10, 15.0, 5.0, 2.0, 6.0, 6.0, 6.0, &required_headroom);
1563 PetscCall(PicurvAssertBool((PetscBool)!should_trigger, "guard should not trigger before warmup completes"));
1564
1565 should_trigger = RuntimeWalltimeGuardShouldTrigger(10, 10, 40.0, 5.0, 2.0, 10.0, 12.0, 14.0, &required_headroom);
1566 PetscCall(PicurvAssertBool((PetscBool)!should_trigger, "guard should not trigger when remaining walltime exceeds required headroom"));
1567 PetscCall(PicurvAssertRealNear(28.0, required_headroom, 1.0e-12, "required headroom after warmup"));
1568
1569 should_trigger = RuntimeWalltimeGuardShouldTrigger(10, 10, 28.0, 5.0, 2.0, 10.0, 12.0, 14.0, &required_headroom);
1570 PetscCall(PicurvAssertBool(should_trigger, "guard should trigger when remaining walltime reaches required headroom"));
1571 PetscCall(PicurvAssertRealNear(28.0, required_headroom, 1.0e-12, "required headroom remains unchanged at trigger threshold"));
1572 PetscFunctionReturn(0);
1573}
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:179
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 1578 of file test_runtime_kernels.c.

1579{
1580 PetscErrorCode ierr;
1581 const PicurvTestCase cases[] = {
1582 {"distribute-particles-remainder-handling", TestDistributeParticlesRemainderHandling},
1583 {"is-particle-inside-bbox-basic-cases", TestIsParticleInsideBoundingBoxBasicCases},
1584 {"update-particle-weights-computes-expected-ratios", TestUpdateParticleWeightsComputesExpectedRatios},
1585 {"update-particle-position-without-brownian-contribution", TestUpdateParticlePositionWithoutBrownianContribution},
1586 {"update-particle-position-diffusivity-gradient-only", TestUpdateParticlePositionDiffusivityGradientOnly},
1587 {"update-particle-field-iem-relaxation", TestUpdateParticleFieldIEMRelaxation},
1588 {"set-initial-interior-field-ignores-non-ucont-request", TestSetInitialInteriorFieldIgnoresNonUcontRequest},
1589 {"set-initial-interior-field-cartesian-constant-sets-contravariant-flux", TestSetInitialInteriorFieldCartesianConstantSetsContravariantFlux},
1590 {"set-initial-interior-field-curvilinear-constant-via-flow-direction", TestSetInitialInteriorFieldCurvilinearConstantViaFlowDirection},
1591 {"set-initial-interior-field-zero-clears-interior", TestSetInitialInteriorFieldZeroClearsInterior},
1592 {"set-initial-interior-field-poiseuille-profile", TestSetInitialInteriorFieldPoiseuilleProfile},
1593 {"cart2contra-converts-cartesian-field", TestCart2ContraConvertsCartesianField},
1594 {"cart2contra-uses-finalized-periodic-ucat", TestCart2ContraUsesFinalizedPeriodicUcat},
1595 {"populate-initial-ucont-loads-staged-ucat", TestPopulateInitialUcontLoadsStagedUcat},
1596 {"write-les-fields-copies-owned-periodic-values", TestWriteLESFieldsCopiesOwnedPeriodicValues},
1597 {"staged-ucat-fourier-modes-use-picurv-discrete-symbol", TestStagedUcatFourierModesUsePicurvDiscreteSymbol},
1598 {"populate-initial-ucont-loads-staged-ucont", TestPopulateInitialUcontLoadsStagedUcont},
1599 {"interpolate-all-fields-to-swarm-constant-fields", TestInterpolateAllFieldsToSwarmConstantFields},
1600 {"interpolate-all-fields-to-swarm-corner-averaged-constant-fields", TestInterpolateAllFieldsToSwarmCornerAveragedConstantFields},
1601 {"scatter-all-particle-fields-to-euler-fields-averages-psi", TestScatterAllParticleFieldsToEulerFieldsAveragesPsi},
1602 {"calculate-particle-count-per-cell-counts-global-cell-ids", TestCalculateParticleCountPerCellCountsGlobalCellIDs},
1603 {"reset-all-particle-statuses-leaves-lost-particles-untouched", TestResetAllParticleStatusesLeavesLostParticlesUntouched},
1604 {"check-and-remove-out-of-bounds-particles-removes-escaped-particle", TestCheckAndRemoveOutOfBoundsParticlesRemovesEscapedParticle},
1605 {"check-and-remove-lost-particles-removes-lost-entries", TestCheckAndRemoveLostParticlesRemovesLostEntries},
1606 {"calculate-brownian-displacement-deterministic-seed", TestCalculateBrownianDisplacementDeterministicSeed},
1607 {"update-all-particle-positions-moves-swarm-entries", TestUpdateAllParticlePositionsMovesSwarmEntries},
1608 {"locate-all-particles-in-grid-prior-cell-fast-path", TestLocateAllParticlesInGridPriorCellFastPath},
1609 {"locate-all-particles-in-grid-guess-path-resolves-local-particle", TestLocateAllParticlesInGridGuessPathResolvesLocalParticle},
1610 {"locate-particle-or-find-migration-target-counts-research", TestLocateParticleOrFindMigrationTargetCountsReSearch},
1611 {"wall-noslip-and-freeslip-helpers", TestWallNoSlipAndFreeSlipHelpers},
1612 {"wall-model-scalar-helpers", TestWallModelScalarHelpers},
1613 {"wall-model-velocity-helpers", TestWallModelVelocityHelpers},
1614 {"wall-function-vector-wrappers", TestWallFunctionVectorWrappers},
1615 {"validate-driven-flow-configuration-no-driven-handlers", TestValidateDrivenFlowConfigurationNoDrivenHandlers},
1616 {"compute-smagorinsky-constant-constant-model", TestComputeSmagorinskyConstantConstantModel},
1617 {"minimal-fixture-mirrors-production-dm-layout", TestMinimalFixtureMirrorsProductionDMLayout},
1618 {"minimal-fixture-registers-production-swarm-fields", TestMinimalFixtureRegistersProductionSwarmFields},
1619 {"update-solver-history-vectors-shifts-states", TestUpdateSolverHistoryVectorsShiftsStates},
1620 {"get-owned-cell-range-single-rank-accounting", TestGetOwnedCellRangeSingleRankAccounting},
1621 {"compute-and-store-neighbor-ranks-single-rank", TestComputeAndStoreNeighborRanksSingleRank},
1622 {"runtime-walltime-guard-parses-positive-seconds", TestRuntimeWalltimeGuardParsesPositiveSeconds},
1623 {"runtime-walltime-guard-estimator-helpers", TestRuntimeWalltimeGuardEstimatorHelpers},
1624 {"runtime-walltime-guard-trigger-decision", TestRuntimeWalltimeGuardTriggerDecision},
1625 };
1626
1627 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv runtime-kernel tests");
1628 if (ierr) {
1629 return (int)ierr;
1630 }
1631
1632 ierr = PicurvRunTests("unit-runtime", cases, sizeof(cases) / sizeof(cases[0]));
1633 if (ierr) {
1634 PetscFinalize();
1635 return (int)ierr;
1636 }
1637
1638 ierr = PetscFinalize();
1639 return (int)ierr;
1640}
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 TestComputeSmagorinskyConstantConstantModel(void)
Tests the constant Smagorinsky model helper path.
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 follows the discrete cross-stream profile and reaches zero at edges.
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: