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"
11
12static volatile sig_atomic_t g_runtime_shutdown_signal = 0;
13static PetscBool g_runtime_shutdown_auto_requested = PETSC_FALSE;
14
15/**
16 * @brief Internal helper implementation: `RuntimeShutdownSignalHandler()`.
17 * @details Local to this translation unit.
18 */
19static void RuntimeShutdownSignalHandler(int signum)
20{
23 }
24}
25
26/**
27 * @brief Internal helper implementation: `RuntimeRequestAutoWalltimeGuard()`.
28 * @details Local to this translation unit.
29 */
31{
34 }
35}
36
37/**
38 * @brief Internal helper implementation: `RuntimeShutdownRequested()`.
39 * @details Local to this translation unit.
40 */
41static PetscBool RuntimeShutdownRequested(void)
42{
44}
45
46/**
47 * @brief Applies verification-only scalar truth and refreshes the scattered Eulerian scalar state.
48 * @details Local to this translation unit.
49 */
51{
52 PetscFunctionBeginUser;
53 if (!user || !VerificationScalarOverrideActive(user->simCtx)) PetscFunctionReturn(0);
56 PetscFunctionReturn(0);
57}
58
59/**
60 * @brief Internal helper implementation: `RuntimeShutdownSignalName()`.
61 * @details Local to this translation unit.
62 */
63static const char *RuntimeShutdownSignalName(PetscInt signum)
64{
65 switch (signum) {
66#ifdef SIGTERM
67 case SIGTERM: return "SIGTERM";
68#endif
69#ifdef SIGUSR1
70 case SIGUSR1: return "SIGUSR1";
71#endif
72#ifdef SIGINT
73 case SIGINT: return "SIGINT";
74#endif
75 default: return "UNKNOWN";
76 }
77}
78
79/**
80 * @brief Internal helper implementation: `RuntimeShutdownReasonName()`.
81 * @details Local to this translation unit.
82 */
83static const char *RuntimeShutdownReasonName(void)
84{
87 }
89 return "AUTO_WALLTIME_GUARD";
90 }
91 return "NONE";
92}
93
94/**
95 * @brief Internal helper implementation: `RegisterRuntimeSignalHandler()`.
96 * @details Local to this translation unit.
97 */
98static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
99{
100 struct sigaction action;
101
102 PetscFunctionBeginUser;
103 memset(&action, 0, sizeof(action));
104 action.sa_handler = RuntimeShutdownSignalHandler;
105
106 if (sigemptyset(&action.sa_mask) != 0) {
107 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigemptyset failed for signal %d.", signum);
108 }
109
110 if (sigaction(signum, &action, NULL) != 0) {
111 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigaction failed for signal %d.", signum);
112 }
113
114 PetscFunctionReturn(0);
115}
116
117/**
118 * @brief Implementation of \ref InitializeRuntimeSignalHandlers().
119 * @details Full API contract (arguments, ownership, side effects) is documented with
120 * the matching public header declaration.
121 * @see InitializeRuntimeSignalHandlers()
122 */
124{
125 PetscErrorCode ierr;
126
127 PetscFunctionBeginUser;
130
131#ifdef SIGTERM
132 ierr = RegisterRuntimeSignalHandler(SIGTERM); CHKERRQ(ierr);
133#endif
134#ifdef SIGUSR1
135 ierr = RegisterRuntimeSignalHandler(SIGUSR1); CHKERRQ(ierr);
136#endif
137#ifdef SIGINT
138 ierr = RegisterRuntimeSignalHandler(SIGINT); CHKERRQ(ierr);
139#endif
140
141 PetscFunctionReturn(0);
142}
143
144/**
145 * @brief Implementation of \ref RuntimeWalltimeGuardUpdateEWMA().
146 * @details Full API contract (arguments, ownership, side effects) is documented with
147 * the matching public header declaration.
148 * @see RuntimeWalltimeGuardUpdateEWMA()
149 */
150PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
151{
152 if (!has_previous) return latest_step_seconds;
153 return alpha * latest_step_seconds + (1.0 - alpha) * previous_ewma_seconds;
154}
155
156/**
157 * @brief Implementation of \ref RuntimeWalltimeGuardConservativeEstimate().
158 * @details Full API contract (arguments, ownership, side effects) is documented with
159 * the matching public header declaration.
160 * @see RuntimeWalltimeGuardConservativeEstimate()
161 */
162PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
163{
164 return PetscMax(warmup_average_seconds, PetscMax(ewma_seconds, latest_step_seconds));
165}
166
167/**
168 * @brief Implementation of \ref RuntimeWalltimeGuardRequiredHeadroom().
169 * @details Full API contract (arguments, ownership, side effects) is documented with
170 * the matching public header declaration.
171 * @see RuntimeWalltimeGuardRequiredHeadroom()
172 */
173PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
174{
175 return PetscMax(min_seconds, multiplier * conservative_estimate_seconds);
176}
177
178/**
179 * @brief Implementation of \ref RuntimeWalltimeGuardShouldTrigger().
180 * @details Full API contract (arguments, ownership, side effects) is documented with
181 * the matching public header declaration.
182 * @see RuntimeWalltimeGuardShouldTrigger()
183 */
184PetscBool 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)
185{
186 PetscReal conservative_estimate = 0.0;
187 PetscReal required_headroom = 0.0;
188
189 if (required_headroom_seconds_out) *required_headroom_seconds_out = 0.0;
190 if (completed_steps < warmup_steps) return PETSC_FALSE;
191
192 conservative_estimate = RuntimeWalltimeGuardConservativeEstimate(warmup_average_seconds, ewma_seconds, latest_step_seconds);
193 required_headroom = RuntimeWalltimeGuardRequiredHeadroom(min_seconds, multiplier, conservative_estimate);
194 if (required_headroom_seconds_out) *required_headroom_seconds_out = required_headroom;
195 return (PetscBool)(remaining_seconds <= required_headroom);
196}
197
198/**
199 * @brief Internal helper implementation: `RuntimeWalltimeGuardRemainingSeconds()`.
200 * @details Local to this translation unit.
201 */
202static PetscReal RuntimeWalltimeGuardRemainingSeconds(const SimCtx *simCtx)
203{
204 time_t now = time(NULL);
205
206 if (now == (time_t)-1) return -1.0;
207 return simCtx->walltimeGuardLimitSeconds - ((PetscReal)now - simCtx->walltimeGuardJobStartEpochSeconds);
208}
209
210/**
211 * @brief Internal helper implementation: `UpdateRuntimeWalltimeGuardEstimator()`.
212 * @details Local to this translation unit.
213 */
214static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
215{
217 simCtx->walltimeGuardLatestStepSeconds = completed_step_seconds;
218
220 simCtx->walltimeGuardWarmupTotalSeconds += completed_step_seconds;
224 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
225 }
226 return;
227 }
228
230 simCtx->walltimeGuardHasEWMA,
232 completed_step_seconds,
234 );
235 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
236}
237
238/**
239 * @brief Internal helper implementation: `MaybeRequestRuntimeWalltimeGuardShutdown()`.
240 * @details Local to this translation unit.
241 */
242static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
243{
244 PetscReal remaining_seconds = 0.0;
245 PetscReal required_headroom = 0.0;
246
247 PetscFunctionBeginUser;
248 if (!simCtx->walltimeGuardActive || RuntimeShutdownRequested()) PetscFunctionReturn(0);
249
250 remaining_seconds = RuntimeWalltimeGuardRemainingSeconds(simCtx);
254 remaining_seconds,
260 &required_headroom)) {
261 PetscFunctionReturn(0);
262 }
263
265 LOG_ALLOW(
266 GLOBAL,
268 "[T=%.4f, Step=%d] AUTO_WALLTIME_GUARD requested at %s: remaining walltime %.1f s <= required headroom %.1f s "
269 "(warmup avg %.1f s, ewma %.1f s, latest %.1f s).\n",
270 simCtx->ti,
271 simCtx->step,
272 checkpoint_name,
273 (double)remaining_seconds,
274 (double)required_headroom,
275 (double)simCtx->walltimeGuardWarmupAverageSeconds,
276 (double)simCtx->walltimeGuardEWMASeconds,
277 (double)simCtx->walltimeGuardLatestStepSeconds
278 );
279
280 PetscFunctionReturn(0);
281}
282
283/**
284 * @brief Internal helper implementation: `WriteForcedTerminationOutput()`.
285 * @details Local to this translation unit.
286 */
287static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
288{
289 PetscErrorCode ierr;
290
291 PetscFunctionBeginUser;
292
293 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Shutdown", RuntimeShutdownReasonName()); CHKERRQ(ierr);
294
296 "[T=%.4f, Step=%d] Shutdown requested by %s during %s. Writing final output outside the normal cadence before exiting.\n",
297 simCtx->ti, simCtx->step, RuntimeShutdownReasonName(), phase);
298
299 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
300 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
301 }
302
303 if (simCtx->np > 0) {
304 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
305 }
306
308 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
309 }
310
311 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRMPI(ierr);
312 fflush(stdout);
313
314 PetscFunctionReturn(0);
315}
316
317/**
318 * @brief Internal helper implementation: `UpdateSolverHistoryVectors()`.
319 * @details Local to this translation unit.
320 */
322{
323 PetscErrorCode ierr;
324 SimCtx *simCtx = user->simCtx; // Access global settings if needed
325
326 PetscFunctionBeginUser;
327 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d, Block %d: Updating solver history vectors.\n",
328 simCtx->rank, user->_this);
329
330 // --- Primary Contravariant Velocity History ---
331 // The order is critical here.
332 // 1. First, move the n-1 state (Ucont_o) to the n-2 slot (Ucont_rm1).
333 ierr = VecCopy(user->Ucont_o, user->Ucont_rm1); CHKERRQ(ierr);
334 // 2. Then, move the new n state (Ucont) to the n-1 slot (Ucont_o).
335 ierr = VecCopy(user->Ucont, user->Ucont_o); CHKERRQ(ierr);
336
337 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucont history updated.\n",simCtx->rank,user->_this);
338
339 // --- Update History for Other Fields ---
340 // These are typically only needed at the n-1 state.
341 ierr = VecCopy(user->Ucat, user->Ucat_o); CHKERRQ(ierr);
342 ierr = VecCopy(user->P, user->P_o); CHKERRQ(ierr);
343 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucat & P history updated.\n",simCtx->rank,user->_this);
344
345 if (simCtx->immersed) {
346 ierr = VecCopy(user->Nvert, user->Nvert_o); CHKERRQ(ierr);
347 }
348
349 // --- Update History for Turbulence Models (if active) ---
350 if (simCtx->rans) {
351 ierr = VecCopy(user->K_Omega, user->K_Omega_o); CHKERRQ(ierr);
352 }
353
354 // --- Synchronize Local Ghost Regions for the new history vectors ---
355 // This is essential so that stencils in the next time step's calculations
356 // have correct values from neighboring processes.
357 ierr = DMGlobalToLocalBegin(user->fda, user->Ucont_o, INSERT_VALUES, user->lUcont_o); CHKERRQ(ierr);
358 ierr = DMGlobalToLocalEnd(user->fda, user->Ucont_o, INSERT_VALUES, user->lUcont_o); CHKERRQ(ierr);
359
360 ierr = DMGlobalToLocalBegin(user->fda, user->Ucont_rm1, INSERT_VALUES, user->lUcont_rm1); CHKERRQ(ierr);
361 ierr = DMGlobalToLocalEnd(user->fda, user->Ucont_rm1, INSERT_VALUES, user->lUcont_rm1); CHKERRQ(ierr);
362
363 if (simCtx->immersed) {
364 ierr = DMGlobalToLocalBegin(user->da, user->Nvert_o, INSERT_VALUES, user->lNvert_o); CHKERRQ(ierr);
365 ierr = DMGlobalToLocalEnd(user->da, user->Nvert_o, INSERT_VALUES, user->lNvert_o); CHKERRQ(ierr);
366 }
367
368 if (simCtx->rans) {
369 ierr = DMGlobalToLocalBegin(user->fda2, user->K_Omega_o, INSERT_VALUES, user->lK_Omega_o); CHKERRQ(ierr);
370 ierr = DMGlobalToLocalEnd(user->fda2, user->K_Omega_o, INSERT_VALUES, user->lK_Omega_o); CHKERRQ(ierr);
371 }
372
373 PetscFunctionReturn(0);
374}
375
376#undef __FUNCT__
377#define __FUNCT__ "PerformInitialSetup"
378/**
379 * @brief Internal helper implementation: `PerformInitializedParticleSetup()`.
380 * @details Local to this translation unit.
381 */
383{
384 PetscErrorCode ierr;
385 // --- Get pointers from SimCtx instead of passing them as arguments ---
386 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
387 BoundingBox *bboxlist = simCtx->bboxlist;
388
389 PetscFunctionBeginUser;
390
391 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Performing initial particle setup procedures.\n", simCtx->ti, simCtx->step);
392
393 // --- 0. Loop over all blocks to compute Eulerian diffusivity.
394 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
395 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
396 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
397 }
398
399 // --- 1. Initial Particle Settlement (Location and Migration) ---
400 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Initial Settlement: Locating and migrating all particles...\n", simCtx->ti, simCtx->step);
401 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
402
404 LOG_ALLOW(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after Initial settlement...\n", simCtx->ti, simCtx->step);
405 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
406 }
407
408 // --- 2. Re-initialize Particles on Inlet Surface (if applicable) ---
411 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Re-initializing particles on inlet surface...\n", simCtx->ti, simCtx->step);
412 ierr = ReinitializeParticlesOnInletSurface(user, simCtx->ti, simCtx->step); CHKERRQ(ierr);
413
414 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Resetting statuses for post-reinitialization settlement.\n", simCtx->ti, simCtx->step);
415 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
416
417 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Post-Reinitialization Settlement...\n", simCtx->ti, simCtx->step);
418 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
419
420 }
421
422 // --- 3. Finalize State for t=0 ---
423 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
424 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
425 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
426
427 // --- 4. Initial History and Output ---
428 // Update solver history vectors with the t=0 state before the first real step
429 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
430 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
431 }
432
433 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
434 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
435 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
436
437 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
438 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
439 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
440 }
441 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
442 }
443
445 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
446 }
447
448 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
449 PetscFunctionReturn(0);
450}
451
452#undef __FUNCT__
453#define __FUNCT__ "PerformLoadedParticleSetup"
454/**
455 * @brief Internal helper implementation: `PerformLoadedParticleSetup()`.
456 * @details Local to this translation unit.
457 */
458PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
459{
460 PetscErrorCode ierr;
461 PetscFunctionBeginUser;
462 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
463
464 // --- 0. Re-compute Eulerian Diffusivity from loaded fields.
465 LOG_ALLOW(GLOBAL, LOG_INFO, "Re-computing Eulerian Diffusivity from loaded fields...\n");
466 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
467 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
468 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
469 }
470
471 // 0.1 This moves particles to their correct ranks immediately using the loaded Cell ID.
472 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing fast restart migration using preloaded Cell IDs...\n");
473 ierr = MigrateRestartParticlesUsingCellID(user); CHKERRQ(ierr);
474
475 // 1. To catch any edge cases (particles with invalid CellIDs or newcomers).
476 // Because we kept the statuses, this function will now SKIP all the particles
477 // that are already on the correct rank,
478 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
479
480 if(get_log_level() == LOG_DEBUG){
481 LOG(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after locating loaded particles...\n", simCtx->ti, simCtx->step);
482 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
483 }
484
485 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
486
487 // 2. Ensure particles have velocity from the authoritative loaded grid for consistency.
488 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
489
490 // 3. Update Eulerian source terms from the loaded particle data.
492 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
493 } else {
494 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
495 }
496
497 // --- 4. Initial History and Output ---
498 // Update solver history vectors with the t=0 state before the first real step
499 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
500 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
501 }
502
503 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
504 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
505 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
506
507 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
508 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
509 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
510 }
511 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
512 }
513
515 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
516 }
517
518 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
519 PetscFunctionReturn(0);
520}
521
522#undef __FUNCT__
523#define __FUNCT__ "FinalizeRestartState"
524/**
525 * @brief Internal helper implementation: `FinalizeRestartState()`.
526 * @details Local to this translation unit.
527 */
528PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
529{
530 PetscErrorCode ierr;
531 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
532
533 PetscFunctionBeginUser;
534
535 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Finalizing RESTART from state (step=%d, t=%.4f) ---\n", simCtx->StartStep, simCtx->ti);
536
537 // This function only needs to handle the particle finalization logic.
538 // The Eulerian state is assumed to be fully loaded and consistent at this point.
539 if (simCtx->np > 0) {
540
541 // Use the particle restart mode to decide the workflow.
542 if (strcmp(simCtx->particleRestartMode, "load") == 0) {
543 // PARTICLES WERE LOADED: The state is complete, but we must verify
544 // the loaded CellIDs and build the in-memory grid-to-particle links.
545 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'load': Verifying particle locations and building grid links...\n");
546 ierr = PerformLoadedParticleSetup(simCtx); CHKERRQ(ierr);
547
548 } else { // Mode must be "init"
549 // PARTICLES WERE RE-INITIALIZED: They need to be fully settled and coupled
550 // to the surrounding (restarted) fluid state.
551 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'init': Running full initial setup for new particles in restarted flow.\n");
552 ierr = PerformInitializedParticleSetup(simCtx); CHKERRQ(ierr);
553 }
554 } else {
555 LOG_ALLOW(GLOBAL, LOG_INFO, "No particles in simulation, restart finalization is complete.\n");
556
557 // Write the initial eulerian fields (this is done in PerformInitialSetup if particles exist.)
558 for(PetscInt bi = 0; bi < simCtx->block_number; bi ++){
559 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
560 }
561 }
562
563 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Restart state successfully finalized. --\n");
564
565 PetscFunctionReturn(0);
566}
567
568#undef __FUNCT__
569#define __FUNCT__ "AdvanceSimulation"
570/**
571 * @brief Internal helper implementation: `AdvanceSimulation()`.
572 * @details Local to this translation unit.
573 */
574PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
575{
576 PetscErrorCode ierr;
577 PetscReal step_start_seconds = 0.0;
578 PetscReal step_elapsed_local = 0.0;
579 PetscReal step_elapsed_max = 0.0;
580 // Get the master context from the first block. All blocks share it.
581 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
582
583 // Retrieve control parameters from SimCtx for clarity
584 const PetscInt StartStep = simCtx->StartStep;
585 const PetscInt StepsToRun = simCtx->StepsToRun;
586 const PetscReal dt = simCtx->dt;
587
588 // Variables for particle removal statistics
589 //PetscInt removed_local_ob, removed_global_ob;
590 PetscInt removed_local_lost, removed_global_lost;
591 PetscBool terminated_early = PETSC_FALSE;
592 PetscInt last_completed_loop_index = StartStep - 1;
593
594 PetscFunctionBeginUser;
596 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting main time-marching loop: %d steps from step %d (t=%.4f), dt=%.4f\n",
597 StepsToRun, StartStep, simCtx->StartTime, dt);
598
599 // --- Main Time-Marching Loop ---
600 for (PetscInt step = StartStep; step < StartStep + StepsToRun; step++) {
601 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "pre-step checkpoint"); CHKERRQ(ierr);
603 ierr = WriteForcedTerminationOutput(simCtx, user, "pre-step checkpoint"); CHKERRQ(ierr);
604 terminated_early = PETSC_TRUE;
605 break;
606 }
607
608 step_start_seconds = MPI_Wtime();
609
610 // =================================================================
611 // 1. PRE-STEP SETUP
612 // =================================================================
613
614 // Update simulation time and step counters in the master context
615 simCtx->step = step + 1;
616 simCtx->ti += simCtx->dt; //simCtx->StartTime + step * simCtx->dt;
617
618 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Advancing Step %d (To t=%.4f) ---\n", simCtx->step, simCtx->ti);
619
620
621 // For particles, reset their status to prepare for the new advection/location cycle
622 if (simCtx->np > 0) {
623 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Resetting all particle statuses to NEEDS_LOCATION.\n");
624 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
625 }
626
627 // =================================================================
628 // 2. EULERIAN SOLVER STEP
629 // =================================================================
631 ierr = LOG_FIELD_ANATOMY(&user[0],"Coordinates","PreFlowSolver"); CHKERRQ(ierr);
632 ierr = LOG_FIELD_ANATOMY(&user[0],"Csi","PreFlowSolver"); CHKERRQ(ierr);
633 ierr = LOG_FIELD_ANATOMY(&user[0],"Eta","PreFlowSolver"); CHKERRQ(ierr);
634 ierr = LOG_FIELD_ANATOMY(&user[0],"Zet","PreFlowSolver"); CHKERRQ(ierr);
635 ierr = LOG_FIELD_ANATOMY(&user[0],"Center-Coordinates","PreFlowSolver"); CHKERRQ(ierr);
636 ierr = LOG_FIELD_ANATOMY(&user[0],"X-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
637 ierr = LOG_FIELD_ANATOMY(&user[0],"Y-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
638 ierr = LOG_FIELD_ANATOMY(&user[0],"Z-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
639 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PreFlowSolver"); CHKERRQ(ierr);
640 }
641 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Eulerian Field ...\n");
642 if(strcmp(simCtx->eulerianSource,"load")==0){
643 //LOAD mode: Read pre-computed fields for the current step.
644 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'load': Reading fields (t=%.4f,step=%d)...\n",simCtx->ti,simCtx->step);
645 for(PetscInt bi = 0; bi < simCtx->block_number;bi++){
646 ierr = ReadSimulationFields(&user[bi],simCtx->step); CHKERRQ(ierr);
647 }
648 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
649 // ANALYTICAL mode:Call the Analytical Solution Prescription Engine to enable a variety of analytical functions
650 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'analytical'. Updating Eulerian field via the Analytical Solution Engine ...\n");
651 ierr = AnalyticalSolutionEngine(simCtx); CHKERRQ(ierr);
652 }else if(strcmp(simCtx->eulerianSource,"solve")==0){
653 // SOLVE mode:Call the refactored, high-level legacy solver. This single function
654 // advances the entire multi-block fluid field from t_n to t_{n+1}.
655 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'solve'. Updating Eulerian field via Solver...\n");
656 ierr = FlowSolver(simCtx); CHKERRQ(ierr);
657 }
658 LOG_ALLOW(GLOBAL, LOG_INFO, "Eulerian Field Updated ...\n");
660 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post FlowSolver field states:\n");
661 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PostFlowSolver"); CHKERRQ(ierr);
662 ierr = LOG_FIELD_ANATOMY(&user[0],"P","PostFlowSolver"); CHKERRQ(ierr);
663 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucont","PostFlowSolver"); CHKERRQ(ierr);
664 }
665
666
667 // =================================================================
668 // 3. LAGRANGIAN PARTICLE STEP
669 // =================================================================
670
671 if (simCtx->np > 0) {
672 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Lagrangian particle system...\n");
673 simCtx->particlesLostLastStep = 0;
674
675 // a. Update Eulerian Transport Properties:
676 // Optimization: Only recalculate if turbulence is active (Nu_t changes).
677 // For Laminar flow, the value calculated at Setup is constant.
678 if (simCtx->les || simCtx->rans) {
679 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
680 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
681 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
682 }
683 }
684
685 // a.1 (Optional) Log Eulerian Diffusivity min/max and anatomy for debugging.
687 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Min/Max:\n");
688 ierr = LOG_FIELD_MIN_MAX(&user[0],"Diffusivity"); CHKERRQ(ierr);
689 ierr = LOG_FIELD_MIN_MAX(&user[0],"DiffusivityGradient"); CHKERRQ(ierr);
690 //LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Anatomy:\n");
691 ierr = LOG_FIELD_ANATOMY(&user[0],"Diffusivity","PostDiffusivityUpdate"); CHKERRQ(ierr);
692 }
693 // b. Advect particles using the velocity interpolated from the *previous* step.
694 // P(t_{n+1}) = P(t_n) + V_p(t_n) * dt
695 ierr = UpdateAllParticlePositions(user); CHKERRQ(ierr);
696
697 // c. Settle all particles: find their new host cells and migrate them across ranks.
698 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
699
700 // d. Remove any particles that are now lost or out of the global domain.
701 ierr = CheckAndRemoveLostParticles(user, &removed_local_lost, &removed_global_lost); CHKERRQ(ierr);
702 //ierr = CheckAndRemoveOutOfBoundsParticles(user, &removed_local_ob, &removed_global_ob, simCtx->bboxlist); CHKERRQ(ierr);
703 simCtx->particlesLostLastStep = removed_global_lost;
704 simCtx->particlesLostCumulative += removed_global_lost;
705 if (removed_global_lost> 0) { // if(removed_global_lost + removed_global_ob > 0){
706 LOG_ALLOW(GLOBAL, LOG_INFO, "Removed %d particles globally this step.\n", removed_global_lost); // removed_global_lost + removed_global_ob;
707 }
708
709 // e. Interpolate the NEW fluid velocity (just computed by FlowSolver) onto the
710 // particles' new positions. This gives them V_p(t_{n+1}) for the *next* advection step.
711 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
712
713 // f. Update the Particle Fields (e.g., temperature, concentration) if applicable.
714 // This can be extended to include reactions, growth, etc.
715 ierr = UpdateAllParticleFields(user); CHKERRQ(ierr);
716
717 // g. (For Two-Way Coupling) Scatter particle data back to the grid to act as a source term.
718 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
719 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
720
721 // h. (Optional) Calculate advanced particle metrics for logging/debugging.
722 ierr = CalculateAdvancedParticleMetrics(user); CHKERRQ(ierr);
723 ierr = LOG_SEARCH_METRICS(user); CHKERRQ(ierr);
724
725 ierr = LOG_PARTICLE_METRICS(user, "Timestep Metrics"); CHKERRQ(ierr);
726
727
729 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post Lagrangian update field states:\n");
730 ierr = LOG_FIELD_MIN_MAX(&user[0],"Psi"); CHKERRQ(ierr);
731 }
732 }
733
734 // =================================================================
735 // 4. UPDATE HISTORY & I/O
736 // =================================================================
737
738 PetscCall(LOG_SOLUTION_CONVERGENCE(simCtx));
739
740 // Copy the newly computed fields (Ucont, P, etc.) to the history vectors
741 // (_o, _rm1) to prepare for the next time step.
742 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
743 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
744 }
745
746 //ierr = LOG_UCAT_ANATOMY(&user[0],"Final"); CHKERRQ(ierr);
747
748 // Handle periodic file output
749 if (ShouldWriteDataOutput(simCtx, simCtx->step)) {
750 LOG_ALLOW(GLOBAL, LOG_INFO, "Writing output for step %d.\n",simCtx->step);
751 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
752 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
753 }
754 if (simCtx->np > 0) {
755 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
756 if (strcmp(simCtx->eulerianSource, "analytical") == 0 &&
759 }
760 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
761 }
762 }
763
764 if (ShouldEmitPeriodicParticleConsoleSnapshot(simCtx, simCtx->step)) {
765 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
766 }
767
768 ProfilingLogTimestepSummary(simCtx, simCtx->step);
769 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Step", "-"); CHKERRQ(ierr);
770
771 // Update Progress Bar
772 if(simCtx->rank == 0) {
773 PrintProgressBar(step,StartStep,StepsToRun,simCtx->ti);
774 if(get_log_level()>=LOG_WARNING) PetscPrintf(PETSC_COMM_SELF,"\n");
775 }
776
777 last_completed_loop_index = step;
778
779 step_elapsed_local = MPI_Wtime() - step_start_seconds;
780 step_elapsed_max = step_elapsed_local;
781 ierr = MPI_Allreduce(&step_elapsed_local, &step_elapsed_max, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
782 if (simCtx->walltimeGuardActive) {
783 UpdateRuntimeWalltimeGuardEstimator(simCtx, step_elapsed_max);
784 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "post-step checkpoint"); CHKERRQ(ierr);
785 }
786
788 ierr = WriteForcedTerminationOutput(simCtx, user, "post-step checkpoint"); CHKERRQ(ierr);
789 terminated_early = PETSC_TRUE;
790 break;
791 }
792 } // --- End of Time-Marching Loop ---
793
794 // After the loop, print the final progress state on rank 0 and add a newline
795 // to ensure subsequent terminal output starts on a fresh line.
796 if (simCtx->rank == 0 && StepsToRun > 0) {
797 if (!terminated_early && last_completed_loop_index >= StartStep) {
798 PrintProgressBar(StartStep + StepsToRun - 1, StartStep, StepsToRun, simCtx->ti);
799 } else if (terminated_early && last_completed_loop_index >= StartStep) {
800 PrintProgressBar(last_completed_loop_index, StartStep, StepsToRun, simCtx->ti);
801 }
802 PetscPrintf(PETSC_COMM_SELF, "\n");
803 fflush(stdout);
804 }
805
806 if (terminated_early) {
808 "Time marching stopped early after %s. Final retained state is step %d at t=%.4f.\n",
809 RuntimeShutdownReasonName(), simCtx->step, simCtx->ti);
810 } else {
811 LOG_ALLOW(GLOBAL, LOG_INFO, "Time marching completed. Final time t=%.4f.\n", simCtx->ti);
812 }
814 PetscFunctionReturn(0);
815}
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.
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 WriteAllSwarmFields(UserCtx *user)
Writes a predefined set of PETSc Swarm fields to files.
Definition io.c:1818
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Reads binary field data for velocity, pressure, and other required vectors.
Definition io.c:1129
PetscBool ShouldWriteDataOutput(const SimCtx *simCtx, PetscInt completed_step)
Returns whether full field/restart output should be written for the.
Definition io.c:70
PetscErrorCode WriteSimulationFields(UserCtx *user)
Writes simulation fields to files.
Definition io.c:1571
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:3182
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
Definition logging.c:183
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:44
PetscErrorCode LOG_INTERPOLATION_ERROR(UserCtx *user)
Logs the interpolation error between the analytical and computed solutions.
Definition logging.c:2719
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:45
PetscBool ShouldEmitPeriodicParticleConsoleSnapshot(const SimCtx *simCtx, PetscInt completed_step)
Returns whether a particle console snapshot should be emitted for the.
Definition logging.c:542
#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:199
PetscBool IsParticleConsoleSnapshotEnabled(const SimCtx *simCtx)
Returns whether periodic particle console snapshots are enabled.
Definition logging.c:525
PetscErrorCode EmitParticleConsoleSnapshot(UserCtx *user, SimCtx *simCtx, PetscInt step)
Emits one particle console snapshot into the main solver log.
Definition logging.c:556
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:820
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
Definition logging.h:83
PetscErrorCode LOG_FIELD_MIN_MAX(UserCtx *user, const char *fieldName)
Computes and logs the local and global min/max values of a 3-component vector field.
Definition logging.c:2301
void PrintProgressBar(PetscInt step, PetscInt startStep, PetscInt totalSteps, PetscReal currentTime)
Prints a progress bar to the console.
Definition logging.c:2254
PetscErrorCode LOG_FIELD_ANATOMY(UserCtx *user, const char *field_name, const char *stage_name)
Logs the anatomy of a specified field at key boundary locations, respecting the solver's specific gri...
Definition logging.c:2449
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:2037
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
Definition logging.c:84
PetscErrorCode ProfilingLogTimestepSummary(SimCtx *simCtx, PetscInt step)
Logs the performance summary for the current timestep and resets timers.
Definition logging.c:1959
PetscErrorCode LOG_PARTICLE_FIELDS(UserCtx *user, PetscInt printInterval)
Prints particle fields in a table that automatically adjusts its column widths.
Definition logging.c:397
PetscErrorCode CalculateAdvancedParticleMetrics(UserCtx *user)
Computes advanced particle statistics and stores them in SimCtx.
Definition logging.c:3128
PetscErrorCode LOG_SCATTER_METRICS(UserCtx *user)
Logs particle-to-grid scatter verification metrics for the prescribed scalar truth path.
Definition logging.c:2795
PetscErrorCode LOG_SOLUTION_CONVERGENCE(SimCtx *simCtx)
Logs physical solution-convergence metrics once per completed timestep.
Definition logging.c:1560
PetscErrorCode LOG_SEARCH_METRICS(UserCtx *user)
Writes compact runtime search metrics to CSV and optionally to console.
Definition logging.c:2977
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:30
@ LOG_WARNING
Non-critical issues that warrant attention.
Definition logging.h:29
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:31
@ LOG_VERBOSE
Extremely detailed logs, typically for development use only.
Definition logging.h:33
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:811
PetscErrorCode ComputeEulerianDiffusivity(UserCtx *user)
Computes the effective diffusivity scalar field (Gamma_eff) on the Eulerian grid.
Definition rhs.c:1959
PetscErrorCode ComputeEulerianDiffusivityGradient(UserCtx *user)
Computes the Eulerian gradient of the effective diffusivity field.
Definition rhs.c:2089
PetscErrorCode InitializeRuntimeSignalHandlers(void)
Implementation of InitializeRuntimeSignalHandlers().
Definition runloop.c:123
static PetscReal RuntimeWalltimeGuardRemainingSeconds(const SimCtx *simCtx)
Internal helper implementation: RuntimeWalltimeGuardRemainingSeconds().
Definition runloop.c:202
static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
Internal helper implementation: MaybeRequestRuntimeWalltimeGuardShutdown().
Definition runloop.c:242
PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
Internal helper implementation: AdvanceSimulation().
Definition runloop.c:574
PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
Implementation of RuntimeWalltimeGuardUpdateEWMA().
Definition runloop.c:150
static PetscBool g_runtime_shutdown_auto_requested
Definition runloop.c:13
static void RuntimeShutdownSignalHandler(int signum)
Internal helper implementation: RuntimeShutdownSignalHandler().
Definition runloop.c:19
static void RuntimeRequestAutoWalltimeGuard(void)
Internal helper implementation: RuntimeRequestAutoWalltimeGuard().
Definition runloop.c:30
PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
Implementation of RuntimeWalltimeGuardConservativeEstimate().
Definition runloop.c:162
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user)
Internal helper implementation: UpdateSolverHistoryVectors().
Definition runloop.c:321
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Implementation of RuntimeWalltimeGuardRequiredHeadroom().
Definition runloop.c:173
PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
Internal helper implementation: FinalizeRestartState().
Definition runloop.c:528
static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
Internal helper implementation: WriteForcedTerminationOutput().
Definition runloop.c:287
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:184
static PetscErrorCode RefreshVerificationScalarScatterState(UserCtx *user)
Applies verification-only scalar truth and refreshes the scattered Eulerian scalar state.
Definition runloop.c:50
static const char * RuntimeShutdownSignalName(PetscInt signum)
Internal helper implementation: RuntimeShutdownSignalName().
Definition runloop.c:63
PetscErrorCode PerformInitializedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformInitializedParticleSetup().
Definition runloop.c:382
static const char * RuntimeShutdownReasonName(void)
Internal helper implementation: RuntimeShutdownReasonName().
Definition runloop.c:83
static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
Internal helper implementation: RegisterRuntimeSignalHandler().
Definition runloop.c:98
static PetscBool RuntimeShutdownRequested(void)
Internal helper implementation: RuntimeShutdownRequested().
Definition runloop.c:41
static volatile sig_atomic_t g_runtime_shutdown_signal
Definition runloop.c:12
PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformLoadedParticleSetup().
Definition runloop.c:458
#define __FUNCT__
Definition runloop.c:377
static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
Internal helper implementation: UpdateRuntimeWalltimeGuardEstimator().
Definition runloop.c:214
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
Definition solvers.c:11
UserCtx * user
Definition variables.h:536
PetscBool inletFaceDefined
Definition variables.h:849
PetscMPIInt rank
Definition variables.h:654
PetscInt block_number
Definition variables.h:726
PetscBool walltimeGuardActive
Definition variables.h:796
PetscReal walltimeGuardWarmupTotalSeconds
Definition variables.h:804
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:833
PetscInt rans
Definition variables.h:746
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
Definition variables.h:517
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
Definition variables.h:520
PetscReal StartTime
Definition variables.h:665
PetscBool walltimeGuardHasEWMA
Definition variables.h:806
Vec K_Omega_o
Definition variables.h:886
PetscInt particlesLostLastStep
Definition variables.h:760
PetscInt tiout
Definition variables.h:663
UserMG usermg
Definition variables.h:778
PetscReal walltimeGuardMinSeconds
Definition variables.h:799
Vec K_Omega
Definition variables.h:886
Vec lUcont_rm1
Definition variables.h:864
PetscInt _this
Definition variables.h:843
PetscReal walltimeGuardLatestStepSeconds
Definition variables.h:808
PetscReal dt
Definition variables.h:666
PetscInt StepsToRun
Definition variables.h:662
PetscInt np
Definition variables.h:753
Vec Ucont
Definition variables.h:856
PetscInt StartStep
Definition variables.h:661
Vec lUcont_o
Definition variables.h:863
Vec Ucat_o
Definition variables.h:863
char particleRestartMode[16]
Definition variables.h:759
BoundingBox * bboxlist
Definition variables.h:756
PetscInt walltimeGuardCompletedSteps
Definition variables.h:803
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:671
PetscInt walltimeGuardWarmupSteps
Definition variables.h:797
ParticleInitializationType ParticleInitialization
Definition variables.h:757
Vec lK_Omega_o
Definition variables.h:886
Vec Ucat
Definition variables.h:856
Vec Ucont_o
Definition variables.h:863
PetscInt mglevels
Definition variables.h:543
Vec Nvert_o
Definition variables.h:863
PetscInt particlesLostCumulative
Definition variables.h:761
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:684
PetscReal walltimeGuardWarmupAverageSeconds
Definition variables.h:805
Vec Ucont_rm1
Definition variables.h:864
PetscInt step
Definition variables.h:659
PetscReal walltimeGuardEWMASeconds
Definition variables.h:807
PetscReal walltimeGuardLimitSeconds
Definition variables.h:802
PetscReal walltimeGuardEstimatorAlpha
Definition variables.h:800
PetscInt les
Definition variables.h:746
Vec Nvert
Definition variables.h:856
MGCtx * mgctx
Definition variables.h:546
Vec lNvert_o
Definition variables.h:863
PetscReal ti
Definition variables.h:660
PetscReal walltimeGuardMultiplier
Definition variables.h:798
PetscInt immersed
Definition variables.h:681
PetscReal walltimeGuardJobStartEpochSeconds
Definition variables.h:801
PetscInt LoggingFrequency
Definition variables.h:783
Vec P_o
Definition variables.h:863
Defines a 3D axis-aligned bounding box.
Definition variables.h:154
The master context for the entire simulation.
Definition variables.h:651
User-defined context containing data specific to a single computational grid level.
Definition variables.h:830
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.