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

Window lifecycle, scheduling, and weighting for the field-statistics pipeline. More...

#include "statistics_window.h"
#include "variables.h"
#include "logging.h"
#include "statistics_accumulator.h"
#include "field_catalog.h"
#include "checksum.h"
Include dependency graph for statistics_window.c:

Go to the source code of this file.

Macros

#define WINDOW_TIME_EPSILON   1.0e-12
 Tolerance for treating two physical times as the same instant.
 

Functions

const char * PicurvWindowStateName (PicurvWindowState state)
 Implementation of PicurvWindowStateName().
 
PetscErrorCode PicurvWindowInit (PicurvWindow *window, const PicurvWindowDefinition *definition)
 Implementation of PicurvWindowInit().
 
static PetscBool WindowStateIsDue (const PicurvWindow *window, PetscInt step, PetscReal time)
 Internal helper: reports whether a state is due under the window's schedule.
 
static void WindowAdvanceTimeTarget (PicurvWindow *window, PetscReal time)
 Internal helper: advances the time-cadence target past the accepted time.
 
PetscErrorCode PicurvWindowOfferState (PicurvWindow *window, PetscInt step, PetscReal time, PetscBool *accepted, PetscReal *weight)
 Implementation of PicurvWindowOfferState().
 
const char * PicurvWindowHashGroupName (PetscInt group)
 Implementation of PicurvWindowHashGroupName().
 
static void SortRequestOrder (PetscInt count, const PetscInt *primary, const PetscInt *secondary, PetscInt *order)
 Internal helper: orders request indices so listing order cannot change the hash.
 
PetscErrorCode PicurvWindowComputeHash (const PicurvWindowDefinition *definition, char digest_hex[65], char group_digest_hex[][PICURV_WINDOW_HASH_GROUP_LENGTH])
 Implementation of PicurvWindowComputeHash().
 
PetscErrorCode PicurvWindowFirstHashDifference (const PicurvWindowDefinition *definition, const char *saved_group_digests, PetscInt *group)
 Implementation of PicurvWindowFirstHashDifference().
 
PetscReal PicurvWindowProgress (const PicurvWindow *window)
 Implementation of PicurvWindowProgress().
 
PetscBool FieldStatisticsIsActive (const SimCtx *simCtx)
 Implementation of FieldStatisticsIsActive().
 
PetscErrorCode FieldStatisticsUpdateWindows (SimCtx *simCtx, PetscInt step, PetscReal time)
 Implementation of FieldStatisticsUpdateWindows().
 

Variables

static const char *const kHashGroupNames [PICURV_WINDOW_HASH_GROUP_COUNT]
 Stable names of the hashed property groups, in serialization order.
 

Detailed Description

Window lifecycle, scheduling, and weighting for the field-statistics pipeline.

Full API contract is documented with the declarations in include/statistics_window.h.

Definition in file statistics_window.c.

Macro Definition Documentation

◆ WINDOW_TIME_EPSILON

#define WINDOW_TIME_EPSILON   1.0e-12

Tolerance for treating two physical times as the same instant.

Definition at line 17 of file statistics_window.c.

Function Documentation

◆ PicurvWindowStateName()

const char * PicurvWindowStateName ( PicurvWindowState  state)

Implementation of PicurvWindowStateName().

Returns a stable human-readable name for a window state.

See also
PicurvWindowStateName()

Definition at line 23 of file statistics_window.c.

24{
25 switch (state) {
26 case PICURV_WINDOW_PENDING: return "pending";
27 case PICURV_WINDOW_ACTIVE: return "active";
28 case PICURV_WINDOW_COMPLETE: return "complete";
29 default: return "unknown";
30 }
31}
@ PICURV_WINDOW_PENDING
Requested start not yet reached.
@ PICURV_WINDOW_COMPLETE
Bounded end reached; accepts nothing further.
@ PICURV_WINDOW_ACTIVE
Accepting due states.
Here is the caller graph for this function:

◆ PicurvWindowInit()

PetscErrorCode PicurvWindowInit ( PicurvWindow window,
const PicurvWindowDefinition definition 
)

Implementation of PicurvWindowInit().

Validates a definition and initializes a window to the pending state.

See also
PicurvWindowInit()

Definition at line 37 of file statistics_window.c.

38{
39 PetscFunctionBeginUser;
40 PetscCheck(window != NULL && definition != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
41 "Window and definition are required.");
42 PetscCheck(definition->name[0] != '\0', PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
43 "Window name must not be empty.");
44 if (definition->cadence_kind == PICURV_CADENCE_STEP) {
45 PetscCheck(definition->step_cadence > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
46 "Window '%s' needs a positive step cadence, got %" PetscInt_FMT ".",
47 definition->name, definition->step_cadence);
48 } else {
49 PetscCheck(definition->time_cadence > 0.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
50 "Window '%s' needs a positive time cadence, got %g.",
51 definition->name, (double)definition->time_cadence);
52 }
53 PetscCheck(!definition->bounded || definition->end_time > definition->start_time,
54 PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
55 "Window '%s' must end after it starts.", definition->name);
56
57 PetscCall(PetscMemzero(window, sizeof(*window)));
58 window->definition = *definition;
60 /* Anchoring the interval origin at the requested start, rather than at the
61 * first accepted state, is what lets the first sample represent the interval
62 * back to the requested bound instead of silently dropping it. */
63 window->effective_start = definition->start_time;
64 window->effective_end = definition->start_time;
65 window->last_accepted_time = definition->start_time;
66 window->activation_step = -1;
67 window->last_event_step = PETSC_MIN_INT;
68 window->next_time_target = 0;
69 PetscFunctionReturn(0);
70}
PetscInt last_event_step
Guards against a step being offered twice.
PetscReal effective_start
Origin of the first represented interval.
PetscReal last_accepted_time
Right edge of the last represented interval.
PicurvWindowState state
PetscReal time_cadence
Used when cadence_kind is time; must be positive.
PetscReal effective_end
End of the last represented interval.
PetscReal end_time
Requested end; ignored when bounded is false.
PicurvCadenceKind cadence_kind
PetscInt step_cadence
Used when cadence_kind is step; must be positive.
PetscBool bounded
False for an open-ended window.
PicurvWindowDefinition definition
PetscInt next_time_target
k in effective_start + k*time_cadence.
PetscReal start_time
Requested start.
PetscInt activation_step
Step at which the window became active.
@ PICURV_CADENCE_STEP
Every n completed steps from activation.
Here is the caller graph for this function:

◆ WindowStateIsDue()

static PetscBool WindowStateIsDue ( const PicurvWindow window,
PetscInt  step,
PetscReal  time 
)
static

Internal helper: reports whether a state is due under the window's schedule.

Local to this translation unit. Advances no state.

Definition at line 76 of file statistics_window.c.

77{
79 /* The activation step is itself due; subsequent ones follow the stride. */
80 if (window->activation_step < 0) return PETSC_TRUE;
81 return (PetscBool)(((step - window->activation_step) % window->definition.step_cadence) == 0);
82 }
83 /* Time cadence: targets sit on the absolute grid effective_start + k*cadence, so
84 * the schedule cannot drift as dt varies. A state is due once it reaches the
85 * next outstanding target. */
86 {
87 const PetscReal target = window->effective_start +
88 (PetscReal)window->next_time_target * window->definition.time_cadence;
89 return (PetscBool)(time >= target - WINDOW_TIME_EPSILON);
90 }
91}
#define WINDOW_TIME_EPSILON
Tolerance for treating two physical times as the same instant.
Here is the caller graph for this function:

◆ WindowAdvanceTimeTarget()

static void WindowAdvanceTimeTarget ( PicurvWindow window,
PetscReal  time 
)
static

Internal helper: advances the time-cadence target past the accepted time.

