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 = UpdateLocalGhosts(user, "Ucont_o"); CHKERRQ(ierr);
358 ierr = UpdateLocalGhosts(user, "Ucont_rm1"); CHKERRQ(ierr);
359
360 if (simCtx->immersed) {
361 ierr = UpdateLocalGhosts(user, "Nvert_o"); CHKERRQ(ierr);
362 }
363
364 if (simCtx->rans) {
365 ierr = UpdateLocalGhosts(user, "K_Omega_o"); CHKERRQ(ierr);
366 }
367
368 PetscFunctionReturn(0);
369}
370
371#undef __FUNCT__
372#define __FUNCT__ "PerformInitialSetup"
373/**
374 * @brief Internal helper implementation: `PerformInitializedParticleSetup()`.
375 * @details Local to this translation unit.
376 */
378{
379 PetscErrorCode ierr;
380 // --- Get pointers from SimCtx instead of passing them as arguments ---
381 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
382 BoundingBox *bboxlist = simCtx->bboxlist;
383
384 PetscFunctionBeginUser;
385
386 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Performing initial particle setup procedures.\n", simCtx->ti, simCtx->step);
387
388 // --- 0. Loop over all blocks to compute Eulerian diffusivity.
389 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
390 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
391 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
392 }
393
394 // --- 1. Initial Particle Settlement (Location and Migration) ---
395 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Initial Settlement: Locating and migrating all particles...\n", simCtx->ti, simCtx->step);
396 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
397
399 LOG_ALLOW(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after Initial settlement...\n", simCtx->ti, simCtx->step);
400 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
401 }
402
403 // --- 2. Re-initialize Particles on Inlet Surface (if applicable) ---
406 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Re-initializing particles on inlet surface...\n", simCtx->ti, simCtx->step);
407 ierr = ReinitializeParticlesOnInletSurface(user, simCtx->ti, simCtx->step); CHKERRQ(ierr);
408
409 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Resetting statuses for post-reinitialization settlement.\n", simCtx->ti, simCtx->step);
410 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
411
412 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Post-Reinitialization Settlement...\n", simCtx->ti, simCtx->step);
413 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
414
415 }
416
417 // --- 3. Finalize State for t=0 ---
418 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
419 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
420 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
421
422 // --- 4. Initial History and Output ---
423 // Update solver history vectors with the t=0 state before the first real step
424 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
425 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
426 }
427
428 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
429 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
430 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
431
432 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
433 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
434 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
435 }
436 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
437 }
438
440 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
441 }
442
443 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
444 PetscFunctionReturn(0);
445}
446
447#undef __FUNCT__
448#define __FUNCT__ "PerformLoadedParticleSetup"
449/**
450 * @brief Internal helper implementation: `PerformLoadedParticleSetup()`.
451 * @details Local to this translation unit.
452 */
453PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
454{
455 PetscErrorCode ierr;
456 PetscFunctionBeginUser;
457 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
458
459 // --- 0. Re-compute Eulerian Diffusivity from loaded fields.
460 LOG_ALLOW(GLOBAL, LOG_INFO, "Re-computing Eulerian Diffusivity from loaded fields...\n");
461 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
462 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
463 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
464 }
465
466 // 0.1 This moves particles to their correct ranks immediately using the loaded Cell ID.
467 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing fast restart migration using preloaded Cell IDs...\n");
468 ierr = MigrateRestartParticlesUsingCellID(user); CHKERRQ(ierr);
469
470 // 1. To catch any edge cases (particles with invalid CellIDs or newcomers).
471 // Because we kept the statuses, this function will now SKIP all the particles
472 // that are already on the correct rank,
473 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
474
475 if(get_log_level() == LOG_DEBUG){
476 LOG(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after locating loaded particles...\n", simCtx->ti, simCtx->step);
477 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
478 }
479
480 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
481
482 // 2. Ensure particles have velocity from the authoritative loaded grid for consistency.
483 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
484
485 // 3. Update Eulerian source terms from the loaded particle data.
487 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
488 } else {
489 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
490 }
491
492 // --- 4. Initial History and Output ---
493 // Update solver history vectors with the t=0 state before the first real step
494 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
495 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
496 }
497
498 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
499 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
500 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
501
502 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
503 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
504 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
505 }
506 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
507 }
508
510 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
511 }
512
513 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
514 PetscFunctionReturn(0);
515}
516
517#undef __FUNCT__
518#define __FUNCT__ "FinalizeRestartState"
519/**
520 * @brief Internal helper implementation: `FinalizeRestartState()`.
521 * @details Local to this translation unit.
522 */
523PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
524{
525 PetscErrorCode ierr;
526 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
527
528 PetscFunctionBeginUser;
529
530 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Finalizing RESTART from state (step=%d, t=%.4f) ---\n", simCtx->StartStep, simCtx->ti);
531
532 // This function only needs to handle the particle finalization logic.
533 // The Eulerian state is assumed to be fully loaded and consistent at this point.
534 if (simCtx->np > 0) {
535
536 // Use the particle restart mode to decide the workflow.
537 if (strcmp(simCtx->particleRestartMode, "load") == 0) {
538 // PARTICLES WERE LOADED: The state is complete, but we must verify
539 // the loaded CellIDs and build the in-memory grid-to-particle links.
540 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'load': Verifying particle locations and building grid links...\n");
541 ierr = PerformLoadedParticleSetup(simCtx); CHKERRQ(ierr);
542
543 } else { // Mode must be "init"
544 // PARTICLES WERE RE-INITIALIZED: They need to be fully settled and coupled
545 // to the surrounding (restarted) fluid state.
546 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'init': Running full initial setup for new particles in restarted flow.\n");
547 ierr = PerformInitializedParticleSetup(simCtx); CHKERRQ(ierr);
548 }
549 } else {
550 LOG_ALLOW(GLOBAL, LOG_INFO, "No particles in simulation, restart finalization is complete.\n");
551
552 // Write the initial eulerian fields (this is done in PerformInitialSetup if particles exist.)
553 for(PetscInt bi = 0; bi < simCtx->block_number; bi ++){
554 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
555 }
556 }
557
558 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Restart state successfully finalized. --\n");
559
560 PetscFunctionReturn(0);
561}
562
563#undef __FUNCT__
564#define __FUNCT__ "AdvanceSimulation"
565/**
566 * @brief Internal helper implementation: `AdvanceSimulation()`.
567 * @details Local to this translation unit.
568 */
569PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
570{
571 PetscErrorCode ierr;
572 PetscReal step_start_seconds = 0.0;
573 PetscReal step_elapsed_local = 0.0;
574 PetscReal step_elapsed_max = 0.0;
575 // Get the master context from the first block. All blocks share it.
576 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
577
578 // Retrieve control parameters from SimCtx for clarity
579 const PetscInt StartStep = simCtx->StartStep;
580 const PetscInt StepsToRun = simCtx->StepsToRun;
581 const PetscReal dt = simCtx->dt;
582
583 // Variables for particle removal statistics
584 //PetscInt removed_local_ob, removed_global_ob;
585 PetscInt removed_local_lost, removed_global_lost;
586 PetscBool terminated_early = PETSC_FALSE;
587 PetscInt last_completed_loop_index = StartStep - 1;
588
589 PetscFunctionBeginUser;
591 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting main time-marching loop: %d steps from step %d (t=%.4f), dt=%.4f\n",
592 StepsToRun, StartStep, simCtx->StartTime, dt);
593
594 // --- Main Time-Marching Loop ---
595 for (PetscInt step = StartStep; step < StartStep + StepsToRun; step++) {
596 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "pre-step checkpoint"); CHKERRQ(ierr);
598 ierr = WriteForcedTerminationOutput(simCtx, user, "pre-step checkpoint"); CHKERRQ(ierr);
599 terminated_early = PETSC_TRUE;
600 break;
601 }
602
603 step_start_seconds = MPI_Wtime();
604
605 // =================================================================
606 // 1. PRE-STEP SETUP
607 // =================================================================
608
609 // Update simulation time and step counters in the master context
610 simCtx->step = step + 1;
611 simCtx->ti += simCtx->dt; //simCtx->StartTime + step * simCtx->dt;
612
613 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Advancing Step %d (To t=%.4f) ---\n", simCtx->step, simCtx->ti);
614
615
616 // For particles, reset their status to prepare for the new advection/location cycle
617 if (simCtx->np > 0) {
618 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Resetting all particle statuses to NEEDS_LOCATION.\n");
619 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
620 }
621
622 // =================================================================
623 // 2. EULERIAN SOLVER STEP
624 // =================================================================
626 ierr = LOG_FIELD_ANATOMY(&user[0],"Coordinates","PreFlowSolver"); CHKERRQ(ierr);
627 ierr = LOG_FIELD_ANATOMY(&user[0],"Csi","PreFlowSolver"); CHKERRQ(ierr);
628 ierr = LOG_FIELD_ANATOMY(&user[0],"Eta","PreFlowSolver"); CHKERRQ(ierr);
629 ierr = LOG_FIELD_ANATOMY(&user[0],"Zet","PreFlowSolver"); CHKERRQ(ierr);
630 ierr = LOG_FIELD_ANATOMY(&user[0],"Center-Coordinates","PreFlowSolver"); CHKERRQ(ierr);
631 ierr = LOG_FIELD_ANATOMY(&user[0],"X-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
632 ierr = LOG_FIELD_ANATOMY(&user[0],"Y-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
633 ierr = LOG_FIELD_ANATOMY(&user[0],"Z-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
634 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PreFlowSolver"); CHKERRQ(ierr);
635 }
636 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Eulerian Field ...\n");
637 if(strcmp(simCtx->eulerianSource,"load")==0){
638 //LOAD mode: Read pre-computed fields for the current step.
639 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'load': Reading fields (t=%.4f,step=%d)...\n",simCtx->ti,simCtx->step);
640 for(PetscInt bi = 0; bi < simCtx->block_number;bi++){
641 ierr = ReadSimulationFields(&user[bi],simCtx->step); CHKERRQ(ierr);
642 }
643 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
644 // ANALYTICAL mode:Call the Analytical Solution Prescription Engine to enable a variety of analytical functions
645 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'analytical'. Updating Eulerian field via the Analytical Solution Engine ...\n");
646 ierr = AnalyticalSolutionEngine(simCtx); CHKERRQ(ierr);
647 }else if(strcmp(simCtx->eulerianSource,"solve")==0){
648 // SOLVE mode:Call the refactored, high-level legacy solver. This single function
649 // advances the entire multi-block fluid field from t_n to t_{n+1}.
650 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'solve'. Updating Eulerian field via Solver...\n");
651 ierr = FlowSolver(simCtx); CHKERRQ(ierr);
652 }
653 LOG_ALLOW(GLOBAL, LOG_INFO, "Eulerian Field Updated ...\n");
655 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post FlowSolver field states:\n");
656 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PostFlowSolver"); CHKERRQ(ierr);
657 ierr = LOG_FIELD_ANATOMY(&user[0],"P","PostFlowSolver"); CHKERRQ(ierr);
658 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucont","PostFlowSolver"); CHKERRQ(ierr);
659 }
660
661
662 // =================================================================
663 // 3. LAGRANGIAN PARTICLE STEP
664 // =================================================================
665
666 if (simCtx->np > 0) {
667 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Lagrangian particle system...\n");
668 simCtx->particlesLostLastStep = 0;
669
670 // a. Update Eulerian Transport Properties:
671 // Optimization: Only recalculate if turbulence is active (Nu_t changes).
672 // For Laminar flow, the value calculated at Setup is constant.
673 if (simCtx->les || simCtx->rans) {
674 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
675 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
676 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
677 }
678 }
679
680 // a.1 (Optional) Log Eulerian Diffusivity min/max and anatomy for debugging.
682 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Min/Max:\n");
683 ierr = LOG_FIELD_MIN_MAX(&user[0],"Diffusivity"); CHKERRQ(ierr);
684 ierr = LOG_FIELD_MIN_MAX(&user[0],"DiffusivityGradient"); CHKERRQ(ierr);
685 //LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Anatomy:\n");
686 ierr = LOG_FIELD_ANATOMY(&user[0],"Diffusivity","PostDiffusivityUpdate"); CHKERRQ(ierr);
687 }
688 // b. Advect particles using the velocity interpolated from the *previous* step.
689 // P(t_{n+1}) = P(t_n) + V_p(t_n) * dt
690 ierr = UpdateAllParticlePositions(user); CHKERRQ(ierr);
691
692 // c. Settle all particles: find their new host cells and migrate them across ranks.
693 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
694
695 // d. Remove any particles that are now lost or out of the global domain.
696 ierr = CheckAndRemoveLostParticles(user, &removed_local_lost, &removed_global_lost); CHKERRQ(ierr);
697 //ierr = CheckAndRemoveOutOfBoundsParticles(user, &removed_local_ob, &removed_global_ob, simCtx->bboxlist); CHKERRQ(ierr);
698 simCtx->particlesLostLastStep = removed_global_lost;
699 simCtx->particlesLostCumulative += removed_global_lost;
700 if (removed_global_lost> 0) { // if(removed_global_lost + removed_global_ob > 0){
701 LOG_ALLOW(GLOBAL, LOG_INFO, "Removed %d particles globally this step.\n", removed_global_lost); // removed_global_lost + removed_global_ob;
702 }
703
704 // e. Interpolate the NEW fluid velocity (just computed by FlowSolver) onto the
705 // particles' new positions. This gives them V_p(t_{n+1}) for the *next* advection step.
706 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
707
708 // f. Update the Particle Fields (e.g., temperature, concentration) if applicable.
709 // This can be extended to include reactions, growth, etc.
710 ierr = UpdateAllParticleFields(user); CHKERRQ(ierr);
711
712 // g. (For Two-Way Coupling) Scatter particle data back to the grid to act as a source term.
713 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
714 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
715
716 // h. (Optional) Calculate advanced particle metrics for logging/debugging.
717 ierr = CalculateAdvancedParticleMetrics(user); CHKERRQ(ierr);
718 ierr = LOG_SEARCH_METRICS(user); CHKERRQ(ierr);
719
720 ierr = LOG_PARTICLE_METRICS(user, "Timestep Metrics"); CHKERRQ(ierr);
721
722
724 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post Lagrangian update field states:\n");
725 ierr = LOG_FIELD_MIN_MAX(&user[0],"Psi"); CHKERRQ(ierr);
726 }
727 }
728
729 // =================================================================
730 // 4. UPDATE HISTORY & I/O
731 // =================================================================
732
733 PetscCall(LOG_SOLUTION_CONVERGENCE(simCtx));
734
735 // Copy the newly computed fields (Ucont, P, etc.) to the history vectors
736 // (_o, _rm1) to prepare for the next time step.
737 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
738 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
739 }
740
741 //ierr = LOG_UCAT_ANATOMY(&user[0],"Final"); CHKERRQ(ierr);
742
743 // Handle periodic file output
744 if (ShouldWriteDataOutput(simCtx, simCtx->step)) {
745 LOG_ALLOW(GLOBAL, LOG_INFO, "Writing output for step %d.\n",simCtx->step);
746 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
747 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
748 }
749 if (simCtx->np > 0) {
750 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
751 if (strcmp(simCtx->eulerianSource, "analytical") == 0 &&
754 }
755 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
756 }
757 }
758
759 if (ShouldEmitPeriodicParticleConsoleSnapshot(simCtx, simCtx->step)) {
760 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
761 }
762
763 ProfilingLogTimestepSummary(simCtx, simCtx->step);
764 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Step", "-"); CHKERRQ(ierr);
765
766 // Update Progress Bar
767 if(simCtx->rank == 0) {
768 PrintProgressBar(step,StartStep,StepsToRun,simCtx->ti);
769 if(get_log_level()>=LOG_WARNING) PetscPrintf(PETSC_COMM_SELF,"\n");
770 }
771
772 last_completed_loop_index = step;
773
774 step_elapsed_local = MPI_Wtime() - step_start_seconds;
775 step_elapsed_max = step_elapsed_local;
776 ierr = MPI_Allreduce(&step_elapsed_local, &step_elapsed_max, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
777 if (simCtx->walltimeGuardActive) {
778 UpdateRuntimeWalltimeGuardEstimator(simCtx, step_elapsed_max);
779 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "post-step checkpoint"); CHKERRQ(ierr);
780 }
781
783 ierr = WriteForcedTerminationOutput(simCtx, user, "post-step checkpoint"); CHKERRQ(ierr);
784 terminated_early = PETSC_TRUE;
785 break;
786 }
787 } // --- End of Time-Marching Loop ---
788
789 // After the loop, print the final progress state on rank 0 and add a newline
790 // to ensure subsequent terminal output starts on a fresh line.
791 if (simCtx->rank == 0 && StepsToRun > 0) {
792 if (!terminated_early && last_completed_loop_index >= StartStep) {
793 PrintProgressBar(StartStep + StepsToRun - 1, StartStep, StepsToRun, simCtx->ti);
794 } else if (terminated_early && last_completed_loop_index >= StartStep) {
795 PrintProgressBar(last_completed_loop_index, StartStep, StepsToRun, simCtx->ti);
796 }
797 PetscPrintf(PETSC_COMM_SELF, "\n");
798 fflush(stdout);
799 }
800
801 if (terminated_early) {
803 "Time marching stopped early after %s. Final retained state is step %d at t=%.4f.\n",
804 RuntimeShutdownReasonName(), simCtx->step, simCtx->ti);
805 } else {
806 LOG_ALLOW(GLOBAL, LOG_INFO, "Time marching completed. Final time t=%.4f.\n", simCtx->ti);
807 }
809 PetscFunctionReturn(0);
810}
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:1810
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:1563
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:3297
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:2825
#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:827
#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:2349
void PrintProgressBar(PetscInt step, PetscInt startStep, PetscInt totalSteps, PetscReal currentTime)
Prints a progress bar to the console.
Definition logging.c:2302
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:2536
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:2085
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:2004
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:3243
PetscErrorCode LOG_SCATTER_METRICS(UserCtx *user)
Logs particle-to-grid scatter verification metrics for the prescribed scalar truth path.
Definition logging.c:2904
PetscErrorCode LOG_SOLUTION_CONVERGENCE(SimCtx *simCtx)
Logs physical solution-convergence metrics once per completed timestep.
Definition logging.c:1599
PetscErrorCode LOG_SEARCH_METRICS(UserCtx *user)
Writes compact runtime search metrics to CSV and optionally to console.
Definition logging.c:3089
@ 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:818
PetscErrorCode ComputeEulerianDiffusivity(UserCtx *user)
Computes the effective diffusivity scalar field (Gamma_eff) on the Eulerian grid.
Definition rhs.c:1810
PetscErrorCode ComputeEulerianDiffusivityGradient(UserCtx *user)
Computes the Eulerian gradient of the effective diffusivity field.
Definition rhs.c:1942
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:569
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:523
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:377
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:453
#define __FUNCT__
Definition runloop.c:372
static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
Internal helper implementation: UpdateRuntimeWalltimeGuardEstimator().
Definition runloop.c:214
PetscErrorCode UpdateLocalGhosts(UserCtx *user, const char *fieldName)
Updates the local vector (including ghost points) from its corresponding global vector.
Definition setup.c:1755
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
Definition solvers.c:11
UserCtx * user
Definition variables.h:569
PetscBool inletFaceDefined
Definition variables.h:897
PetscMPIInt rank
Definition variables.h:687
PetscInt block_number
Definition variables.h:768
PetscBool walltimeGuardActive
Definition variables.h:839
PetscReal walltimeGuardWarmupTotalSeconds
Definition variables.h:847
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:879
PetscInt rans
Definition variables.h:789
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
Definition variables.h:550
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
Definition variables.h:553
PetscReal StartTime
Definition variables.h:698
PetscBool walltimeGuardHasEWMA
Definition variables.h:849
Vec K_Omega_o
Definition variables.h:935
PetscInt particlesLostLastStep
Definition variables.h:803
PetscInt tiout
Definition variables.h:696
UserMG usermg
Definition variables.h:821
PetscReal walltimeGuardMinSeconds
Definition variables.h:842
Vec K_Omega
Definition variables.h:935
PetscInt _this
Definition variables.h:889
PetscReal walltimeGuardLatestStepSeconds
Definition variables.h:851
PetscReal dt
Definition variables.h:699
PetscInt StepsToRun
Definition variables.h:695
PetscInt np
Definition variables.h:796
Vec Ucont
Definition variables.h:904
PetscInt StartStep
Definition variables.h:694
Vec Ucat_o
Definition variables.h:911
char particleRestartMode[16]
Definition variables.h:802
BoundingBox * bboxlist
Definition variables.h:799
PetscInt walltimeGuardCompletedSteps
Definition variables.h:846
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:704
PetscInt walltimeGuardWarmupSteps
Definition variables.h:840
ParticleInitializationType ParticleInitialization
Definition variables.h:800
Vec Ucat
Definition variables.h:904
Vec Ucont_o
Definition variables.h:911
PetscInt mglevels
Definition variables.h:576
Vec Nvert_o
Definition variables.h:911
PetscInt particlesLostCumulative
Definition variables.h:804
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:717
PetscReal walltimeGuardWarmupAverageSeconds
Definition variables.h:848
Vec Ucont_rm1
Definition variables.h:912
PetscInt step
Definition variables.h:692
PetscReal walltimeGuardEWMASeconds
Definition variables.h:850
PetscReal walltimeGuardLimitSeconds
Definition variables.h:845
PetscReal walltimeGuardEstimatorAlpha
Definition variables.h:843
PetscInt les
Definition variables.h:789
Vec Nvert
Definition variables.h:904
MGCtx * mgctx
Definition variables.h:579
PetscReal ti
Definition variables.h:693
PetscReal walltimeGuardMultiplier
Definition variables.h:841
PetscInt immersed
Definition variables.h:714
PetscReal walltimeGuardJobStartEpochSeconds
Definition variables.h:844
PetscInt LoggingFrequency
Definition variables.h:826
Vec P_o
Definition variables.h:911
Defines a 3D axis-aligned bounding box.
Definition variables.h:169
The master context for the entire simulation.
Definition variables.h:684
User-defined context containing data specific to a single computational grid level.
Definition variables.h:876
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.