PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
runloop.c
Go to the documentation of this file.
1/**
2 * @file runloop.c
3 * @brief Test program for DMSwarm interpolation using the fdf-curvIB method.
4 * Provides the setup to start any simulation with DMSwarm and DMDAs.
5 **/
6
7#include <signal.h>
8
9#include "runloop.h"
10#include "statistics_window.h"
12
13static volatile sig_atomic_t g_runtime_shutdown_signal = 0;
14static PetscBool g_runtime_shutdown_auto_requested = PETSC_FALSE;
15
16/**
17 * @brief Record receipt of a termination signal for safe handling by the run loop.
18 */
19static void RuntimeShutdownSignalHandler(int signum)
20{
23 }
24}
25
26/**
27 * @brief Request a controlled shutdown because the estimated walltime margin is exhausted.
28 */
30{
33 }
34}
35
36/**
37 * @brief Report whether a signal or walltime guard has requested run-loop shutdown.
38 */
39static PetscBool RuntimeShutdownRequested(void)
40{
42}
43
44/**
45 * @brief Applies verification-only scalar truth and refreshes the scattered Eulerian scalar state.
46 * @details Local to this translation unit.
47 */
49{
50 PetscFunctionBeginUser;
51 if (!user || !VerificationScalarOverrideActive(user->simCtx)) PetscFunctionReturn(0);
54 PetscFunctionReturn(0);
55}
56
57/**
58 * @brief Translate a recorded termination signal into a user-facing signal name.
59 */
60static const char *RuntimeShutdownSignalName(PetscInt signum)
61{
62 switch (signum) {
63#ifdef SIGTERM
64 case SIGTERM: return "SIGTERM";
65#endif
66#ifdef SIGUSR1
67 case SIGUSR1: return "SIGUSR1";
68#endif
69#ifdef SIGINT
70 case SIGINT: return "SIGINT";
71#endif
72 default: return "UNKNOWN";
73 }
74}
75
76/**
77 * @brief Translate the current shutdown reason into a user-facing diagnostic label.
78 */
79static const char *RuntimeShutdownReasonName(void)
80{
83 }
85 return "AUTO_WALLTIME_GUARD";
86 }
87 return "NONE";
88}
89
90/**
91 * @brief Install the process signal handler used to request graceful simulation shutdown.
92 */
93static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
94{
95 struct sigaction action;
96
97 PetscFunctionBeginUser;
98 memset(&action, 0, sizeof(action));
99 action.sa_handler = RuntimeShutdownSignalHandler;
100
101 if (sigemptyset(&action.sa_mask) != 0) {
102 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigemptyset failed for signal %d.", signum);
103 }
104
105 if (sigaction(signum, &action, NULL) != 0) {
106 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigaction failed for signal %d.", signum);
107 }
108
109 PetscFunctionReturn(0);
110}
111
112/**
113 * @brief Implementation of \ref InitializeRuntimeSignalHandlers().
114 * @details Full API contract (arguments, ownership, side effects) is documented with
115 * the matching public header declaration.
116 * @see InitializeRuntimeSignalHandlers()
117 */
119{
120 PetscErrorCode ierr;
121
122 PetscFunctionBeginUser;
125
126#ifdef SIGTERM
127 ierr = RegisterRuntimeSignalHandler(SIGTERM); CHKERRQ(ierr);
128#endif
129#ifdef SIGUSR1
130 ierr = RegisterRuntimeSignalHandler(SIGUSR1); CHKERRQ(ierr);
131#endif
132#ifdef SIGINT
133 ierr = RegisterRuntimeSignalHandler(SIGINT); CHKERRQ(ierr);
134#endif
135
136 PetscFunctionReturn(0);
137}
138
139/**
140 * @brief Implementation of \ref RuntimeWalltimeGuardUpdateEWMA().
141 * @details Full API contract (arguments, ownership, side effects) is documented with
142 * the matching public header declaration.
143 * @see RuntimeWalltimeGuardUpdateEWMA()
144 */
145PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
146{
147 if (!has_previous) return latest_step_seconds;
148 return alpha * latest_step_seconds + (1.0 - alpha) * previous_ewma_seconds;
149}
150
151/**
152 * @brief Implementation of \ref RuntimeWalltimeGuardConservativeEstimate().
153 * @details Full API contract (arguments, ownership, side effects) is documented with
154 * the matching public header declaration.
155 * @see RuntimeWalltimeGuardConservativeEstimate()
156 */
157PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
158{
159 return PetscMax(warmup_average_seconds, PetscMax(ewma_seconds, latest_step_seconds));
160}
161
162/**
163 * @brief Implementation of \ref RuntimeWalltimeGuardRequiredHeadroom().
164 * @details Full API contract (arguments, ownership, side effects) is documented with
165 * the matching public header declaration.
166 * @see RuntimeWalltimeGuardRequiredHeadroom()
167 */
168PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
169{
170 return PetscMax(min_seconds, multiplier * conservative_estimate_seconds);
171}
172
173/**
174 * @brief Implementation of \ref RuntimeWalltimeGuardShouldTrigger().
175 * @details Full API contract (arguments, ownership, side effects) is documented with
176 * the matching public header declaration.
177 * @see RuntimeWalltimeGuardShouldTrigger()
178 */
179PetscBool RuntimeWalltimeGuardShouldTrigger(PetscInt completed_steps, PetscInt warmup_steps, PetscReal remaining_seconds, PetscReal min_seconds, PetscReal multiplier, PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds, PetscReal *required_headroom_seconds_out)
180{
181 PetscReal conservative_estimate = 0.0;
182 PetscReal required_headroom = 0.0;
183
184 if (required_headroom_seconds_out) *required_headroom_seconds_out = 0.0;
185 if (completed_steps < warmup_steps) return PETSC_FALSE;
186
187 conservative_estimate = RuntimeWalltimeGuardConservativeEstimate(warmup_average_seconds, ewma_seconds, latest_step_seconds);
188 required_headroom = RuntimeWalltimeGuardRequiredHeadroom(min_seconds, multiplier, conservative_estimate);
189 if (required_headroom_seconds_out) *required_headroom_seconds_out = required_headroom;
190 return (PetscBool)(remaining_seconds <= required_headroom);
191}
192
193/**
194 * @brief Estimate the remaining scheduler walltime after reserving the configured shutdown margin.
195 */
196static PetscReal RuntimeWalltimeGuardRemainingSeconds(const SimCtx *simCtx)
197{
198 time_t now = time(NULL);
199
200 if (now == (time_t)-1) return -1.0;
201 return simCtx->walltimeGuardLimitSeconds - ((PetscReal)now - simCtx->walltimeGuardJobStartEpochSeconds);
202}
203
204/**
205 * @brief Update the timestep-duration estimate used by the automatic walltime guard.
206 */
207static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
208{
210 simCtx->walltimeGuardLatestStepSeconds = completed_step_seconds;
211
213 simCtx->walltimeGuardWarmupTotalSeconds += completed_step_seconds;
217 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
218 }
219 return;
220 }
221
223 simCtx->walltimeGuardHasEWMA,
225 completed_step_seconds,
227 );
228 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
229}
230
231/**
232 * @brief Request graceful shutdown when another timestep would exceed the walltime budget.
233 */
234static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
235{
236 PetscReal remaining_seconds = 0.0;
237 PetscReal required_headroom = 0.0;
238
239 PetscFunctionBeginUser;
240 if (!simCtx->walltimeGuardActive || RuntimeShutdownRequested()) PetscFunctionReturn(0);
241
242 remaining_seconds = RuntimeWalltimeGuardRemainingSeconds(simCtx);
246 remaining_seconds,
252 &required_headroom)) {
253 PetscFunctionReturn(0);
254 }
255
257 LOG_ALLOW(
258 GLOBAL,
260 "[T=%.4f, Step=%d] AUTO_WALLTIME_GUARD requested at %s: remaining walltime %.1f s <= required headroom %.1f s "
261 "(warmup avg %.1f s, ewma %.1f s, latest %.1f s).\n",
262 simCtx->ti,
263 simCtx->step,
264 checkpoint_name,
265 (double)remaining_seconds,
266 (double)required_headroom,
267 (double)simCtx->walltimeGuardWarmupAverageSeconds,
268 (double)simCtx->walltimeGuardEWMASeconds,
269 (double)simCtx->walltimeGuardLatestStepSeconds
270 );
271
272 PetscFunctionReturn(0);
273}
274
275/**
276 * @brief Write restart-safe output when a controlled shutdown interrupts the run loop.
277 */
278static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
279{
280 PetscErrorCode ierr;
281
282 PetscFunctionBeginUser;
283
284 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Shutdown", RuntimeShutdownReasonName()); CHKERRQ(ierr);
285
287 "[T=%.4f, Step=%d] Shutdown requested by %s during %s. Writing final output outside the normal cadence before exiting.\n",
288 simCtx->ti, simCtx->step, RuntimeShutdownReasonName(), phase);
289
290 ierr = WriteCheckpointBundle(simCtx, "signal"); CHKERRQ(ierr);
291
293 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
294 }
295
296 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRMPI(ierr);
297 fflush(stdout);
298
299 PetscFunctionReturn(0);
300}
301
302/**
303 * @brief Internal helper implementation: `UpdateSolverHistoryVectors()`.
304 * @details Local to this translation unit.
305 */
306PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user, PetscBool preserve_previous_state)
307{
308 PetscErrorCode ierr;
309 SimCtx *simCtx = user->simCtx; // Access global settings if needed
310
311 PetscFunctionBeginUser;
312 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d, Block %d: Updating solver history vectors.\n",
313 simCtx->rank, user->_this);
314
315 // --- Primary Contravariant Velocity History ---
316 // The order is critical here.
317 // 1. Move n-1 into n-2 during normal advancement. A restored checkpoint
318 // already supplied the authoritative n-1 state in Ucont_rm1.
319 if (!preserve_previous_state) {
320 ierr = VecCopy(user->Ucont_o, user->Ucont_rm1); CHKERRQ(ierr);
321 }
322 // 2. Then, move the new n state (Ucont) to the n-1 slot (Ucont_o).
323 ierr = VecCopy(user->Ucont, user->Ucont_o); CHKERRQ(ierr);
324
325 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucont history updated.\n",simCtx->rank,user->_this);
326
327 // --- Update History for Other Fields ---
328 // These are typically only needed at the n-1 state.
329 ierr = VecCopy(user->Ucat, user->Ucat_o); CHKERRQ(ierr);
330 ierr = VecCopy(user->P, user->P_o); CHKERRQ(ierr);
331 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucat & P history updated.\n",simCtx->rank,user->_this);
332
333 if (simCtx->immersed) {
334 ierr = VecCopy(user->Nvert, user->Nvert_o); CHKERRQ(ierr);
335 }
336
337 // --- Update History for Turbulence Models (if active) ---
338 if (simCtx->rans) {
339 ierr = VecCopy(user->K_Omega, user->K_Omega_o); CHKERRQ(ierr);
340 }
341
342 // --- Synchronize Local Ghost Regions for the new history vectors ---
343 // This is essential so that stencils in the next time step's calculations
344 // have correct values from neighboring processes.
345 ierr = UpdateLocalGhosts(user, FIELD_ID_UCONT_O); CHKERRQ(ierr);
346 ierr = UpdateLocalGhosts(user, FIELD_ID_UCONT_RM1); CHKERRQ(ierr);
347
348 if (simCtx->immersed) {
349 ierr = UpdateLocalGhosts(user, FIELD_ID_NVERT_O); CHKERRQ(ierr);
350 }
351
352 if (simCtx->rans) {
353 ierr = UpdateLocalGhosts(user, FIELD_ID_K_OMEGA_O); CHKERRQ(ierr);
354 }
355
356 PetscFunctionReturn(0);
357}
358
359#undef __FUNCT__
360#define __FUNCT__ "PerformInitialSetup"
361/**
362 * @brief Internal helper implementation: `PerformInitializedParticleSetup()`.
363 * @details Local to this translation unit.
364 */
366{
367 PetscErrorCode ierr;
368 // --- Get pointers from SimCtx instead of passing them as arguments ---
369 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
370 BoundingBox *bboxlist = simCtx->bboxlist;
371
372 PetscFunctionBeginUser;
373
374 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Performing initial particle setup procedures.\n", simCtx->ti, simCtx->step);
375
376 // --- 0. Loop over all blocks to compute Eulerian diffusivity.
377 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
378 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
379 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
380 }
381
382 // --- 1. Initial Particle Settlement (Location and Migration) ---
383 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Initial Settlement: Locating and migrating all particles...\n", simCtx->ti, simCtx->step);
384 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
385
387 LOG_ALLOW(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after Initial settlement...\n", simCtx->ti, simCtx->step);
388 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
389 }
390
391 // --- 2. Re-initialize Particles on Inlet Surface (if applicable) ---
394 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Re-initializing particles on inlet surface...\n", simCtx->ti, simCtx->step);
395 ierr = ReinitializeParticlesOnInletSurface(user, simCtx->ti, simCtx->step); CHKERRQ(ierr);
396
397 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Resetting statuses for post-reinitialization settlement.\n", simCtx->ti, simCtx->step);
398 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
399
400 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Post-Reinitialization Settlement...\n", simCtx->ti, simCtx->step);
401 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
402
403 }
404
405 // --- 3. Finalize State for t=0 ---
406 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
407 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
408 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
409
410 // --- 4. Initial History and Output ---
411 // Update solver history vectors with the t=0 state before the first real step
412 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
413 ierr = UpdateSolverHistoryVectors(&user[bi],
414 (PetscBool)(simCtx->StartStep > 0 && simCtx->restartHistoryAvailable)); CHKERRQ(ierr);
415 }
416
417 {
418 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initialized checkpoint.\n", simCtx->ti, simCtx->step);
419 ierr = WriteCheckpointBundle(simCtx, simCtx->StartStep == 0 ? "initial" : "branch_start"); CHKERRQ(ierr);
420 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
421 }
422
424 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
425 }
426
427 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
428 PetscFunctionReturn(0);
429}
430
431#undef __FUNCT__
432#define __FUNCT__ "PerformLoadedParticleSetup"
433/**
434 * @brief Internal helper implementation: `PerformLoadedParticleSetup()`.
435 * @details Local to this translation unit.
436 */
437PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
438{
439 PetscErrorCode ierr;
440 PetscFunctionBeginUser;
441 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
442
443 // --- 0. Re-compute Eulerian Diffusivity from loaded fields.
444 LOG_ALLOW(GLOBAL, LOG_INFO, "Re-computing Eulerian Diffusivity from loaded fields...\n");
445 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
446 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
447 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
448 }
449
450 // 0.1 This moves particles to their correct ranks immediately using the loaded Cell ID.
451 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing fast restart migration using preloaded Cell IDs...\n");
452 ierr = MigrateRestartParticlesUsingCellID(user); CHKERRQ(ierr);
453
454 // 1. To catch any edge cases (particles with invalid CellIDs or newcomers).
455 // Because we kept the statuses, this function will now SKIP all the particles
456 // that are already on the correct rank,
457 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
458
459 if(get_log_level() == LOG_DEBUG){
460 LOG(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after locating loaded particles...\n", simCtx->ti, simCtx->step);
461 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
462 }
463
464 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
465
466 // 2. Ensure particles have velocity from the authoritative loaded grid for consistency.
467 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
468
469 // 3. Update Eulerian source terms from the loaded particle data.
471 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
472 } else {
473 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
474 }
475
476 // --- 4. Initial History and Output ---
477 // Update solver history vectors with the t=0 state before the first real step
478 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
479 ierr = UpdateSolverHistoryVectors(&user[bi],
480 (PetscBool)(simCtx->StartStep > 0 && simCtx->restartHistoryAvailable)); CHKERRQ(ierr);
481 }
482
483 {
484 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing restored checkpoint.\n", simCtx->ti, simCtx->step);
485 ierr = WriteCheckpointBundle(simCtx, "branch_start"); CHKERRQ(ierr);
486 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
487 }
488
490 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
491 }
492
493 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
494 PetscFunctionReturn(0);
495}
496
497#undef __FUNCT__
498#define __FUNCT__ "FinalizeRestartState"
499/**
500 * @brief Internal helper implementation: `FinalizeRestartState()`.
501 * @details Local to this translation unit.
502 */
503PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
504{
505 PetscErrorCode ierr;
506 PetscFunctionBeginUser;
507
508 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Finalizing RESTART from state (step=%d, t=%.4f) ---\n", simCtx->StartStep, simCtx->ti);
509
510 // This function only needs to handle the particle finalization logic.
511 // The Eulerian state is assumed to be fully loaded and consistent at this point.
512 if (simCtx->np > 0) {
513
514 // Use the particle restart mode to decide the workflow.
515 if (strcmp(simCtx->particleRestartMode, "load") == 0) {
516 // PARTICLES WERE LOADED: The state is complete, but we must verify
517 // the loaded CellIDs and build the in-memory grid-to-particle links.
518 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'load': Verifying particle locations and building grid links...\n");
519 ierr = PerformLoadedParticleSetup(simCtx); CHKERRQ(ierr);
520
521 } else { // Mode must be "init"
522 // PARTICLES WERE RE-INITIALIZED: They need to be fully settled and coupled
523 // to the surrounding (restarted) fluid state.
524 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'init': Running full initial setup for new particles in restarted flow.\n");
525 ierr = PerformInitializedParticleSetup(simCtx); CHKERRQ(ierr);
526 }
527 } else {
528 LOG_ALLOW(GLOBAL, LOG_INFO, "No particles in simulation, restart finalization is complete.\n");
529
530 ierr = WriteCheckpointBundle(simCtx, "branch_start"); CHKERRQ(ierr);
531 }
532
533 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Restart state successfully finalized. --\n");
534
535 PetscFunctionReturn(0);
536}
537
538#undef __FUNCT__
539#define __FUNCT__ "AdvanceSimulation"
540/**
541 * @brief Internal helper implementation: `AdvanceSimulation()`.
542 * @details Local to this translation unit.
543 */
544PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
545{
546 PetscErrorCode ierr;
547 PetscReal step_start_seconds = 0.0;
548 PetscReal step_elapsed_local = 0.0;
549 PetscReal step_elapsed_max = 0.0;
550 // Get the master context from the first block. All blocks share it.
551 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
552
553 // Retrieve control parameters from SimCtx for clarity
554 const PetscInt StartStep = simCtx->StartStep;
555 const PetscInt StepsToRun = simCtx->StepsToRun;
556 const PetscReal dt = simCtx->dt;
557
558 // Variables for particle removal statistics
559 //PetscInt removed_local_ob, removed_global_ob;
560 PetscInt removed_local_lost, removed_global_lost;
561 PetscBool terminated_early = PETSC_FALSE;
562 PetscInt last_completed_loop_index = StartStep - 1;
563
564 PetscFunctionBeginUser;
566 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting main time-marching loop: %d steps from step %d (t=%.4f), dt=%.4f\n",
567 StepsToRun, StartStep, simCtx->StartTime, dt);
568
569 // --- Main Time-Marching Loop ---
570 for (PetscInt step = StartStep; step < StartStep + StepsToRun; step++) {
571 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "pre-step checkpoint"); CHKERRQ(ierr);
573 ierr = WriteForcedTerminationOutput(simCtx, user, "pre-step checkpoint"); CHKERRQ(ierr);
574 terminated_early = PETSC_TRUE;
575 break;
576 }
577
578 step_start_seconds = MPI_Wtime();
579
580 // =================================================================
581 // 1. PRE-STEP SETUP
582 // =================================================================
583
584 // Update simulation time and step counters in the master context
585 simCtx->step = step + 1;
586 simCtx->ti += simCtx->dt; //simCtx->StartTime + step * simCtx->dt;
587
588 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Advancing Step %d (To t=%.4f) ---\n", simCtx->step, simCtx->ti);
589
590
591 // For particles, reset their status to prepare for the new advection/location cycle
592 if (simCtx->np > 0) {
593 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Resetting all particle statuses to NEEDS_LOCATION.\n");
594 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
595 }
596
597 // =================================================================
598 // 2. EULERIAN SOLVER STEP
599 // =================================================================
601 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_COORDINATES, "PreFlowSolver"); CHKERRQ(ierr);
602 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CSI, "PreFlowSolver"); CHKERRQ(ierr);
603 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_ETA, "PreFlowSolver"); CHKERRQ(ierr);
604 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_ZET, "PreFlowSolver"); CHKERRQ(ierr);
605 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENT, "PreFlowSolver"); CHKERRQ(ierr);
606 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTX, "PreFlowSolver"); CHKERRQ(ierr);
607 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTY, "PreFlowSolver"); CHKERRQ(ierr);
608 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTZ, "PreFlowSolver"); CHKERRQ(ierr);
609 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCAT, "PreFlowSolver"); CHKERRQ(ierr);
610 }
611 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Eulerian Field ...\n");
612 if(strcmp(simCtx->eulerianSource,"load")==0){
613 //LOAD mode: Read pre-computed fields for the current step.
614 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'load': Reading fields (t=%.4f,step=%d)...\n",simCtx->ti,simCtx->step);
615 for(PetscInt bi = 0; bi < simCtx->block_number;bi++){
616 ierr = ReadSimulationFields(&user[bi],simCtx->step); CHKERRQ(ierr);
617 }
618 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
619 // ANALYTICAL mode:Call the Analytical Solution Prescription Engine to enable a variety of analytical functions
620 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'analytical'. Updating Eulerian field via the Analytical Solution Engine ...\n");
621 ierr = AnalyticalSolutionEngine(simCtx); CHKERRQ(ierr);
622 }else if(strcmp(simCtx->eulerianSource,"solve")==0){
623 // SOLVE mode:Call the refactored, high-level legacy solver. This single function
624 // advances the entire multi-block fluid field from t_n to t_{n+1}.
625 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'solve'. Updating Eulerian field via Solver...\n");
626 ierr = FlowSolver(simCtx); CHKERRQ(ierr);
627 }
628 LOG_ALLOW(GLOBAL, LOG_INFO, "Eulerian Field Updated ...\n");
630 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post FlowSolver field states:\n");
631 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCAT, "PostFlowSolver"); CHKERRQ(ierr);
632 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_P, "PostFlowSolver"); CHKERRQ(ierr);
633 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCONT, "PostFlowSolver"); CHKERRQ(ierr);
634 }
635
636
637 // =================================================================
638 // 3. LAGRANGIAN PARTICLE STEP
639 // =================================================================
640
641 if (simCtx->np > 0) {
642 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Lagrangian particle system...\n");
643 simCtx->particlesLostLastStep = 0;
644
645 // a. Update Eulerian Transport Properties:
646 // Optimization: Only recalculate if turbulence is active (Nu_t changes).
647 // For Laminar flow, the value calculated at Setup is constant.
648 if (simCtx->les || simCtx->rans) {
649 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
650 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
651 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
652 }
653 }
654
655 // a.1 (Optional) Log Eulerian Diffusivity min/max and anatomy for debugging.
657 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Min/Max:\n");
658 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_DIFFUSIVITY); CHKERRQ(ierr);
659 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_DIFFUSIVITY_GRADIENT); CHKERRQ(ierr);
660 //LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Anatomy:\n");
661 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_DIFFUSIVITY, "PostDiffusivityUpdate"); CHKERRQ(ierr);
662 }
663 // b. Advect particles using the velocity interpolated from the *previous* step.
664 // P(t_{n+1}) = P(t_n) + V_p(t_n) * dt
665 ierr = UpdateAllParticlePositions(user); CHKERRQ(ierr);
666
667 // c. Settle all particles: find their new host cells and migrate them across ranks.
668 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
669
670 // d. Remove any particles that are now lost or out of the global domain.
671 ierr = CheckAndRemoveLostParticles(user, &removed_local_lost, &removed_global_lost); CHKERRQ(ierr);
672 //ierr = CheckAndRemoveOutOfBoundsParticles(user, &removed_local_ob, &removed_global_ob, simCtx->bboxlist); CHKERRQ(ierr);
673 simCtx->particlesLostLastStep = removed_global_lost;
674 simCtx->particlesLostCumulative += removed_global_lost;
675 if (removed_global_lost> 0) { // if(removed_global_lost + removed_global_ob > 0){
676 LOG_ALLOW(GLOBAL, LOG_INFO, "Removed %d particles globally this step.\n", removed_global_lost); // removed_global_lost + removed_global_ob;
677 }
678
679 // e. Interpolate the NEW fluid velocity (just computed by FlowSolver) onto the
680 // particles' new positions. This gives them V_p(t_{n+1}) for the *next* advection step.
681 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
682
683 // f. Update the Particle Fields (e.g., temperature, concentration) if applicable.
684 // This can be extended to include reactions, growth, etc.
685 ierr = UpdateAllParticleFields(user); CHKERRQ(ierr);
686
687 // g. (For Two-Way Coupling) Scatter particle data back to the grid to act as a source term.
688 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
689 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
690
691 // h. (Optional) Calculate advanced particle metrics for logging/debugging.
692 ierr = CalculateAdvancedParticleMetrics(user); CHKERRQ(ierr);
693 ierr = LOG_SEARCH_METRICS(user); CHKERRQ(ierr);
694
695 ierr = LOG_PARTICLE_METRICS(user, "Timestep Metrics"); CHKERRQ(ierr);
696
697
699 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post Lagrangian update field states:\n");
700 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_PSI); CHKERRQ(ierr);
701 }
702 }
703
704 // =================================================================
705 // 4. UPDATE HISTORY & I/O
706 // =================================================================
707
708 // The completed-state event feeds statistics windows before physical-solution
709 // monitoring, and before history rotation replaces the state just computed.
710 ierr = FieldStatisticsUpdateWindows(simCtx, simCtx->step, simCtx->ti); CHKERRQ(ierr);
712 ierr = EmitStatisticsConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
713 }
714
715 PetscCall(LOG_SOLUTION_CONVERGENCE(simCtx));
716
717 // Copy the newly computed fields (Ucont, P, etc.) to the history vectors
718 // (_o, _rm1) to prepare for the next time step.
719 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
720 ierr = UpdateSolverHistoryVectors(&user[bi], PETSC_FALSE); CHKERRQ(ierr);
721 }
722
723 //ierr = LOG_UCAT_ANATOMY(&user[0],"Final"); CHKERRQ(ierr);
724
725 // Handle periodic file output
726 if (ShouldWriteDataOutput(simCtx, simCtx->step)) {
727 LOG_ALLOW(GLOBAL, LOG_INFO, "Writing output for step %d.\n",simCtx->step);
728 ierr = WriteCheckpointBundle(simCtx, "cadence"); CHKERRQ(ierr);
729 if (simCtx->np > 0) {
730 if (strcmp(simCtx->eulerianSource, "analytical") == 0 &&
733 }
734 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
735 }
736 }
737
738 if (ShouldEmitPeriodicParticleConsoleSnapshot(simCtx, simCtx->step)) {
739 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
740 }
741
742 ProfilingLogTimestepSummary(simCtx, simCtx->step);
743 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Step", "-"); CHKERRQ(ierr);
744
745 // Update Progress Bar
746 if(simCtx->rank == 0) {
747 PrintProgressBar(step,StartStep,StepsToRun,simCtx->ti);
748 if(get_log_level()>=LOG_WARNING) PetscPrintf(PETSC_COMM_SELF,"\n");
749 }
750
751 last_completed_loop_index = step;
752
753 step_elapsed_local = MPI_Wtime() - step_start_seconds;
754 step_elapsed_max = step_elapsed_local;
755 ierr = MPI_Allreduce(&step_elapsed_local, &step_elapsed_max, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
756 if (simCtx->walltimeGuardActive) {
757 UpdateRuntimeWalltimeGuardEstimator(simCtx, step_elapsed_max);
758 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "post-step checkpoint"); CHKERRQ(ierr);
759 }
760
762 ierr = WriteForcedTerminationOutput(simCtx, user, "post-step checkpoint"); CHKERRQ(ierr);
763 terminated_early = PETSC_TRUE;
764 break;
765 }
766 } // --- End of Time-Marching Loop ---
767
768 // After the loop, print the final progress state on rank 0 and add a newline
769 // to ensure subsequent terminal output starts on a fresh line.
770 if (simCtx->rank == 0 && StepsToRun > 0) {
771 if (!terminated_early && last_completed_loop_index >= StartStep) {
772 PrintProgressBar(StartStep + StepsToRun - 1, StartStep, StepsToRun, simCtx->ti);
773 } else if (terminated_early && last_completed_loop_index >= StartStep) {
774 PrintProgressBar(last_completed_loop_index, StartStep, StepsToRun, simCtx->ti);
775 }
776 PetscPrintf(PETSC_COMM_SELF, "\n");
777 fflush(stdout);
778 }
779
780 if (terminated_early) {
782 "Time marching stopped early after %s. Final retained state is step %d at t=%.4f.\n",
783 RuntimeShutdownReasonName(), simCtx->step, simCtx->ti);
784 } else {
785 if (StepsToRun > 0) {
786 ierr = WriteCheckpointBundle(simCtx, "final"); CHKERRQ(ierr);
787 }
788 LOG_ALLOW(GLOBAL, LOG_INFO, "Time marching completed. Final time t=%.4f.\n", simCtx->ti);
789 }
791 PetscFunctionReturn(0);
792}
PetscErrorCode AnalyticalSolutionEngine(SimCtx *simCtx)
Dispatches to the appropriate analytical solution function based on simulation settings.
PetscBool AnalyticalTypeSupportsInterpolationError(const char *analytical_type)
Reports whether an analytical type has a non-trivial velocity field for which interpolation error mea...
PetscErrorCode MigrateRestartParticlesUsingCellID(UserCtx *user)
Fast-path migration for restart particles using preloaded Cell IDs.
PetscErrorCode UpdateAllParticlePositions(UserCtx *user)
Loops over all local particles in the DMSwarm, updating their positions based on velocity and the glo...
PetscErrorCode CalculateParticleCountPerCell(UserCtx *user)
Counts particles in each cell of the DMDA 'da' and stores the result in user->ParticleCount.
PetscErrorCode LocateAllParticlesInGrid(UserCtx *user, BoundingBox *bboxlist)
Orchestrates the complete particle location and migration process for one timestep.
PetscErrorCode ResetAllParticleStatuses(UserCtx *user)
Marks all local particles as NEEDS_LOCATION for the next settlement pass.
PetscErrorCode ReinitializeParticlesOnInletSurface(UserCtx *user, PetscReal currentTime, PetscInt step)
Re-initializes the positions of particles currently on this rank if this rank owns part of the design...
PetscErrorCode CheckAndRemoveLostParticles(UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal)
Removes particles that have been definitively flagged as LOST by the location algorithm.
PetscErrorCode UpdateAllParticleFields(UserCtx *user)
Orchestrates the update of all physical properties for particles.
@ FIELD_ID_PSI
@ FIELD_ID_CENTZ
@ FIELD_ID_CSI
@ FIELD_ID_UCAT
@ FIELD_ID_NVERT_O
@ FIELD_ID_COORDINATES
@ FIELD_ID_UCONT_O
@ FIELD_ID_CENTY
@ FIELD_ID_DIFFUSIVITY_GRADIENT
@ FIELD_ID_UCONT
@ FIELD_ID_ETA
@ FIELD_ID_CENT
@ FIELD_ID_K_OMEGA_O
@ FIELD_ID_P
@ FIELD_ID_UCONT_RM1
@ FIELD_ID_ZET
@ FIELD_ID_CENTX
@ FIELD_ID_DIFFUSIVITY
PetscErrorCode ScatterAllParticleFieldsToEulerFields(UserCtx *user)
Scatters a predefined set of particle fields to their corresponding Eulerian fields.
PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Reads binary field data for velocity, pressure, and other required vectors.
Definition io.c:1463
PetscBool ShouldWriteDataOutput(const SimCtx *simCtx, PetscInt completed_step)
Returns whether full field/restart output should be written for the.
Definition io.c:432
PetscErrorCode WriteCheckpointBundle(SimCtx *simCtx, const char *reason)
Write and atomically publish one complete checkpoint bundle.
Definition io.c:2530
PetscErrorCode LOG_FIELD_MIN_MAX(UserCtx *user, FieldId field_id)
Computes and logs the local and global min/max values of a 3-component vector field.
Definition logging.c:2349
PetscErrorCode LOG_PARTICLE_METRICS(UserCtx *user, const char *stageName)
Logs particle swarm metrics, adapting its behavior based on a boolean flag in SimCtx.
Definition logging.c:3337
PetscBool ShouldEmitPeriodicStatisticsConsoleSnapshot(const struct SimCtx *simCtx, PetscInt completed_step)
Reports whether a completed step falls on the console snapshot cadence.
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
Definition logging.c:186
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:45
PetscErrorCode LOG_INTERPOLATION_ERROR(UserCtx *user)
Logs the interpolation error between the analytical and computed solutions.
Definition logging.c:2865
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:46
PetscBool ShouldEmitPeriodicParticleConsoleSnapshot(const SimCtx *simCtx, PetscInt completed_step)
Returns whether a particle console snapshot should be emitted for the.
Definition logging.c:545
#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
PetscBool IsParticleConsoleSnapshotEnabled(const SimCtx *simCtx)
Returns whether periodic particle console snapshots are enabled.
Definition logging.c:528
PetscErrorCode EmitParticleConsoleSnapshot(UserCtx *user, SimCtx *simCtx, PetscInt step)
Emits one particle console snapshot into the main solver log.
Definition logging.c:559
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:859
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
Definition logging.h:84
PetscErrorCode EmitStatisticsConsoleSnapshot(UserCtx *user, const struct SimCtx *simCtx, PetscInt step)
Emits one console snapshot of window progress.
void PrintProgressBar(PetscInt step, PetscInt startStep, PetscInt totalSteps, PetscReal currentTime)
Prints a progress bar to the console.
Definition logging.c:2302
PetscErrorCode RuntimeMemoryLogSample(SimCtx *simCtx, PetscInt step, const char *event, const char *reason)
Append a reduced runtime memory sample to the configured memory log.
Definition logging.c:2086
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
Definition logging.c:87
PetscErrorCode ProfilingLogTimestepSummary(SimCtx *simCtx, PetscInt step)
Logs the performance summary for the current timestep and resets timers.
Definition logging.c:2005
PetscErrorCode LOG_PARTICLE_FIELDS(UserCtx *user, PetscInt printInterval)
Prints particle fields in a table that automatically adjusts its column widths.
Definition logging.c:400
PetscErrorCode CalculateAdvancedParticleMetrics(UserCtx *user)
Computes advanced particle statistics and stores them in SimCtx.
Definition logging.c:3283
PetscErrorCode LOG_SCATTER_METRICS(UserCtx *user)
Logs particle-to-grid scatter verification metrics for the prescribed scalar truth path.
Definition logging.c:2944
PetscErrorCode LOG_SOLUTION_CONVERGENCE(SimCtx *simCtx)
Logs physical solution-convergence metrics once per completed timestep.
Definition logging.c:1600
PetscErrorCode LOG_FIELD_ANATOMY(UserCtx *user, FieldId field_id, const char *stage_name)
Logs the anatomy of a specified field at key boundary locations, respecting the solver's specific gri...
Definition logging.c:2752
PetscErrorCode LOG_SEARCH_METRICS(UserCtx *user)
Writes compact runtime search metrics to CSV and optionally to console.
Definition logging.c:3129
@ 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
@ LOG_VERBOSE
Extremely detailed logs, typically for development use only.
Definition logging.h:34
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:850
PetscErrorCode ComputeEulerianDiffusivity(UserCtx *user)
Computes the effective diffusivity scalar field (Gamma_eff) on the Eulerian grid.
Definition rhs.c:1815
PetscErrorCode ComputeEulerianDiffusivityGradient(UserCtx *user)
Computes the Eulerian gradient of the effective diffusivity field.
Definition rhs.c:1947
PetscErrorCode InitializeRuntimeSignalHandlers(void)
Implementation of InitializeRuntimeSignalHandlers().
Definition runloop.c:118
static PetscReal RuntimeWalltimeGuardRemainingSeconds(const SimCtx *simCtx)
Estimate the remaining scheduler walltime after reserving the configured shutdown margin.
Definition runloop.c:196
static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
Request graceful shutdown when another timestep would exceed the walltime budget.
Definition runloop.c:234
PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
Internal helper implementation: AdvanceSimulation().
Definition runloop.c:544
PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
Implementation of RuntimeWalltimeGuardUpdateEWMA().
Definition runloop.c:145
static PetscBool g_runtime_shutdown_auto_requested
Definition runloop.c:14
static void RuntimeShutdownSignalHandler(int signum)
Record receipt of a termination signal for safe handling by the run loop.
Definition runloop.c:19
static void RuntimeRequestAutoWalltimeGuard(void)
Request a controlled shutdown because the estimated walltime margin is exhausted.
Definition runloop.c:29
PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
Implementation of RuntimeWalltimeGuardConservativeEstimate().
Definition runloop.c:157
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Implementation of RuntimeWalltimeGuardRequiredHeadroom().
Definition runloop.c:168
PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
Internal helper implementation: FinalizeRestartState().
Definition runloop.c:503
static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
Write restart-safe output when a controlled shutdown interrupts the run loop.
Definition runloop.c:278
PetscBool RuntimeWalltimeGuardShouldTrigger(PetscInt completed_steps, PetscInt warmup_steps, PetscReal remaining_seconds, PetscReal min_seconds, PetscReal multiplier, PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds, PetscReal *required_headroom_seconds_out)
Implementation of RuntimeWalltimeGuardShouldTrigger().
Definition runloop.c:179
static PetscErrorCode RefreshVerificationScalarScatterState(UserCtx *user)
Applies verification-only scalar truth and refreshes the scattered Eulerian scalar state.
Definition runloop.c:48
static const char * RuntimeShutdownSignalName(PetscInt signum)
Translate a recorded termination signal into a user-facing signal name.
Definition runloop.c:60
PetscErrorCode PerformInitializedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformInitializedParticleSetup().
Definition runloop.c:365
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user, PetscBool preserve_previous_state)
Internal helper implementation: UpdateSolverHistoryVectors().
Definition runloop.c:306
static const char * RuntimeShutdownReasonName(void)
Translate the current shutdown reason into a user-facing diagnostic label.
Definition runloop.c:79
static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
Install the process signal handler used to request graceful simulation shutdown.
Definition runloop.c:93
static PetscBool RuntimeShutdownRequested(void)
Report whether a signal or walltime guard has requested run-loop shutdown.
Definition runloop.c:39
static volatile sig_atomic_t g_runtime_shutdown_signal
Definition runloop.c:13
PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformLoadedParticleSetup().
Definition runloop.c:437
#define __FUNCT__
Definition runloop.c:360
static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
Update the timestep-duration estimate used by the automatic walltime guard.
Definition runloop.c:207
PetscErrorCode UpdateLocalGhosts(UserCtx *user, FieldId field_id)
Updates the local vector (including ghost points) from its corresponding global vector.
Definition setup.c:1838
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
Definition solvers.c:11
Window lifecycle, scheduling, and weighting for the field-statistics pipeline.
PetscErrorCode FieldStatisticsUpdateWindows(struct SimCtx *simCtx, PetscInt step, PetscReal time)
Offers one completed state to every configured window.
UserCtx * user
Definition variables.h:571
PetscBool inletFaceDefined
Definition variables.h:932
PetscMPIInt rank
Definition variables.h:698
PetscInt block_number
Definition variables.h:790
PetscBool walltimeGuardActive
Definition variables.h:870
PetscReal walltimeGuardWarmupTotalSeconds
Definition variables.h:878
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:909
PetscInt rans
Definition variables.h:821
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
Definition variables.h:552
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
Definition variables.h:555
PetscReal StartTime
Definition variables.h:709
PetscBool walltimeGuardHasEWMA
Definition variables.h:880
Vec K_Omega_o
Definition variables.h:982
PetscInt particlesLostLastStep
Definition variables.h:834
UserMG usermg
Definition variables.h:852
PetscReal walltimeGuardMinSeconds
Definition variables.h:873
Vec K_Omega
Definition variables.h:982
PetscInt _this
Definition variables.h:924
PetscReal walltimeGuardLatestStepSeconds
Definition variables.h:882
PetscReal dt
Definition variables.h:710
PetscInt StepsToRun
Definition variables.h:706
PetscInt np
Definition variables.h:827
Vec Ucont
Definition variables.h:939
PetscInt StartStep
Definition variables.h:705
Vec Ucat_o
Definition variables.h:946
char particleRestartMode[16]
Definition variables.h:833
BoundingBox * bboxlist
Definition variables.h:830
PetscInt walltimeGuardCompletedSteps
Definition variables.h:877
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:715
PetscInt walltimeGuardWarmupSteps
Definition variables.h:871
ParticleInitializationType ParticleInitialization
Definition variables.h:831
Vec Ucat
Definition variables.h:939
Vec Ucont_o
Definition variables.h:946
PetscInt mglevels
Definition variables.h:578
Vec Nvert_o
Definition variables.h:946
PetscInt particlesLostCumulative
Definition variables.h:835
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:729
PetscReal walltimeGuardWarmupAverageSeconds
Definition variables.h:879
Vec Ucont_rm1
Definition variables.h:947
PetscInt step
Definition variables.h:703
PetscReal walltimeGuardEWMASeconds
Definition variables.h:881
PetscReal walltimeGuardLimitSeconds
Definition variables.h:876
PetscReal walltimeGuardEstimatorAlpha
Definition variables.h:874
PetscInt les
Definition variables.h:821
Vec Nvert
Definition variables.h:939
MGCtx * mgctx
Definition variables.h:581
PetscBool restartHistoryAvailable
Definition variables.h:723
PetscReal ti
Definition variables.h:704
PetscReal walltimeGuardMultiplier
Definition variables.h:872
PetscInt immersed
Definition variables.h:726
PetscReal walltimeGuardJobStartEpochSeconds
Definition variables.h:875
PetscInt LoggingFrequency
Definition variables.h:857
Vec P_o
Definition variables.h:946
Defines a 3D axis-aligned bounding box.
Definition variables.h:171
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:906
PetscErrorCode ApplyVerificationScalarOverrideToParticles(UserCtx *user)
Populates the particle Psi field from a verification-only source override.
PetscBool VerificationScalarOverrideActive(const SimCtx *simCtx)
Reports whether a verification-only scalar override is active.