Local to this translation unit. A single large step may overshoot several targets; they are consumed at once, because the accepted state's weight is the actual elapsed interval and so already accounts for the whole span.

Definition at line 99 of file statistics_window.c.

100{
101 if (window->definition.cadence_kind != PICURV_CADENCE_TIME) return;
102 while (window->effective_start +
103 (PetscReal)window->next_time_target * window->definition.time_cadence
104 <= time + WINDOW_TIME_EPSILON) {
105 window->next_time_target += 1;
106 }
107}
@ PICURV_CADENCE_TIME
First state at or past each nominal time target.
Here is the caller graph for this function:

◆ PicurvWindowOfferState()

PetscErrorCode PicurvWindowOfferState ( PicurvWindow window,
PetscInt  step,
PetscReal  time,
PetscBool *  accepted,
PetscReal *  weight 
)

Implementation of PicurvWindowOfferState().

Offers one completed state to a window and reports the decision.

See also
PicurvWindowOfferState()

Definition at line 113 of file statistics_window.c.

115{
116 PetscReal interval = 0.0;
117 PetscReal right_edge = 0.0;
118 PetscBool closes = PETSC_FALSE;
119
120 PetscFunctionBeginUser;
121 PetscCheck(window != NULL && accepted != NULL && weight != NULL,
122 PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
123 "Window, acceptance flag, and weight output are required.");
124 *accepted = PETSC_FALSE;
125 *weight = 0.0;
126
127 if (window->state == PICURV_WINDOW_COMPLETE) PetscFunctionReturn(0);
128 /* A completed state is accepted at most once, so a step already seen is
129 * rejected outright rather than double counted. */
130 if (step == window->last_event_step) PetscFunctionReturn(0);
131 if (time < window->definition.start_time - WINDOW_TIME_EPSILON) PetscFunctionReturn(0);
132
133 /* First observation: a window resumed later than its requested start cannot
134 * claim represented time it never saw, so the origin moves forward. */
135 if (window->state == PICURV_WINDOW_PENDING) {
136 if (time > window->definition.start_time + WINDOW_TIME_EPSILON) {
137 window->effective_start = time;
138 window->last_accepted_time = time;
139 }
140 window->state = PICURV_WINDOW_ACTIVE;
141 window->activation_step = step;
142 window->effective_end = window->effective_start;
143 window->next_time_target = 0;
145 }
146
147 if (!WindowStateIsDue(window, step, time)) {
148 /* An active off-schedule state changes no scientific state. */
149 PetscFunctionReturn(0);
150 }
151 window->last_event_step = step;
152
153 /* Clip the final represented interval to the requested bound. */
154 right_edge = time;
155 if (window->definition.bounded && time >= window->definition.end_time - WINDOW_TIME_EPSILON) {
156 right_edge = window->definition.end_time;
157 closes = PETSC_TRUE;
158 }
159
160 interval = right_edge - window->last_accepted_time;
161 WindowAdvanceTimeTarget(window, time);
162
163 if (interval <= WINDOW_TIME_EPSILON) {
164 /* A zero-length interval is not a sample. It still anchors the origin, which
165 * is what makes initial-state handling identical under both weightings. */
166 window->last_accepted_time = right_edge;
167 window->effective_end = right_edge;
168 if (closes) window->state = PICURV_WINDOW_COMPLETE;
169 PetscFunctionReturn(0);
170 }
171
172 *weight = (window->definition.weighting == PICURV_WEIGHTING_SAMPLE) ? 1.0 : interval;
173 *accepted = PETSC_TRUE;
174
175 window->last_accepted_time = right_edge;
176 window->effective_end = right_edge;
177 window->sample_count += 1;
178 window->total_weight += *weight;
179 window->represented_time += interval;
180 if (closes) window->state = PICURV_WINDOW_COMPLETE;
181 PetscFunctionReturn(0);
182}
static void WindowAdvanceTimeTarget(PicurvWindow *window, PetscReal time)
Internal helper: advances the time-cadence target past the accepted time.
static PetscBool WindowStateIsDue(const PicurvWindow *window, PetscInt step, PetscReal time)
Internal helper: reports whether a state is due under the window's schedule.
PetscInt sample_count
PetscReal total_weight
@ PICURV_WEIGHTING_SAMPLE
Equal weight per accepted state.
PetscReal represented_time
Physical time the window covers.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PicurvWindowHashGroupName()

const char * PicurvWindowHashGroupName ( PetscInt  group)

Implementation of PicurvWindowHashGroupName().

Returns the stable name of one hashed property group.

See also
PicurvWindowHashGroupName()

Definition at line 193 of file statistics_window.c.

194{
195 if (group < 0 || group >= PICURV_WINDOW_HASH_GROUP_COUNT) return "unknown";
196 return kHashGroupNames[group];
197}
static const char *const kHashGroupNames[PICURV_WINDOW_HASH_GROUP_COUNT]
Stable names of the hashed property groups, in serialization order.
#define PICURV_WINDOW_HASH_GROUP_COUNT
Number of independently hashed property groups in a window definition.
Here is the caller graph for this function:

◆ SortRequestOrder()

static void SortRequestOrder ( PetscInt  count,
const PetscInt *  primary,
const PetscInt *  secondary,
PetscInt *  order 
)
static

Internal helper: orders request indices so listing order cannot change the hash.

Local to this translation unit. Insertion sort over at most PICURV_WINDOW_MAX_REQUESTS entries, keyed on a primary and secondary integer so the same routine serves both fields and covariance pairs.

Definition at line 205 of file statistics_window.c.

207{
208 for (PetscInt n = 0; n < count; ++n) order[n] = n;
209 for (PetscInt n = 1; n < count; ++n) {
210 const PetscInt candidate = order[n];
211 PetscInt m = n - 1;
212
213 while (m >= 0 &&
214 (primary[order[m]] > primary[candidate] ||
215 (primary[order[m]] == primary[candidate] &&
216 secondary[order[m]] > secondary[candidate]))) {
217 order[m + 1] = order[m];
218 --m;
219 }
220 order[m + 1] = candidate;
221 }
222}
Here is the caller graph for this function:

◆ PicurvWindowComputeHash()

PetscErrorCode PicurvWindowComputeHash ( const PicurvWindowDefinition definition,
char  digest_hex[65],
char  group_digest_hex[][PICURV_WINDOW_HASH_GROUP_LENGTH] 
)

Implementation of PicurvWindowComputeHash().

See also
PicurvWindowComputeHash()

Definition at line 228 of file statistics_window.c.

231{
233 PetscInt field_primary[PICURV_WINDOW_MAX_REQUESTS];
234 PetscInt field_secondary[PICURV_WINDOW_MAX_REQUESTS];
235 PetscInt field_order[PICURV_WINDOW_MAX_REQUESTS];
236 PetscInt pair_primary[PICURV_WINDOW_MAX_REQUESTS];
237 PetscInt pair_secondary[PICURV_WINDOW_MAX_REQUESTS];
238 PetscInt pair_order[PICURV_WINDOW_MAX_REQUESTS];
239
240 PetscFunctionBeginUser;
241 PetscCheck(definition != NULL && digest_hex != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
242 "Definition and digest output are required.");
243 PetscCheck(definition->field_count >= 0 && definition->field_count <= PICURV_WINDOW_MAX_REQUESTS,
244 PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
245 "Window '%s' requests %" PetscInt_FMT " fields; at most %d are supported.",
246 definition->name, definition->field_count, PICURV_WINDOW_MAX_REQUESTS);
247 PetscCheck(definition->covariance_count >= 0 &&
249 PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
250 "Window '%s' requests %" PetscInt_FMT " covariances; at most %d are supported.",
251 definition->name, definition->covariance_count, PICURV_WINDOW_MAX_REQUESTS);
252
253 for (PetscInt field_index = 0; field_index < definition->field_count; ++field_index) {
254 field_primary[field_index] = definition->fields[field_index].field_id;
255 field_secondary[field_index] = 0;
256 }
257 SortRequestOrder(definition->field_count, field_primary, field_secondary, field_order);
258 for (PetscInt pair_index = 0; pair_index < definition->covariance_count; ++pair_index) {
259 const PetscInt a = definition->covariances[pair_index].first;
260 const PetscInt b = definition->covariances[pair_index].second;
261
262 /* Covariance is symmetric, so the pair is canonicalized here rather than
263 * requiring the user to list its members in catalog order. */
264 pair_primary[pair_index] = PetscMin(a, b);
265 pair_secondary[pair_index] = PetscMax(a, b);
266 }
267 SortRequestOrder(definition->covariance_count, pair_primary, pair_secondary, pair_order);
268
269 PicurvSHA256Init(&whole);
270 for (PetscInt group = 0; group < PICURV_WINDOW_HASH_GROUP_COUNT; ++group) {
271 char text[1024];
272 char group_digest[65];
274 size_t used = 0;
275 size_t length = 0;
276
277 text[0] = '\0';
278 switch (group) {
279 case 0:
280 PetscCall(PetscSNPrintf(text, sizeof(text), "name=%s\n", definition->name));
281 break;
282 case 1:
283 PetscCall(PetscSNPrintf(text, sizeof(text), "start_time=%.17g\n",
284 (double)definition->start_time));
285 break;
286 case 2:
287 PetscCall(PetscSNPrintf(text, sizeof(text), "weighting=%s\n",
289 ? "sample" : "physical_time"));
290 break;
291 case 3:
292 if (definition->cadence_kind == PICURV_CADENCE_STEP) {
293 PetscCall(PetscSNPrintf(text, sizeof(text), "cadence=step:%" PetscInt_FMT "\n",
294 definition->step_cadence));
295 } else {
296 PetscCall(PetscSNPrintf(text, sizeof(text), "cadence=time:%.17g\n",
297 (double)definition->time_cadence));
298 }
299 break;
300 case 4:
301 for (PetscInt n = 0; n < definition->field_count; ++n) {
302 const PicurvWindowFieldRequest *request = &definition->fields[field_order[n]];
303 const char *name = FieldCanonicalName((FieldId)request->field_id);
304
305 PetscCheck(name != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
306 "Window '%s' requests unknown field id %" PetscInt_FMT ".",
307 definition->name, request->field_id);
308 PetscCall(PetscStrlen(text, &used));
309 PetscCall(PetscSNPrintf(text + used, sizeof(text) - used, "field=%s:%s\n",
310 name, request->want_second ? "first,second" : "first"));
311 }
312 break;
313 case 5:
314 for (PetscInt n = 0; n < definition->covariance_count; ++n) {
315 const PetscInt index = pair_order[n];
316 const char *first = FieldCanonicalName((FieldId)pair_primary[index]);
317 const char *second = FieldCanonicalName((FieldId)pair_secondary[index]);
318
319 PetscCheck(first != NULL && second != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
320 "Window '%s' requests a covariance over an unknown field id.",
321 definition->name);
322 PetscCall(PetscStrlen(text, &used));
323 PetscCall(PetscSNPrintf(text + used, sizeof(text) - used, "covariance=%s,%s\n",
324 first, second));
325 }
326 break;
327 case 6:
328 /* Phase 2 resolves exactly one mask, so this group hashes a constant.
329 * It exists now so a Phase 3 mask key extends this group instead of
330 * renumbering every group after it and invalidating saved state. */
331 PetscCall(PetscSNPrintf(text, sizeof(text), "mask=fluid\n"));
332 break;
333 default:
334 PetscCall(PetscSNPrintf(text, sizeof(text), "target=pointwise\n"));
335 for (PetscInt n = 0; n < definition->field_count; ++n) {
336 const PicurvWindowFieldRequest *request = &definition->fields[field_order[n]];
337 const FieldDescriptor *descriptor = NULL;
338
339 PetscCall(FieldGetDescriptor((FieldId)request->field_id, &descriptor));
340 PetscCall(PetscStrlen(text, &used));
341 PetscCall(PetscSNPrintf(text + used, sizeof(text) - used, "layout=%s:%s\n",
342 descriptor->canonical_name,
343 FieldLayoutName(descriptor->layout)));
344 }
345 break;
346 }
347
348 PetscCall(PetscStrlen(text, &length));
349 PicurvSHA256Update(&whole, text, length);
350 if (group_digest_hex) {
351 PicurvSHA256Init(&part);
352 PicurvSHA256Update(&part, text, length);
353 PicurvSHA256FinalHex(&part, group_digest);
354 PetscCall(PetscStrncpy(group_digest_hex[group], group_digest,
356 }
357 }
358 PicurvSHA256FinalHex(&whole, digest_hex);
359 PetscFunctionReturn(0);
360}
void PicurvSHA256Init(PicurvSHA256Context *context)
Initialize an incremental SHA-256 calculation.
Definition checksum.c:62
void PicurvSHA256Update(PicurvSHA256Context *context, const void *data, size_t length)
Add bytes to an incremental SHA-256 calculation.
Definition checksum.c:74
void PicurvSHA256FinalHex(PicurvSHA256Context *context, char digest_hex[65])
Finish a SHA-256 calculation and return a lowercase hexadecimal digest.
Definition checksum.c:98
Incremental SHA-256 state.
Definition checksum.h:14
FieldLayout layout
const char * FieldCanonicalName(FieldId field_id)
Return the canonical printable name for an ID.
const char * canonical_name
const char * FieldLayoutName(FieldLayout layout)
Return a stable printable label for a field layout.
PetscErrorCode FieldGetDescriptor(FieldId field_id, const FieldDescriptor **descriptor)
Return immutable metadata for a valid field identifier.
FieldId
Compile-time identity for a catalogued Eulerian field.
Immutable metadata for one field identity.
static void SortRequestOrder(PetscInt count, const PetscInt *primary, const PetscInt *secondary, PetscInt *order)
Internal helper: orders request indices so listing order cannot change the hash.
#define PICURV_WINDOW_HASH_GROUP_LENGTH
Stored length of one truncated group digest, including the terminator.
PetscInt first
First member; must also appear in the field list.
PicurvWindowFieldRequest fields[16]
PetscBool want_second
Also keep the centered second moment.
PetscInt second
Second member; must also appear in the field list.
PicurvWindowCovarianceRequest covariances[16]
PetscInt field_id
Catalogued Eulerian field identity.
#define PICURV_WINDOW_MAX_REQUESTS
Maximum fields or covariance pairs one window may request.
One field a window accumulates.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PicurvWindowFirstHashDifference()

PetscErrorCode PicurvWindowFirstHashDifference ( const PicurvWindowDefinition definition,
const char *  saved_group_digests,
PetscInt *  group 
)

Implementation of PicurvWindowFirstHashDifference().

Reports which hashed property group first differs from saved group digests.

See also
PicurvWindowFirstHashDifference()

Definition at line 366 of file statistics_window.c.

369{
370 char digest[65];
372 const char *cursor = saved_group_digests;
373
374 PetscFunctionBeginUser;
375 PetscCheck(definition != NULL && group != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
376 "Definition and group output are required.");
377 *group = -1;
378 if (!saved_group_digests) PetscFunctionReturn(0);
379 PetscCall(PicurvWindowComputeHash(definition, digest, current));
380
381 for (PetscInt index = 0; index < PICURV_WINDOW_HASH_GROUP_COUNT; ++index) {
382 const char *comma = strchr(cursor, ',');
383 const size_t length = comma ? (size_t)(comma - cursor) : strlen(cursor);
384 size_t expected = 0;
385
386 PetscCall(PetscStrlen(current[index], &expected));
387 /* Every well-formed digest is fixed width, so a short segment means the
388 * saved list is malformed rather than that this property changed. A
389 * malformed list localizes to nothing: reporting the wrong property would
390 * be worse than reporting none. */
391 if (length != expected) PetscFunctionReturn(0);
392 if (strncmp(cursor, current[index], length)) {
393 *group = index;
394 PetscFunctionReturn(0);
395 }
396 if (!comma) PetscFunctionReturn(0);
397 cursor = comma + 1;
398 }
399 PetscFunctionReturn(0);
400}
PetscErrorCode PicurvWindowComputeHash(const PicurvWindowDefinition *definition, char digest_hex[65], char group_digest_hex[][PICURV_WINDOW_HASH_GROUP_LENGTH])
Implementation of PicurvWindowComputeHash().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PicurvWindowProgress()

PetscReal PicurvWindowProgress ( const PicurvWindow window)

Implementation of PicurvWindowProgress().

Reports the fraction of a bounded window's span that has been represented.

See also
PicurvWindowProgress()

Definition at line 406 of file statistics_window.c.

407{
408 PetscReal span = 0.0;
409
410 if (window == NULL || !window->definition.bounded) return 0.0;
411 span = window->definition.end_time - window->effective_start;
412 if (span <= 0.0) return 0.0;
413 return PetscMin(1.0, window->represented_time / span);
414}
Here is the caller graph for this function:

◆ FieldStatisticsIsActive()

PetscBool FieldStatisticsIsActive ( const SimCtx simCtx)

Implementation of FieldStatisticsIsActive().

See also
FieldStatisticsIsActive()

Definition at line 420 of file statistics_window.c.

421{
422 if (!simCtx || !simCtx->fieldStatisticsEnabled) return PETSC_FALSE;
423 return (PetscBool)(simCtx->fieldStatisticsWindowCount > 0 &&
424 simCtx->fieldStatisticsWindows != NULL);
425}
PetscInt fieldStatisticsWindowCount
Definition variables.h:770
PetscBool fieldStatisticsEnabled
Definition variables.h:769
struct PicurvWindow * fieldStatisticsWindows
Definition variables.h:771
Here is the caller graph for this function:

◆ FieldStatisticsUpdateWindows()

PetscErrorCode FieldStatisticsUpdateWindows ( SimCtx simCtx,
PetscInt  step,
PetscReal  time 
)

Implementation of FieldStatisticsUpdateWindows().

Offers one completed state to every configured window.

See also
FieldStatisticsUpdateWindows()

Definition at line 431 of file statistics_window.c.

432{
433 PetscFunctionBeginUser;
434 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "SimCtx cannot be NULL.");
435 if (!FieldStatisticsIsActive(simCtx)) PetscFunctionReturn(0);
436
437 for (PetscInt window_index = 0; window_index < simCtx->fieldStatisticsWindowCount; ++window_index) {
438 PicurvWindow *window = &simCtx->fieldStatisticsWindows[window_index];
439 const PicurvWindowState before = window->state;
440 PetscBool accepted = PETSC_FALSE;
441 PetscReal weight = 0.0;
442
443 PetscCall(PicurvWindowOfferState(window, step, time, &accepted, &weight));
444
445 if (before == PICURV_WINDOW_PENDING && window->state == PICURV_WINDOW_ACTIVE) {
447 "Statistics window '%s' active from t=%.6g.\n",
448 window->definition.name, (double)window->effective_start);
449 }
450 if (accepted) {
451 /* Apply the accepted weight to every block's accumulators. Windows share
452 * the source state but own independent accumulator state. */
453 for (PetscInt bi = 0; bi < simCtx->block_number; ++bi) {
454 UserCtx *user = &simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user[bi];
455 if (!user->fieldStatisticsStorage) continue;
456 PetscCall(PicurvWindowAccumulate(user, &window->definition,
457 &user->fieldStatisticsStorage[window_index], weight));
458 }
460 "Statistics window '%s' accepted step %d at t=%.6g with weight %.6g "
461 "(samples=%d, represented=%.6g).\n",
462 window->definition.name, step, (double)time, (double)weight,
463 window->sample_count, (double)window->represented_time);
464 } else if (window->state == PICURV_WINDOW_ACTIVE) {
465 /* An active window that took nothing was either off schedule or offered a
466 * zero-length interval. Both are expected, so this is the level that
467 * explains a sample count without implying anything is wrong. */
469 "Statistics window '%s' did not sample step %d at t=%.6g "
470 "(last accepted t=%.6g, samples=%d).\n",
471 window->definition.name, step, (double)time,
472 (double)window->last_accepted_time, window->sample_count);
473 }
474 if (before != PICURV_WINDOW_COMPLETE && window->state == PICURV_WINDOW_COMPLETE) {
476 "Statistics window '%s' complete: %d sample(s), total weight %.6g, "
477 "represented time %.6g.\n",
478 window->definition.name, window->sample_count,
479 (double)window->total_weight, (double)window->represented_time);
480 if (window->sample_count == 0) {
482 "Statistics window '%s' completed without accepting any sample.\n",
483 window->definition.name);
484 } else {
485 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
486
487 /* A point that was never valid carries no average at all, which a
488 * reader of the mean field cannot see. Report it once, at the only
489 * moment the final coverage is known. The reduction is collective and
490 * runs once per window, not per step. */
491 if (user && user->fieldStatisticsStorage) {
492 PetscReal lowest = 1.0, highest = 0.0;
493
494 PetscCall(PicurvWindowValidFractionRange(user, &window->definition,
495 &user->fieldStatisticsStorage[window_index],
496 window->sample_count, &lowest, &highest));
497 if (lowest <= 0.0) {
499 "Statistics window '%s' completed with points that were never "
500 "valid; their mean and moments are undefined.\n",
501 window->definition.name);
502 } else {
504 "Statistics window '%s' per-point valid fraction spans [%.3f, %.3f].\n",
505 window->definition.name, (double)lowest, (double)highest);
506 }
507 }
508 }
509 }
510 }
511 PetscFunctionReturn(0);
512}
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:46
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:200
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:31
@ LOG_WARNING
Non-critical issues that warrant attention.
Definition logging.h:30
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
PetscErrorCode PicurvWindowValidFractionRange(UserCtx *user, const PicurvWindowDefinition *definition, const PicurvWindowStorage *storage, PetscInt sample_count, PetscReal *minimum, PetscReal *maximum)
Reports the range of per-point valid fraction across a window's domain.
PetscErrorCode PicurvWindowAccumulate(UserCtx *user, const PicurvWindowDefinition *definition, PicurvWindowStorage *storage, PetscReal weight)
Applies one accepted completed state to a window's accumulators.
PetscBool FieldStatisticsIsActive(const SimCtx *simCtx)
Implementation of FieldStatisticsIsActive().
PetscErrorCode PicurvWindowOfferState(PicurvWindow *window, PetscInt step, PetscReal time, PetscBool *accepted, PetscReal *weight)
Implementation of PicurvWindowOfferState().
PicurvWindowState
Lifecycle state of one window.
Runtime state of one window.
UserCtx * user
Definition variables.h:571
PetscInt block_number
Definition variables.h:790
UserMG usermg
Definition variables.h:842
PetscInt mglevels
Definition variables.h:578
struct PicurvWindowStorage * fieldStatisticsStorage
Definition variables.h:952
MGCtx * mgctx
Definition variables.h:581
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:

Variable Documentation

◆ kHashGroupNames

const char* const kHashGroupNames[PICURV_WINDOW_HASH_GROUP_COUNT]
static
Initial value:
= {
"name", "start_time", "weighting", "cadence", "fields", "covariances", "mask", "target"
}

Stable names of the hashed property groups, in serialization order.

Definition at line 185 of file statistics_window.c.

185 {
186 "name", "start_time", "weighting", "cadence", "fields", "covariances", "mask", "target"
187};