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

Control ingress for the field-statistics pipeline. More...

#include "statistics_config.h"
#include "statistics_window.h"
#include "field_catalog.h"
#include "logging.h"
#include "io.h"
Include dependency graph for statistics_config.c:

Go to the source code of this file.

Macros

#define STATISTICS_OPTION_NAME_LENGTH   128
 Longest constructed option name this module builds.
 
#define STATISTICS_OPTION_VALUE_LENGTH   256
 Longest option value this module reads, sized for a moment or pair list.
 

Functions

static PetscErrorCode ResolveStatisticsField (const char *window_name, const char *field_name, PetscInt *field_id)
 Internal helper: resolves one field name against the typed catalog.
 
static PetscErrorCode SplitStatisticsList (char *value, char **tokens, PetscInt capacity, PetscInt *count)
 Internal helper: splits a comma-separated value into trimmed tokens.
 
static PetscErrorCode ParseStatisticsFields (PetscInt window, PicurvWindowDefinition *definition)
 Internal helper: reads one window's field list into its definition.
 
static PetscErrorCode ParseStatisticsCovariances (PetscInt window, PicurvWindowDefinition *definition)
 Internal helper: reads one window's covariance list into its definition.
 
static PetscErrorCode ParseStatisticsWindowSchedule (PetscInt window, PicurvWindowDefinition *definition)
 Internal helper: reads one window's scheduling and weighting properties.
 
static PetscErrorCode LogResolvedWindow (const PicurvWindowDefinition *definition)
 Internal helper: reports one resolved window definition to the log.
 
PetscErrorCode ParseFieldStatisticsConfig (SimCtx *simCtx)
 Implementation of ParseFieldStatisticsConfig().
 
PetscErrorCode DestroyFieldStatisticsConfig (SimCtx *simCtx)
 Implementation of DestroyFieldStatisticsConfig().
 

Detailed Description

Control ingress for the field-statistics pipeline.

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

Definition in file statistics_config.c.

Macro Definition Documentation

◆ STATISTICS_OPTION_NAME_LENGTH

#define STATISTICS_OPTION_NAME_LENGTH   128

Longest constructed option name this module builds.

Definition at line 16 of file statistics_config.c.

◆ STATISTICS_OPTION_VALUE_LENGTH

#define STATISTICS_OPTION_VALUE_LENGTH   256

Longest option value this module reads, sized for a moment or pair list.

Definition at line 19 of file statistics_config.c.

Function Documentation

◆ ResolveStatisticsField()

static PetscErrorCode ResolveStatisticsField ( const char *  window_name,
const char *  field_name,
PetscInt *  field_id 
)
static

Internal helper: resolves one field name against the typed catalog.

Local to this translation unit. The error names the window so a hand-written control file reports the same context Python would.

Definition at line 26 of file statistics_config.c.

28{
29 FieldId resolved = FIELD_ID_UCAT;
30
31 PetscFunctionBeginUser;
32 PetscCheck(field_name != NULL && field_name[0] != '\0', PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
33 "Statistics window '%s' names an empty field.", window_name);
34 PetscCall(FieldIdFromName(field_name, &resolved));
35 *field_id = (PetscInt)resolved;
36 PetscFunctionReturn(0);
37}
PetscErrorCode FieldIdFromName(const char *field_name, FieldId *field_id)
Resolve a user-facing field name once into its typed identity.
FieldId
Compile-time identity for a catalogued Eulerian field.
@ FIELD_ID_UCAT
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SplitStatisticsList()

static PetscErrorCode SplitStatisticsList ( char *  value,
char **  tokens,
PetscInt  capacity,
PetscInt *  count 
)
static

Internal helper: splits a comma-separated value into trimmed tokens.

Local to this translation unit. Rewrites value in place, so callers pass a mutable buffer they own.

Definition at line 44 of file statistics_config.c.

46{
47 char *cursor = value;
48
49 PetscFunctionBeginUser;
50 *count = 0;
51 while (cursor && *cursor) {
52 char *comma = strchr(cursor, ',');
53
54 if (comma) *comma = '\0';
55 TrimWhitespace(cursor);
56 if (cursor[0] != '\0') {
57 PetscCheck(*count < capacity, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE,
58 "A statistics list holds at most %" PetscInt_FMT " entries.", capacity);
59 tokens[(*count)++] = cursor;
60 }
61 cursor = comma ? comma + 1 : NULL;
62 }
63 PetscFunctionReturn(0);
64}
void TrimWhitespace(char *str)
Removes leading and trailing ASCII whitespace from a mutable string.
Definition io.c:399
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ParseStatisticsFields()

