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

C unit tests for pointwise spatial target resolution. More...

#include "test_support.h"
#include "statistics_target.h"
#include "setup.h"
Include dependency graph for test_statistics_target.c:

Go to the source code of this file.

Macros

#define TARGET_TEST_N   6 /* fixture size; DMDA is TARGET_TEST_N + 1 per dimension */
 
#define TARGET_CELL_EXTENT   5 /* cell-like span: indices [1, 6) */
 
#define TARGET_NODE_EXTENT   6 /* node-like nonperiodic span: indices [0, 6) */
 

Functions

static PetscErrorCode PlanCount (UserCtx *user, FieldId field_id, PetscInt *count)
 Builds a plan and returns its global point count.
 
static PetscErrorCode TestCellCenteredExcludesBoundaryAndDummy (void)
 Cell-centered fields must exclude the dummy slot and the extra high slot.
 
static PetscErrorCode TestFaceLayoutsAreNodeLikeInOwnDirection (void)
 Each face family is node-like in exactly its own direction.
 
static PetscErrorCode TestPeriodicDirectionsDropDuplicatePlane (void)
 Periodic directions must drop the wrapped duplicate plane.
 
static PetscErrorCode TestComponentStaggeredRejected (void)
 Component-staggered fields cannot share one pointwise domain and are rejected.
 
static PetscErrorCode TestFluidMaskThreshold (void)
 The fluid mask admits fluid cells and rejects blanked ones at the documented threshold.
 
static PetscErrorCode TestCellSpanAgreesWithOwnedCellRange (void)
 The cell-centered span must agree with the existing owned-cell helper.
 
int main (int argc, char **argv)
 Entry point for the spatial target suite.
 

Detailed Description

C unit tests for pointwise spatial target resolution.

Covers the layout acceptance items in 11. How It Is Validated — cell, node, and I/J/K-face layouts, and nonperiodic, mixed, and fully periodic domains with no duplicate planes.

The fixture builds a DMDA of size n + 1 per dimension, so with n = 6 each dimension has seven slots: one extra non-physical high-side slot, and under the solver's shifted convention a boundary/dummy slot at index zero.

Definition in file test_statistics_target.c.

Macro Definition Documentation

◆ TARGET_TEST_N

#define TARGET_TEST_N   6 /* fixture size; DMDA is TARGET_TEST_N + 1 per dimension */

Definition at line 19 of file test_statistics_target.c.

◆ TARGET_CELL_EXTENT

#define TARGET_CELL_EXTENT   5 /* cell-like span: indices [1, 6) */

Definition at line 20 of file test_statistics_target.c.

◆ TARGET_NODE_EXTENT

#define TARGET_NODE_EXTENT   6 /* node-like nonperiodic span: indices [0, 6) */

Definition at line 21 of file test_statistics_target.c.

Function Documentation

◆ PlanCount()

static PetscErrorCode PlanCount ( UserCtx *  user,
FieldId  field_id,
PetscInt *  count 
)
static

Builds a plan and returns its global point count.

Definition at line 24 of file test_statistics_target.c.

25{
27
28 PetscFunctionBeginUser;
29 PetscCall(SpatialTargetPlanCreate(user, field_id, PICURV_STATISTICS_MASK_FLUID, &plan));
30 PetscCall(SpatialTargetPlanGlobalPointCount(&plan, PETSC_COMM_WORLD, count));
31 PetscFunctionReturn(0);
32}
@ PICURV_STATISTICS_MASK_FLUID
PetscErrorCode SpatialTargetPlanGlobalPointCount(const SpatialTargetPlan *plan, MPI_Comm comm, PetscInt *count)
Counts the points contributed across a communicator.
PetscErrorCode SpatialTargetPlanCreate(UserCtx *user, FieldId field_id, PicurvStatisticsMask mask, SpatialTargetPlan *plan)
Resolves the iteration domain for one field on one block.
Resolved iteration domain for one field on one block.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCellCenteredExcludesBoundaryAndDummy()

static PetscErrorCode TestCellCenteredExcludesBoundaryAndDummy ( void  )
static

Cell-centered fields must exclude the dummy slot and the extra high slot.

Definition at line 35 of file test_statistics_target.c.

36{
37 SimCtx *simCtx = NULL;
38 UserCtx *user = NULL;
40 PetscInt local = 0, global = 0;
41
42 PetscFunctionBeginUser;
44
46 PetscCall(PicurvAssertIntEqual(PICURV_TARGET_POINTWISE, plan.kind, "plan kind should be pointwise"));
48 "P should resolve as cell-centered"));
49 /* On one rank the owned range spans the block, so the plan is the layout span. */
50 if (simCtx->size == 1) {
51 for (PetscInt dim = 0; dim < 3; ++dim) {
52 PetscCall(PicurvAssertIntEqual(1, plan.start[dim],
53 "cell-centered span must skip the index-zero dummy slot"));
54 PetscCall(PicurvAssertIntEqual(TARGET_TEST_N, plan.end[dim],
55 "cell-centered span must skip the extra high-side slot"));
56 }
57 }
58 PetscCall(SpatialTargetPlanLocalPointCount(&plan, &local));
59 PetscCall(SpatialTargetPlanGlobalPointCount(&plan, PETSC_COMM_WORLD, &global));
61 "cell-centered global point count"));
62 PetscCall(PicurvAssertBool((PetscBool)(local <= global), "local count cannot exceed global count"));
63
64 /* Vector and scalar cell-centered fields share one domain. */
65 PetscCall(PlanCount(user, FIELD_ID_UCAT, &global));
67 "Ucat shares the cell-centered domain regardless of dof"));
68
69 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
70 PetscFunctionReturn(0);
71}
FieldLayout layout
@ FIELD_LAYOUT_CELL_CENTERED
@ FIELD_ID_UCAT
@ FIELD_ID_P
PicurvTargetKind kind
Spatial mapping; always pointwise.
@ PICURV_TARGET_POINTWISE
PetscInt end[3]
Exclusive end per dimension (i, j, k).
PetscInt start[3]
Inclusive start per dimension (i, j, k).
PetscErrorCode SpatialTargetPlanLocalPointCount(const SpatialTargetPlan *plan, PetscInt *count)
Counts the points this rank contributes.
const FieldDescriptor * descriptor
Catalog metadata for the targeted field.
static PetscErrorCode PlanCount(UserCtx *user, FieldId field_id, PetscInt *count)
Builds a plan and returns its global point count.
#define TARGET_CELL_EXTENT
#define TARGET_TEST_N
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.
PetscErrorCode PicurvAssertIntEqual(PetscInt expected, PetscInt actual, const char *context)
Asserts that two integer values are equal.
PetscErrorCode PicurvAssertBool(PetscBool value, const char *context)
Asserts that one boolean condition is true.
PetscMPIInt size
Definition variables.h:870
The master context for the entire simulation.
Definition variables.h:866
User-defined context containing data specific to a single computational grid level.
Definition variables.h:1073
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestFaceLayoutsAreNodeLikeInOwnDirection()

static PetscErrorCode TestFaceLayoutsAreNodeLikeInOwnDirection ( void  )
static

Each face family is node-like in exactly its own direction.

Definition at line 74 of file test_statistics_target.c.

75{
76 SimCtx *simCtx = NULL;
77 UserCtx *user = NULL;
78 PetscInt global = 0;
79 const PetscInt cell = TARGET_CELL_EXTENT;
80 const PetscInt node = TARGET_NODE_EXTENT;
81
82 PetscFunctionBeginUser;
84
85 PetscCall(PlanCount(user, FIELD_ID_CSI, &global));
86 PetscCall(PicurvAssertIntEqual(node * cell * cell, global, "I-face domain is node-like in i only"));
87 PetscCall(PlanCount(user, FIELD_ID_ETA, &global));
88 PetscCall(PicurvAssertIntEqual(cell * node * cell, global, "J-face domain is node-like in j only"));
89 PetscCall(PlanCount(user, FIELD_ID_ZET, &global));
90 PetscCall(PicurvAssertIntEqual(cell * cell * node, global, "K-face domain is node-like in k only"));
91 PetscCall(PlanCount(user, FIELD_ID_COORDINATES, &global));
92 PetscCall(PicurvAssertIntEqual(node * node * node, global, "node-centered domain is node-like in all directions"));
93
94 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
95 PetscFunctionReturn(0);
96}
@ FIELD_ID_CSI
@ FIELD_ID_COORDINATES
@ FIELD_ID_ETA
@ FIELD_ID_ZET
#define TARGET_NODE_EXTENT
A generic C-style linked list node for integers.
Definition variables.h:470
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestPeriodicDirectionsDropDuplicatePlane()

static PetscErrorCode TestPeriodicDirectionsDropDuplicatePlane ( void  )
static

Periodic directions must drop the wrapped duplicate plane.

The periodic repair algorithms write index zero and the final slot from the opposite side, so both are dependent duplicates. A node-like direction therefore loses one entry under periodicity, while a cell-like direction is unchanged because its duplicates were already outside the span.

Definition at line 106 of file test_statistics_target.c.

107{
108 SimCtx *simCtx = NULL;
109 UserCtx *user = NULL;
110 PetscInt global = 0;
111 const PetscInt cell = TARGET_CELL_EXTENT;
112 const PetscInt node = TARGET_NODE_EXTENT;
113
114 PetscFunctionBeginUser;
115 /* Mixed: periodic in i only. */
116 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(&simCtx, &user,
118 PETSC_TRUE, PETSC_FALSE, PETSC_FALSE));
119 PetscCall(PlanCount(user, FIELD_ID_P, &global));
120 PetscCall(PicurvAssertIntEqual(cell * cell * cell, global,
121 "cell-centered count is unchanged by periodicity"));
122 PetscCall(PlanCount(user, FIELD_ID_CSI, &global));
123 PetscCall(PicurvAssertIntEqual(cell * cell * cell, global,
124 "I-face loses its duplicate plane when i is periodic"));
125 PetscCall(PlanCount(user, FIELD_ID_ETA, &global));
126 PetscCall(PicurvAssertIntEqual(cell * node * cell, global,
127 "J-face keeps its node-like span when only i is periodic"));
128 PetscCall(PlanCount(user, FIELD_ID_COORDINATES, &global));
129 PetscCall(PicurvAssertIntEqual(cell * node * node, global,
130 "node-centered loses only the periodic direction"));
131 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
132
133 /* Fully periodic: every node-like direction collapses to the cell extent. */
134 PetscCall(PicurvCreateMinimalContextsWithPeriodicity(&simCtx, &user,
136 PETSC_TRUE, PETSC_TRUE, PETSC_TRUE));
137 PetscCall(PlanCount(user, FIELD_ID_COORDINATES, &global));
138 PetscCall(PicurvAssertIntEqual(cell * cell * cell, global,
139 "fully periodic node-centered domain has no duplicate planes"));
140 PetscCall(PlanCount(user, FIELD_ID_CSI, &global));
141 PetscCall(PicurvAssertIntEqual(cell * cell * cell, global,
142 "fully periodic I-face domain has no duplicate planes"));
143 PetscCall(PlanCount(user, FIELD_ID_P, &global));
144 PetscCall(PicurvAssertIntEqual(cell * cell * cell, global,
145 "fully periodic cell-centered domain is unchanged"));
146 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
147 PetscFunctionReturn(0);
148}
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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestComponentStaggeredRejected()

static PetscErrorCode TestComponentStaggeredRejected ( void  )
static

Component-staggered fields cannot share one pointwise domain and are rejected.

Definition at line 151 of file test_statistics_target.c.

152{
153 SimCtx *simCtx = NULL;
154 UserCtx *user = NULL;
156 PetscErrorCode staggered_ierr = 0;
157 PetscErrorCode classify_ierr = 0;
158 PetscBool node_like = PETSC_FALSE;
159
160 PetscFunctionBeginUser;
162
163 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
165 PetscCall(PetscPopErrorHandler());
166 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_WRONGSTATE, staggered_ierr,
167 "Ucont is component-staggered and must not resolve a pointwise domain"));
168
169 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
171 PetscCall(PetscPopErrorHandler());
172 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_WRONGSTATE, classify_ierr,
173 "component-staggered layout has no single per-dimension classification"));
174
175 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
176 classify_ierr = PicurvLayoutDimensionIsNodeLike(FIELD_LAYOUT_CELL_CENTERED, 3, &node_like);
177 PetscCall(PetscPopErrorHandler());
178 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_OUTOFRANGE, classify_ierr,
179 "dimension index outside 0..2 must be rejected"));
180
181 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
182 PetscFunctionReturn(0);
183}
@ FIELD_LAYOUT_COMPONENT_STAGGERED
@ FIELD_ID_UCONT
PetscErrorCode PicurvLayoutDimensionIsNodeLike(FieldLayout layout, PetscInt dim, PetscBool *node_like)
Reports whether a layout is node-like in one dimension.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestFluidMaskThreshold()

static PetscErrorCode TestFluidMaskThreshold ( void  )
static

The fluid mask admits fluid cells and rejects blanked ones at the documented threshold.

Definition at line 186 of file test_statistics_target.c.

187{
188 SimCtx *simCtx = NULL;
189 UserCtx *user = NULL;
191
192 PetscFunctionBeginUser;
195
196 PetscCall(PicurvAssertBool(SpatialTargetPlanMaskAllows(&plan, 0.0),
197 "open fluid must pass the fluid mask"));
198 PetscCall(PicurvAssertBool(SpatialTargetPlanMaskAllows(&plan, 0.05),
199 "values below the threshold must pass the fluid mask"));
200 PetscCall(PicurvAssertBool((PetscBool)!SpatialTargetPlanMaskAllows(&plan, 1.0),
201 "solid cells must fail the fluid mask"));
203 "the threshold itself is excluded, matching the existing Nvert < 0.1 rule"));
204 PetscCall(PicurvAssertBool((PetscBool)!SpatialTargetPlanMaskAllows(NULL, 0.0),
205 "a null plan must not admit points"));
206
207 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
208 PetscFunctionReturn(0);
209}
#define PICURV_STATISTICS_FLUID_THRESHOLD
Threshold below which a cell counts as fluid for the default mask.
PetscBool SpatialTargetPlanMaskAllows(const SpatialTargetPlan *plan, PetscReal nvert_value)
Reports whether a point passes the plan's mask.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TestCellSpanAgreesWithOwnedCellRange()

static PetscErrorCode TestCellSpanAgreesWithOwnedCellRange ( void  )
static

The cell-centered span must agree with the existing owned-cell helper.

GetOwnedCellRange reports cells by their origin node index, while field storage uses the solver's shifted convention where the cell with origin j lives at array index j + 1. The two therefore describe the same cells in different index spaces. This pins that relationship so the target plan and the established helper cannot drift apart.

Definition at line 220 of file test_statistics_target.c.

221{
222 SimCtx *simCtx = NULL;
223 UserCtx *user = NULL;
225
226 PetscFunctionBeginUser;
229
230 for (PetscInt dim = 0; dim < 3; ++dim) {
231 PetscInt origin_start = 0;
232 PetscInt origin_count = 0;
233
234 PetscCall(GetOwnedCellRange(&user->info, dim, &origin_start, &origin_count));
235 /* Shift from origin-node indexing into field-storage indexing. */
236 PetscCall(PicurvAssertIntEqual(origin_start + 1, plan.start[dim],
237 "cell span start must be the owned-cell origin shifted by one"));
238 PetscCall(PicurvAssertIntEqual(origin_start + origin_count + 1, plan.end[dim],
239 "cell span end must be the owned-cell extent shifted by one"));
240 }
241
242 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
243 PetscFunctionReturn(0);
244}
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:2976
DMDALocalInfo info
Definition variables.h:1085
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Entry point for the spatial target suite.

Definition at line 249 of file test_statistics_target.c.

250{
251 PetscErrorCode ierr;
252 const PicurvTestCase cases[] = {
253 {"cell-centered-excludes-boundary-and-dummy", TestCellCenteredExcludesBoundaryAndDummy},
254 {"face-layouts-node-like-in-own-direction", TestFaceLayoutsAreNodeLikeInOwnDirection},
255 {"periodic-directions-drop-duplicate-plane", TestPeriodicDirectionsDropDuplicatePlane},
256 {"component-staggered-rejected", TestComponentStaggeredRejected},
257 {"fluid-mask-threshold", TestFluidMaskThreshold},
258 {"cell-span-agrees-with-owned-cell-range", TestCellSpanAgreesWithOwnedCellRange},
259 };
260
261 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv spatial target tests");
262 if (ierr) {
263 return (int)ierr;
264 }
265
266 ierr = PicurvRunTests("unit-statistics-target", cases, sizeof(cases) / sizeof(cases[0]));
267 if (ierr) {
268 PetscFinalize();
269 return (int)ierr;
270 }
271
272 ierr = PetscFinalize();
273 return (int)ierr;
274}
static PetscErrorCode TestComponentStaggeredRejected(void)
Component-staggered fields cannot share one pointwise domain and are rejected.
static PetscErrorCode TestPeriodicDirectionsDropDuplicatePlane(void)
Periodic directions must drop the wrapped duplicate plane.
static PetscErrorCode TestCellCenteredExcludesBoundaryAndDummy(void)
Cell-centered fields must exclude the dummy slot and the extra high slot.
static PetscErrorCode TestFaceLayoutsAreNodeLikeInOwnDirection(void)
Each face family is node-like in exactly its own direction.
static PetscErrorCode TestFluidMaskThreshold(void)
The fluid mask admits fluid cells and rejects blanked ones at the documented threshold.
static PetscErrorCode TestCellSpanAgreesWithOwnedCellRange(void)
The cell-centered span must agree with the existing owned-cell helper.
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: