16#define STATISTICS_OPTION_NAME_LENGTH 128
19#define STATISTICS_OPTION_VALUE_LENGTH 256
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);
35 *field_id = (PetscInt)resolved;
36 PetscFunctionReturn(0);
49 PetscFunctionBeginUser;
51 while (cursor && *cursor) {
52 char *comma = strchr(cursor,
',');
54 if (comma) *comma =
'\0';
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;
61 cursor = comma ? comma + 1 : NULL;
63 PetscFunctionReturn(0);
73 PetscBool found = PETSC_FALSE;
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);
82 PETSC_ERR_ARG_OUTOFRANGE,
83 "Statistics window '%s' requests %" PetscInt_FMT
" fields; at most %d are supported.",
86 for (PetscInt field_index = 0; field_index < definition->
field_count; ++field_index) {
90 PetscInt token_count = 0;
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);
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);
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);
113 for (PetscInt t = 0; t < token_count; ++t) {
114 if (!strcmp(tokens[t],
"first"))
continue;
115 if (!strcmp(tokens[t],
"second")) {
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]);
125 PetscFunctionReturn(0);
135 PetscBool found = PETSC_FALSE;
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));
144 PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE,
145 "Statistics window '%s' requests %" PetscInt_FMT
" covariances; at most %d are supported.",
148 for (PetscInt pair_index = 0; pair_index < definition->
covariance_count; ++pair_index) {
151 PetscInt token_count = 0;
152 PetscBool first_present = PETSC_FALSE;
153 PetscBool second_present = PETSC_FALSE;
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);
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);
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]);
175 for (PetscInt field_index = 0; field_index < definition->
field_count; ++field_index) {
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]);
184 PetscFunctionReturn(0);
195 PetscBool found = PETSC_FALSE;
196 PetscBool step_found = PETSC_FALSE;
197 PetscBool time_found = PETSC_FALSE;
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);
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));
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")) {
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);
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.",
237 PetscFunctionReturn(0);
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 ?
" " :
"",
261 "Statistics window '%s': t=[%.6g,%s] weighting=%s every %d step(s), fields: %s, "
262 "%d covariance(s).\n",
264 definition->
bounded ?
"bounded" :
"open",
269 "Statistics window '%s': t=[%.6g,%s] weighting=%s every %.6g of time, fields: %s, "
270 "%d covariance(s).\n",
272 definition->
bounded ?
"bounded" :
"open",
280 PetscFunctionReturn(0);
291 PetscInt window_count = 0;
292 PetscBool found = PETSC_FALSE;
294 PetscFunctionBeginUser;
295 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx cannot be NULL.");
297 PetscCall(PetscOptionsGetInt(NULL, NULL,
"-statistics_console_output_freq",
299 PetscCall(PetscOptionsGetBool(NULL, NULL,
"-field_statistics_enabled",
303 PetscFunctionReturn(0);
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.");
312 for (PetscInt window_index = 0; window_index < window_count; ++window_index) {
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);
326 for (PetscInt prior = 0; prior < window_index; ++prior) {
327 PetscBool clash = PETSC_FALSE;
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);
344 PetscFunctionReturn(0);
355 PetscFunctionBeginUser;
360 PetscFunctionReturn(0);
Authoritative identities and storage metadata for persistent Eulerian fields.
PetscErrorCode FieldIdFromName(const char *field_name, FieldId *field_id)
Resolve a user-facing field name once into its typed identity.
const char * FieldCanonicalName(FieldId field_id)
Return the canonical printable name for an ID.
FieldId
Compile-time identity for a catalogued Eulerian field.
Public interface for data input/output routines.
void TrimWhitespace(char *str)
Removes leading and trailing ASCII whitespace from a mutable string.
Logging utilities and macros for PETSc-based applications.
#define GLOBAL
Scope for global logging across all processes.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
@ LOG_INFO
Informational messages about program execution.
@ LOG_DEBUG
Detailed debugging information.
PetscErrorCode DestroyFieldStatisticsConfig(SimCtx *simCtx)
Implementation of DestroyFieldStatisticsConfig().
#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.
PetscErrorCode ParseFieldStatisticsConfig(SimCtx *simCtx)
Implementation of ParseFieldStatisticsConfig().
static PetscErrorCode LogResolvedWindow(const PicurvWindowDefinition *definition)
Internal helper: reports one resolved window definition to the log.
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 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.
static PetscErrorCode SplitStatisticsList(char *value, char **tokens, PetscInt capacity, PetscInt *count)
Internal helper: splits a comma-separated value into trimmed tokens.
Control ingress for the field-statistics pipeline.
Window lifecycle, scheduling, and weighting for the field-statistics pipeline.
PetscInt first
First member; must also appear in the field list.
PicurvWindowFieldRequest fields[16]
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.
PetscErrorCode PicurvWindowInit(PicurvWindow *window, const PicurvWindowDefinition *definition)
Validates a definition and initializes a window to the pending state.
PetscBool want_second
Also keep the centered second moment.
PetscInt second
Second member; must also appear in the field list.
PicurvWindowCovarianceRequest covariances[16]
PetscBool bounded
False for an open-ended window.
PicurvWindowDefinition definition
PetscReal start_time
Requested start.
PetscInt covariance_count
PetscInt field_id
Catalogued Eulerian field identity.
#define PICURV_WINDOW_MAX_REQUESTS
Maximum fields or covariance pairs one window may request.
@ 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.
PicurvWeighting weighting
The scientifically immutable definition of one window.
PetscInt fieldStatisticsWindowCount
PetscInt statisticsConsoleOutputFreq
PetscBool fieldStatisticsEnabled
struct PicurvWindow * fieldStatisticsWindows
The master context for the entire simulation.