static PetscErrorCode ParseStatisticsFields ( PetscInt  window,
PicurvWindowDefinition definition 
)
static

Internal helper: reads one window's field list into its definition.

Local to this translation unit.

Definition at line 70 of file statistics_config.c.

71{
73 PetscBool found = PETSC_FALSE;
74
75 PetscFunctionBeginUser;
76 PetscCall(PetscSNPrintf(name, sizeof(name),
77 "-field_statistics_window_%" PetscInt_FMT "_field_count", window));
78 PetscCall(PetscOptionsGetInt(NULL, NULL, name, &definition->field_count, &found));
79 PetscCheck(found && definition->field_count > 0, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
80 "Statistics window '%s' requests no field.", definition->name);
81 PetscCheck(definition->field_count <= PICURV_WINDOW_MAX_REQUESTS, PETSC_COMM_WORLD,
82 PETSC_ERR_ARG_OUTOFRANGE,
83 "Statistics window '%s' requests %" PetscInt_FMT " fields; at most %d are supported.",
84 definition->name, definition->field_count, PICURV_WINDOW_MAX_REQUESTS);
85
86 for (PetscInt field_index = 0; field_index < definition->field_count; ++field_index) {
87 char field_name[STATISTICS_OPTION_VALUE_LENGTH];
89 char *tokens[4];
90 PetscInt token_count = 0;
91
92 PetscCall(PetscSNPrintf(name, sizeof(name),
93 "-field_statistics_window_%" PetscInt_FMT "_field_%" PetscInt_FMT "_name",
94 window, field_index));
95 PetscCall(PetscOptionsGetString(NULL, NULL, name, field_name, sizeof(field_name), &found));
96 PetscCheck(found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
97 "Statistics window '%s' field %" PetscInt_FMT " has no name.",
98 definition->name, field_index);
99 PetscCall(ResolveStatisticsField(definition->name, field_name,
100 &definition->fields[field_index].field_id));
101
102 PetscCall(PetscSNPrintf(name, sizeof(name),
103 "-field_statistics_window_%" PetscInt_FMT "_field_%" PetscInt_FMT "_moments",
104 window, field_index));
105 PetscCall(PetscOptionsGetString(NULL, NULL, name, moments, sizeof(moments), &found));
106 PetscCheck(found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
107 "Statistics window '%s' field '%s' requests no moment.", definition->name, field_name);
108 PetscCall(SplitStatisticsList(moments, tokens, 4, &token_count));
109 PetscCheck(token_count > 0, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
110 "Statistics window '%s' field '%s' requests no moment.", definition->name, field_name);
111
112 definition->fields[field_index].want_second = PETSC_FALSE;
113 for (PetscInt t = 0; t < token_count; ++t) {
114 if (!strcmp(tokens[t], "first")) continue;
115 if (!strcmp(tokens[t], "second")) {
116 definition->fields[field_index].want_second = PETSC_TRUE;
117 continue;
118 }
119 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
120 "Statistics window '%s' field '%s' requests unknown moment '%s'; "
121 "only 'first' and 'second' exist in Phase 2.",
122 definition->name, field_name, tokens[t]);
123 }
124 }
125 PetscFunctionReturn(0);
126}
#define STATISTICS_OPTION_NAME_LENGTH
Longest constructed option name this module builds.
#define STATISTICS_OPTION_VALUE_LENGTH
Longest option value this module reads, sized for a moment or pair list.
static PetscErrorCode ResolveStatisticsField(const char *window_name, const char *field_name, PetscInt *field_id)
Internal helper: resolves one field name against the typed catalog.
static PetscErrorCode SplitStatisticsList(char *value, char **tokens, PetscInt capacity, PetscInt *count)
Internal helper: splits a comma-separated value into trimmed tokens.
PicurvWindowFieldRequest fields[16]
PetscBool want_second
Also keep the centered second moment.
PetscInt field_id
Catalogued Eulerian field identity.
#define PICURV_WINDOW_MAX_REQUESTS
Maximum fields or covariance pairs one window may request.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ParseStatisticsCovariances()

static PetscErrorCode ParseStatisticsCovariances ( PetscInt  window,
PicurvWindowDefinition definition 
)
static

Internal helper: reads one window's covariance list into its definition.

Local to this translation unit.

Definition at line 132 of file statistics_config.c.

133{
135 PetscBool found = PETSC_FALSE;
136
137 PetscFunctionBeginUser;
138 PetscCall(PetscSNPrintf(name, sizeof(name),
139 "-field_statistics_window_%" PetscInt_FMT "_covariance_count", window));
140 PetscCall(PetscOptionsGetInt(NULL, NULL, name, &definition->covariance_count, &found));
141 if (!found) definition->covariance_count = 0;
142 PetscCheck(definition->covariance_count >= 0 &&
144 PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE,
145 "Statistics window '%s' requests %" PetscInt_FMT " covariances; at most %d are supported.",
146 definition->name, definition->covariance_count, PICURV_WINDOW_MAX_REQUESTS);
147
148 for (PetscInt pair_index = 0; pair_index < definition->covariance_count; ++pair_index) {
150 char *tokens[4];
151 PetscInt token_count = 0;
152 PetscBool first_present = PETSC_FALSE;
153 PetscBool second_present = PETSC_FALSE;
154
155 PetscCall(PetscSNPrintf(name, sizeof(name),
156 "-field_statistics_window_%" PetscInt_FMT "_covariance_%" PetscInt_FMT,
157 window, pair_index));
158 PetscCall(PetscOptionsGetString(NULL, NULL, name, pair, sizeof(pair), &found));
159 PetscCheck(found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
160 "Statistics window '%s' covariance %" PetscInt_FMT " has no members.",
161 definition->name, pair_index);
162 PetscCall(SplitStatisticsList(pair, tokens, 4, &token_count));
163 PetscCheck(token_count == 2, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
164 "Statistics window '%s' covariance %" PetscInt_FMT " needs exactly two members.",
165 definition->name, pair_index);
166 PetscCall(ResolveStatisticsField(definition->name, tokens[0], &definition->covariances[pair_index].first));
167 PetscCall(ResolveStatisticsField(definition->name, tokens[1], &definition->covariances[pair_index].second));
168 PetscCheck(definition->covariances[pair_index].first != definition->covariances[pair_index].second,
169 PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
170 "Statistics window '%s' pairs '%s' with itself; that is the self-product already "
171 "requested through moments: [second].", definition->name, tokens[0]);
172
173 /* Both members must carry a running mean, because a co-moment centers
174 * against them. This is the C-side guard behind the same Python rule. */
175 for (PetscInt field_index = 0; field_index < definition->field_count; ++field_index) {
176 if (definition->fields[field_index].field_id == definition->covariances[pair_index].first) first_present = PETSC_TRUE;
177 if (definition->fields[field_index].field_id == definition->covariances[pair_index].second) second_present = PETSC_TRUE;
178 }
179 PetscCheck(first_present && second_present, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
180 "Statistics window '%s' pairs '%s' with '%s', but both must also appear in its "
181 "field list so their means exist to center against.",
182 definition->name, tokens[0], tokens[1]);
183 }
184 PetscFunctionReturn(0);
185}
PetscInt first
First member; must also appear in the field list.
PetscInt second
Second member; must also appear in the field list.
PicurvWindowCovarianceRequest covariances[16]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ParseStatisticsWindowSchedule()

static PetscErrorCode ParseStatisticsWindowSchedule ( PetscInt  window,
PicurvWindowDefinition definition 
)
static

Internal helper: reads one window's scheduling and weighting properties.

Local to this translation unit.

Definition at line 191 of file statistics_config.c.

192{
194 char weighting[STATISTICS_OPTION_VALUE_LENGTH];
195 PetscBool found = PETSC_FALSE;
196 PetscBool step_found = PETSC_FALSE;
197 PetscBool time_found = PETSC_FALSE;
198
199 PetscFunctionBeginUser;
200 PetscCall(PetscSNPrintf(name, sizeof(name),
201 "-field_statistics_window_%" PetscInt_FMT "_start_time", window));
202 PetscCall(PetscOptionsGetReal(NULL, NULL, name, &definition->start_time, &found));
203 PetscCheck(found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
204 "Statistics window '%s' has no start time.", definition->name);
205
206 /* An absent end time is what makes a window open ended, so its absence is
207 * meaningful rather than a defaulted value. */
208 PetscCall(PetscSNPrintf(name, sizeof(name),
209 "-field_statistics_window_%" PetscInt_FMT "_end_time", window));
210 PetscCall(PetscOptionsGetReal(NULL, NULL, name, &definition->end_time, &definition->bounded));
211
212 PetscCall(PetscSNPrintf(name, sizeof(name),
213 "-field_statistics_window_%" PetscInt_FMT "_weighting", window));
214 PetscCall(PetscOptionsGetString(NULL, NULL, name, weighting, sizeof(weighting), &found));
215 PetscCheck(found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
216 "Statistics window '%s' has no weighting.", definition->name);
217 if (!strcmp(weighting, "sample")) {
219 } else if (!strcmp(weighting, "physical_time")) {
221 } else {
222 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
223 "Statistics window '%s' has weighting '%s'; only 'sample' and 'physical_time' exist.",
224 definition->name, weighting);
225 }
226
227 PetscCall(PetscSNPrintf(name, sizeof(name),
228 "-field_statistics_window_%" PetscInt_FMT "_step_cadence", window));
229 PetscCall(PetscOptionsGetInt(NULL, NULL, name, &definition->step_cadence, &step_found));
230 PetscCall(PetscSNPrintf(name, sizeof(name),
231 "-field_statistics_window_%" PetscInt_FMT "_time_cadence", window));
232 PetscCall(PetscOptionsGetReal(NULL, NULL, name, &definition->time_cadence, &time_found));
233 PetscCheck(step_found != time_found, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
234 "Statistics window '%s' must select exactly one of step_cadence and time_cadence.",
235 definition->name);
236 definition->cadence_kind = step_found ? PICURV_CADENCE_STEP : PICURV_CADENCE_TIME;
237 PetscFunctionReturn(0);
238}
PetscReal time_cadence
Used when cadence_kind is time; must be positive.
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.
PetscReal start_time
Requested start.
@ PICURV_WEIGHTING_PHYSICAL_TIME
Weight is the represented interval.
@ PICURV_WEIGHTING_SAMPLE
Equal weight per accepted state.
@ PICURV_CADENCE_TIME
First state at or past each nominal time target.
@ PICURV_CADENCE_STEP
Every n completed steps from activation.
Here is the caller graph for this function:

◆ LogResolvedWindow()

static PetscErrorCode LogResolvedWindow ( const PicurvWindowDefinition definition)
static

Internal helper: reports one resolved window definition to the log.

Local to this translation unit. Runs once per window at startup, so a run's log records exactly what it accumulated without having to be cross-referenced against the configuration that produced it.

Definition at line 246 of file statistics_config.c.

247{
248 char fields[STATISTICS_OPTION_VALUE_LENGTH] = "";
249 size_t used = 0;
250
251 PetscFunctionBeginUser;
252 for (PetscInt field_index = 0; field_index < definition->field_count; ++field_index) {
253 PetscCall(PetscStrlen(fields, &used));
254 PetscCall(PetscSNPrintf(fields + used, sizeof(fields) - used, "%s%s%s",
255 field_index ? " " : "",
256 FieldCanonicalName((FieldId)definition->fields[field_index].field_id),
257 definition->fields[field_index].want_second ? "(1,2)" : "(1)"));
258 }
259 if (definition->cadence_kind == PICURV_CADENCE_STEP) {
261 "Statistics window '%s': t=[%.6g,%s] weighting=%s every %d step(s), fields: %s, "
262 "%d covariance(s).\n",
263 definition->name, (double)definition->start_time,
264 definition->bounded ? "bounded" : "open",
265 definition->weighting == PICURV_WEIGHTING_SAMPLE ? "sample" : "physical_time",
266 (int)definition->step_cadence, fields, (int)definition->covariance_count);
267 } else {
269 "Statistics window '%s': t=[%.6g,%s] weighting=%s every %.6g of time, fields: %s, "
270 "%d covariance(s).\n",
271 definition->name, (double)definition->start_time,
272 definition->bounded ? "bounded" : "open",
273 definition->weighting == PICURV_WEIGHTING_SAMPLE ? "sample" : "physical_time",
274 (double)definition->time_cadence, fields, (int)definition->covariance_count);
275 }
276 if (definition->bounded) {
277 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Statistics window '%s' ends at t=%.6g.\n",
278 definition->name, (double)definition->end_time);
279 }
280 PetscFunctionReturn(0);
281}
const char * FieldCanonicalName(FieldId field_id)
Return the canonical printable name for an ID.
#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_DEBUG
Detailed debugging information.
Definition logging.h:32
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ParseFieldStatisticsConfig()

PetscErrorCode ParseFieldStatisticsConfig ( SimCtx simCtx)

Implementation of ParseFieldStatisticsConfig().

Resolves field-statistics configuration from the control file.

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/statistics_config.h.

See also
ParseFieldStatisticsConfig()

Definition at line 289 of file statistics_config.c.

290{
291 PetscInt window_count = 0;
292 PetscBool found = PETSC_FALSE;
293
294 PetscFunctionBeginUser;
295 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "SimCtx cannot be NULL.");
296
297 PetscCall(PetscOptionsGetInt(NULL, NULL, "-statistics_console_output_freq",
298 &simCtx->statisticsConsoleOutputFreq, NULL));
299 PetscCall(PetscOptionsGetBool(NULL, NULL, "-field_statistics_enabled",
300 &simCtx->fieldStatisticsEnabled, NULL));
301 if (!simCtx->fieldStatisticsEnabled) {
302 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Field statistics are disabled.\n");
303 PetscFunctionReturn(0);
304 }
305
306 PetscCall(PetscOptionsGetInt(NULL, NULL, "-field_statistics_window_count", &window_count, &found));
307 PetscCheck(found && window_count > 0, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
308 "Field statistics are enabled but no window is configured.");
309 PetscCall(PetscCalloc1((size_t)window_count, &simCtx->fieldStatisticsWindows));
310 simCtx->fieldStatisticsWindowCount = window_count;
311
312 for (PetscInt window_index = 0; window_index < window_count; ++window_index) {
313 PicurvWindowDefinition definition;
314 char option_name[STATISTICS_OPTION_NAME_LENGTH];
315
316 PetscCall(PetscMemzero(&definition, sizeof(definition)));
317 PetscCall(PetscSNPrintf(option_name, sizeof(option_name),
318 "-field_statistics_window_%" PetscInt_FMT "_name", window_index));
319 PetscCall(PetscOptionsGetString(NULL, NULL, option_name, definition.name,
320 sizeof(definition.name), &found));
321 PetscCheck(found && definition.name[0] != '\0', PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
322 "Statistics window %" PetscInt_FMT " has no name.", window_index);
323
324 /* A duplicate name would make two windows indistinguishable in the
325 * checkpoint, where window state is matched by name on restart. */
326 for (PetscInt prior = 0; prior < window_index; ++prior) {
327 PetscBool clash = PETSC_FALSE;
328
329 PetscCall(PetscStrcmp(simCtx->fieldStatisticsWindows[prior].definition.name,
330 definition.name, &clash));
331 PetscCheck(!clash, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
332 "Statistics window name '%s' is used more than once; names identify saved "
333 "state across a restart and must be unique.", definition.name);
334 }
335
336 PetscCall(ParseStatisticsWindowSchedule(window_index, &definition));
337 PetscCall(ParseStatisticsFields(window_index, &definition));
338 PetscCall(ParseStatisticsCovariances(window_index, &definition));
339 PetscCall(PicurvWindowInit(&simCtx->fieldStatisticsWindows[window_index], &definition));
340 PetscCall(LogResolvedWindow(&simCtx->fieldStatisticsWindows[window_index].definition));
341 }
342
343 LOG_ALLOW(GLOBAL, LOG_INFO, "Field statistics resolved %d window(s).\n", (int)window_count);
344 PetscFunctionReturn(0);
345}
static PetscErrorCode LogResolvedWindow(const PicurvWindowDefinition *definition)
Internal helper: reports one resolved window definition to the log.
static PetscErrorCode ParseStatisticsCovariances(PetscInt window, PicurvWindowDefinition *definition)
Internal helper: reads one window's covariance list into its definition.
static PetscErrorCode ParseStatisticsWindowSchedule(PetscInt window, PicurvWindowDefinition *definition)
Internal helper: reads one window's scheduling and weighting properties.
static PetscErrorCode ParseStatisticsFields(PetscInt window, PicurvWindowDefinition *definition)
Internal helper: reads one window's field list into its definition.
PetscErrorCode PicurvWindowInit(PicurvWindow *window, const PicurvWindowDefinition *definition)
Validates a definition and initializes a window to the pending state.
PicurvWindowDefinition definition
The scientifically immutable definition of one window.
PetscInt fieldStatisticsWindowCount
Definition variables.h:770
PetscInt statisticsConsoleOutputFreq
Definition variables.h:772
PetscBool fieldStatisticsEnabled
Definition variables.h:769
struct PicurvWindow * fieldStatisticsWindows
Definition variables.h:771
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DestroyFieldStatisticsConfig()

PetscErrorCode DestroyFieldStatisticsConfig ( SimCtx simCtx)

Implementation of DestroyFieldStatisticsConfig().

Releases the window definitions resolved by ParseFieldStatisticsConfig().

Full API contract (arguments, ownership, side effects) is documented with the header declaration in include/statistics_config.h.

See also
DestroyFieldStatisticsConfig()

Definition at line 353 of file statistics_config.c.

354{
355 PetscFunctionBeginUser;
356 if (!simCtx || !simCtx->fieldStatisticsWindows) PetscFunctionReturn(0);
357 PetscCall(PetscFree(simCtx->fieldStatisticsWindows));
358 simCtx->fieldStatisticsWindows = NULL;
359 simCtx->fieldStatisticsWindowCount = 0;
360 PetscFunctionReturn(0);
361}
Here is the caller graph for this function: