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 Stage 2 acceptance items in Field Statistics Phase 2 Implementation Specification section 13: 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 20 of file test_statistics_target.c.

◆ TARGET_CELL_EXTENT

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

Definition at line 21 of file test_statistics_target.c.

◆ TARGET_NODE_EXTENT

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

Definition at line 22 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 25 of file test_statistics_target.c.

26{
28
29 PetscFunctionBeginUser;
30 PetscCall(SpatialTargetPlanCreate(user, field_id, PICURV_STATISTICS_MASK_FLUID, &plan));
31 PetscCall(SpatialTargetPlanGlobalPointCount(&plan, PETSC_COMM_WORLD, count));
32 PetscFunctionReturn(0);
33}
@ 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 36 of file test_statistics_target.c.

37{
38 SimCtx *simCtx = NULL;
39 UserCtx *user = NULL;
41 PetscInt local = 0, global = 0;
42
43 PetscFunctionBeginUser;
45
47 PetscCall(PicurvAssertIntEqual(PICURV_TARGET_POINTWISE, plan.kind, "plan kind should be pointwise"));
49 "P should resolve as cell-centered"));
50 /* On one rank the owned range spans the block, so the plan is the layout span. */
51 if (simCtx->size == 1) {
52 for (PetscInt dim = 0; dim < 3; ++dim) {
53 PetscCall(PicurvAssertIntEqual(1, plan.start[dim],
54 "cell-centered span must skip the index-zero dummy slot"));
55 PetscCall(PicurvAssertIntEqual(TARGET_TEST_N, plan.end[dim],
56 "cell-centered span must skip the extra high-side slot"));
57 }
58 }
59 PetscCall(SpatialTargetPlanLocalPointCount(&plan, &local));
60 PetscCall(SpatialTargetPlanGlobalPointCount(&plan, PETSC_COMM_WORLD, &global));
62 "cell-centered global point count"));
63 PetscCall(PicurvAssertBool((PetscBool)(local <= global), "local count cannot exceed global count"));
64
65 /* Vector and scalar cell-centered fields share one domain. */
66 PetscCall(PlanCount(user, FIELD_ID_UCAT, &global));
68 "Ucat shares the cell-centered domain regardless of dof"));
69
70 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
71 PetscFunctionReturn(0);
72}
FieldLayout layout
@ FIELD_LAYOUT_CELL_CENTERED
@ FIELD_ID_UCAT
@ FIELD_ID_P
PicurvTargetKind kind
Spatial mapping; always pointwise in Phase 2.
@ 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:699
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:896
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 75 of file test_statistics_target.c.

76{
77 SimCtx *simCtx = NULL;
78 UserCtx *user = NULL;
79 PetscInt global = 0;
80 const PetscInt cell = TARGET_CELL_EXTENT;
81 const PetscInt node = TARGET_NODE_EXTENT;
82
83 PetscFunctionBeginUser;
85
86 PetscCall(PlanCount(user, FIELD_ID_CSI, &global));
87 PetscCall(PicurvAssertIntEqual(node * cell * cell, global, "I-face domain is node-like in i only"));
88 PetscCall(PlanCount(user, FIELD_ID_ETA, &global));
89 PetscCall(PicurvAssertIntEqual(cell * node * cell, global, "J-face domain is node-like in j only"));
90 PetscCall(PlanCount(user, FIELD_ID_ZET, &global));
91 PetscCall(PicurvAssertIntEqual(cell * cell * node, global, "K-face domain is node-like in k only"));
92 PetscCall(PlanCount(user, FIELD_ID_COORDINATES, &global));
93 PetscCall(PicurvAssertIntEqual(node * node * node, global, "node-centered domain is node-like in all directions"));
94
95 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
96 PetscFunctionReturn(0);
97}
@ 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:439
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 107 of file test_statistics_target.c.

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

153{
154 SimCtx *simCtx = NULL;
155 UserCtx *user = NULL;
157 PetscErrorCode staggered_ierr = 0;
158 PetscErrorCode classify_ierr = 0;
159 PetscBool node_like = PETSC_FALSE;
160
161 PetscFunctionBeginUser;
163
164 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
166 PetscCall(PetscPopErrorHandler());
167 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_WRONGSTATE, staggered_ierr,
168 "Ucont is component-staggered and must not resolve a pointwise domain"));
169
170 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
172 PetscCall(PetscPopErrorHandler());
173 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_WRONGSTATE, classify_ierr,
174 "component-staggered layout has no single per-dimension classification"));
175
176 PetscCall(PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL));
177 classify_ierr = PicurvLayoutDimensionIsNodeLike(FIELD_LAYOUT_CELL_CENTERED, 3, &node_like);
178 PetscCall(PetscPopErrorHandler());
179 PetscCall(PicurvAssertIntEqual(PETSC_ERR_ARG_OUTOFRANGE, classify_ierr,
180 "dimension index outside 0..2 must be rejected"));
181
182 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
183 PetscFunctionReturn(0);
184}
@ 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 187 of file test_statistics_target.c.

188{
189 SimCtx *simCtx = NULL;
190 UserCtx *user = NULL;
192
193 PetscFunctionBeginUser;
196
197 PetscCall(PicurvAssertBool(SpatialTargetPlanMaskAllows(&plan, 0.0),
198 "open fluid must pass the fluid mask"));
199 PetscCall(PicurvAssertBool(SpatialTargetPlanMaskAllows(&plan, 0.05),
200 "values below the threshold must pass the fluid mask"));
201 PetscCall(PicurvAssertBool((PetscBool)!SpatialTargetPlanMaskAllows(&plan, 1.0),
202 "solid cells must fail the fluid mask"));
204 "the threshold itself is excluded, matching the existing Nvert < 0.1 rule"));
205 PetscCall(PicurvAssertBool((PetscBool)!SpatialTargetPlanMaskAllows(NULL, 0.0),
206 "a null plan must not admit points"));
207
208 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
209 PetscFunctionReturn(0);
210}
#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 221 of file test_statistics_target.c.

222{
223 SimCtx *simCtx = NULL;
224 UserCtx *user = NULL;
226
227 PetscFunctionBeginUser;
230
231 for (PetscInt dim = 0; dim < 3; ++dim) {
232 PetscInt origin_start = 0;
233 PetscInt origin_count = 0;
234
235 PetscCall(GetOwnedCellRange(&user->info, dim, &origin_start, &origin_count));
236 /* Shift from origin-node indexing into field-storage indexing. */
237 PetscCall(PicurvAssertIntEqual(origin_start + 1, plan.start[dim],
238 "cell span start must be the owned-cell origin shifted by one"));
239 PetscCall(PicurvAssertIntEqual(origin_start + origin_count + 1, plan.end[dim],
240 "cell span end must be the owned-cell extent shifted by one"));
241 }
242
243 PetscCall(PicurvDestroyMinimalContexts(&simCtx, &user));
244 PetscFunctionReturn(0);
245}
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:2278
DMDALocalInfo info
Definition variables.h:908
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 250 of file test_statistics_target.c.

251{
252 PetscErrorCode ierr;
253 const PicurvTestCase cases[] = {
254 {"cell-centered-excludes-boundary-and-dummy", TestCellCenteredExcludesBoundaryAndDummy},
255 {"face-layouts-node-like-in-own-direction", TestFaceLayoutsAreNodeLikeInOwnDirection},
256 {"periodic-directions-drop-duplicate-plane", TestPeriodicDirectionsDropDuplicatePlane},
257 {"component-staggered-rejected", TestComponentStaggeredRejected},
258 {"fluid-mask-threshold", TestFluidMaskThreshold},
259 {"cell-span-agrees-with-owned-cell-range", TestCellSpanAgreesWithOwnedCellRange},
260 };
261
262 ierr = PetscInitialize(&argc, &argv, NULL, "PICurv spatial target tests");
263 if (ierr) {
264 return (int)ierr;
265 }
266
267 ierr = PicurvRunTests("unit-statistics-target", cases, sizeof(cases) / sizeof(cases[0]));
268 if (ierr) {
269 PetscFinalize();
270 return (int)ierr;
271 }
272
273 ierr = PetscFinalize();
274 return (int)ierr;
275}
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: