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
294 "[T=%.4f, Step=%d] Shutdown requested by %s during %s. Writing final output outside the normal cadence before exiting.\n",
295 simCtx->ti, simCtx->step, RuntimeShutdownReasonName(), phase);
296
297 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
298 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
299 }
300
301 if (simCtx->np > 0) {
302 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
303 }
304
306 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
307 }
308
309 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRMPI(ierr);
310 fflush(stdout);
311
312 PetscFunctionReturn(0);
313}
314
315/**
316 * @brief Internal helper implementation: `UpdateSolverHistoryVectors()`.
317 * @details Local to this translation unit.
318 */
320{
321 PetscErrorCode ierr;
322 SimCtx *simCtx = user->simCtx; // Access global settings if needed
323
324 PetscFunctionBeginUser;
325 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d, Block %d: Updating solver history vectors.\n",
326 simCtx->rank, user->_this);
327
328 // --- Primary Contravariant Velocity History ---
329 // The order is critical here.
330 // 1. First, move the n-1 state (Ucont_o) to the n-2 slot (Ucont_rm1).
331 ierr = VecCopy(user->Ucont_o, user->Ucont_rm1); CHKERRQ(ierr);
332 // 2. Then, move the new n state (Ucont) to the n-1 slot (Ucont_o).
333 ierr = VecCopy(user->Ucont, user->Ucont_o); CHKERRQ(ierr);
334
335 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucont history updated.\n",simCtx->rank,user->_this);
336
337 // --- Update History for Other Fields ---
338 // These are typically only needed at the n-1 state.
339 ierr = VecCopy(user->Ucat, user->Ucat_o); CHKERRQ(ierr);
340 ierr = VecCopy(user->P, user->P_o); CHKERRQ(ierr);
341 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucat & P history updated.\n",simCtx->rank,user->_this);
342
343 if (simCtx->immersed) {
344 ierr = VecCopy(user->Nvert, user->Nvert_o); CHKERRQ(ierr);
345 }
346
347 // --- Update History for Turbulence Models (if active) ---
348 if (simCtx->rans) {
349 ierr = VecCopy(user->K_Omega, user->K_Omega_o); CHKERRQ(ierr);
350 }
351
352 // --- Synchronize Local Ghost Regions for the new history vectors ---
353 // This is essential so that stencils in the next time step's calculations
354 // have correct values from neighboring processes.
355 ierr = DMGlobalToLocalBegin(user->fda, user->Ucont_o, INSERT_VALUES, user->lUcont_o); CHKERRQ(ierr);
356 ierr = DMGlobalToLocalEnd(user->fda, user->Ucont_o, INSERT_VALUES, user->lUcont_o); CHKERRQ(ierr);
357
358 ierr = DMGlobalToLocalBegin(user->fda, user->Ucont_rm1, INSERT_VALUES, user->lUcont_rm1); CHKERRQ(ierr);
359 ierr = DMGlobalToLocalEnd(user->fda, user->Ucont_rm1, INSERT_VALUES, user->lUcont_rm1); CHKERRQ(ierr);
360
361 if (simCtx->immersed) {
362 ierr = DMGlobalToLocalBegin(user->da, user->Nvert_o, INSERT_VALUES, user->lNvert_o); CHKERRQ(ierr);
363 ierr = DMGlobalToLocalEnd(user->da, user->Nvert_o, INSERT_VALUES, user->lNvert_o); CHKERRQ(ierr);
364 }
365
366 if (simCtx->rans) {
367 ierr = DMGlobalToLocalBegin(user->fda2, user->K_Omega_o, INSERT_VALUES, user->lK_Omega_o); CHKERRQ(ierr);
368 ierr = DMGlobalToLocalEnd(user->fda2, user->K_Omega_o, INSERT_VALUES, user->lK_Omega_o); CHKERRQ(ierr);
369 }
370
371 PetscFunctionReturn(0);
372}
373
374#undef __FUNCT__
375#define __FUNCT__ "PerformInitialSetup"
376/**
377 * @brief Internal helper implementation: `PerformInitializedParticleSetup()`.
378 * @details Local to this translation unit.
379 */
381{
382 PetscErrorCode ierr;
383 // --- Get pointers from SimCtx instead of passing them as arguments ---
384 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
385 BoundingBox *bboxlist = simCtx->bboxlist;
386
387 PetscFunctionBeginUser;
388
389 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Performing initial particle setup procedures.\n", simCtx->ti, simCtx->step);
390
391 // --- 0. Loop over all blocks to compute Eulerian diffusivity.
392 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
393 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
394 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
395 }
396
397 // --- 1. Initial Particle Settlement (Location and Migration) ---
398 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Initial Settlement: Locating and migrating all particles...\n", simCtx->ti, simCtx->step);
399 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
400
402 LOG_ALLOW(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after Initial settlement...\n", simCtx->ti, simCtx->step);
403 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
404 }
405
406 // --- 2. Re-initialize Particles on Inlet Surface (if applicable) ---
409 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Re-initializing particles on inlet surface...\n", simCtx->ti, simCtx->step);
410 ierr = ReinitializeParticlesOnInletSurface(user, simCtx->ti, simCtx->step); CHKERRQ(ierr);
411
412 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Resetting statuses for post-reinitialization settlement.\n", simCtx->ti, simCtx->step);
413 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
414
415 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Post-Reinitialization Settlement...\n", simCtx->ti, simCtx->step);
416 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
417
418 }
419
420 // --- 3. Finalize State for t=0 ---
421 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
422 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
423 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
424
425 // --- 4. Initial History and Output ---
426 // Update solver history vectors with the t=0 state before the first real step
427 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
428 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
429 }
430
431 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
432 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
433 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
434
435 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
436 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
437 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
438 }
439 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
440 }
441
443 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
444 }
445
446 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
447 PetscFunctionReturn(0);
448}
449
450#undef __FUNCT__
451#define __FUNCT__ "PerformLoadedParticleSetup"
452/**
453 * @brief Internal helper implementation: `PerformLoadedParticleSetup()`.
454 * @details Local to this translation unit.
455 */
456PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
457{
458 PetscErrorCode ierr;
459 PetscFunctionBeginUser;
460 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
461
462 // --- 0. Re-compute Eulerian Diffusivity from loaded fields.
463 LOG_ALLOW(GLOBAL, LOG_INFO, "Re-computing Eulerian Diffusivity from loaded fields...\n");
464 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
465 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
466 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
467 }
468
469 // 0.1 This moves particles to their correct ranks immediately using the loaded Cell ID.
470 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing fast restart migration using preloaded Cell IDs...\n");
471 ierr = MigrateRestartParticlesUsingCellID(user); CHKERRQ(ierr);
472
473 // 1. To catch any edge cases (particles with invalid CellIDs or newcomers).
474 // Because we kept the statuses, this function will now SKIP all the particles
475 // that are already on the correct rank,
476 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
477
478 if(get_log_level() == LOG_DEBUG){
479 LOG(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after locating loaded particles...\n", simCtx->ti, simCtx->step);
480 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
481 }
482
483 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
484
485 // 2. Ensure particles have velocity from the authoritative loaded grid for consistency.
486 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
487
488 // 3. Update Eulerian source terms from the loaded particle data.
490 ierr = RefreshVerificationScalarScatterState(user); CHKERRQ(ierr);
491 } else {
492 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
493 }
494
495 // --- 4. Initial History and Output ---
496 // Update solver history vectors with the t=0 state before the first real step
497 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
498 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
499 }
500
501 if (simCtx->tiout > 0 || (simCtx->StepsToRun == 0 && simCtx->StartStep == 0)) {
502 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initial simulation data.\n", simCtx->ti, simCtx->step);
503 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
504
505 // --- Eulerian Field Output (MUST loop over all blocks) --- // <<< CHANGED/FIXED
506 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
507 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
508 }
509 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
510 }
511
513 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
514 }
515
516 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
517 PetscFunctionReturn(0);
518}
519
520#undef __FUNCT__
521#define __FUNCT__ "FinalizeRestartState"
522/**
523 * @brief Internal helper implementation: `FinalizeRestartState()`.
524 * @details Local to this translation unit.
525 */
526PetscErrorCode FinalizeRestartState(SimCtx *simCtx)
527{
528 PetscErrorCode ierr;
529 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
530
531 PetscFunctionBeginUser;
532
533 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Finalizing RESTART from state (step=%d, t=%.4f) ---\n", simCtx->StartStep, simCtx->ti);
534
535 // This function only needs to handle the particle finalization logic.
536 // The Eulerian state is assumed to be fully loaded and consistent at this point.
537 if (simCtx->np > 0) {
538
539 // Use the particle restart mode to decide the workflow.
540 if (strcmp(simCtx->particleRestartMode, "load") == 0) {
541 // PARTICLES WERE LOADED: The state is complete, but we must verify
542 // the loaded CellIDs and build the in-memory grid-to-particle links.
543 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'load': Verifying particle locations and building grid links...\n");
544 ierr = PerformLoadedParticleSetup(simCtx); CHKERRQ(ierr);
545
546 } else { // Mode must be "init"
547 // PARTICLES WERE RE-INITIALIZED: They need to be fully settled and coupled
548 // to the surrounding (restarted) fluid state.
549 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'init': Running full initial setup for new particles in restarted flow.\n");
550 ierr = PerformInitializedParticleSetup(simCtx); CHKERRQ(ierr);
551 }
552 } else {
553 LOG_ALLOW(GLOBAL, LOG_INFO, "No particles in simulation, restart finalization is complete.\n");
554
555 // Write the initial eulerian fields (this is done in PerformInitialSetup if particles exist.)
556 for(PetscInt bi = 0; bi < simCtx->block_number; bi ++){
557 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
558 }
559 }
560
561 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Restart state successfully finalized. --\n");
562
563 PetscFunctionReturn(0);
564}
565
566#undef __FUNCT__
567#define __FUNCT__ "AdvanceSimulation"
568/**
569 * @brief Internal helper implementation: `AdvanceSimulation()`.
570 * @details Local to this translation unit.
571 */
572PetscErrorCode AdvanceSimulation(SimCtx *simCtx)
573{
574 PetscErrorCode ierr;
575 PetscReal step_start_seconds = 0.0;
576 PetscReal step_elapsed_local = 0.0;
577 PetscReal step_elapsed_max = 0.0;
578 // Get the master context from the first block. All blocks share it.
579 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
580
581 // Retrieve control parameters from SimCtx for clarity
582 const PetscInt StartStep = simCtx->StartStep;
583 const PetscInt StepsToRun = simCtx->StepsToRun;
584 const PetscReal dt = simCtx->dt;
585
586 // Variables for particle removal statistics
587 //PetscInt removed_local_ob, removed_global_ob;
588 PetscInt removed_local_lost, removed_global_lost;
589 PetscBool terminated_early = PETSC_FALSE;
590 PetscInt last_completed_loop_index = StartStep - 1;
591
592 PetscFunctionBeginUser;
594 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting main time-marching loop: %d steps from step %d (t=%.4f), dt=%.4f\n",
595 StepsToRun, StartStep, simCtx->StartTime, dt);
596
597 // --- Main Time-Marching Loop ---
598 for (PetscInt step = StartStep; step < StartStep + StepsToRun; step++) {
599 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "pre-step checkpoint"); CHKERRQ(ierr);
601 ierr = WriteForcedTerminationOutput(simCtx, user, "pre-step checkpoint"); CHKERRQ(ierr);
602 terminated_early = PETSC_TRUE;
603 break;
604 }
605
606 step_start_seconds = MPI_Wtime();
607
608 // =================================================================
609 // 1. PRE-STEP SETUP
610 // =================================================================
611
612 // Update simulation time and step counters in the master context
613 simCtx->step = step + 1;
614 simCtx->ti += simCtx->dt; //simCtx->StartTime + step * simCtx->dt;
615
616 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Advancing Step %d (To t=%.4f) ---\n", simCtx->step, simCtx->ti);
617
618
619 // For particles, reset their status to prepare for the new advection/location cycle
620 if (simCtx->np > 0) {
621 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Resetting all particle statuses to NEEDS_LOCATION.\n");
622 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
623 }
624
625 // =================================================================
626 // 2. EULERIAN SOLVER STEP
627 // =================================================================
629 ierr = LOG_FIELD_ANATOMY(&user[0],"Coordinates","PreFlowSolver"); CHKERRQ(ierr);
630 ierr = LOG_FIELD_ANATOMY(&user[0],"Csi","PreFlowSolver"); CHKERRQ(ierr);
631 ierr = LOG_FIELD_ANATOMY(&user[0],"Eta","PreFlowSolver"); CHKERRQ(ierr);
632 ierr = LOG_FIELD_ANATOMY(&user[0],"Zet","PreFlowSolver"); CHKERRQ(ierr);
633 ierr = LOG_FIELD_ANATOMY(&user[0],"Center-Coordinates","PreFlowSolver"); CHKERRQ(ierr);
634 ierr = LOG_FIELD_ANATOMY(&user[0],"X-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
635 ierr = LOG_FIELD_ANATOMY(&user[0],"Y-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
636 ierr = LOG_FIELD_ANATOMY(&user[0],"Z-Face-Centers","PreFlowSolver"); CHKERRQ(ierr);
637 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PreFlowSolver"); CHKERRQ(ierr);
638 }
639 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Eulerian Field ...\n");
640 if(strcmp(simCtx->eulerianSource,"load")==0){
641 //LOAD mode: Read pre-computed fields for the current step.
642 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'load': Reading fields (t=%.4f,step=%d)...\n",simCtx->ti,simCtx->step);
643 for(PetscInt bi = 0; bi < simCtx->block_number;bi++){
644 ierr = ReadSimulationFields(&user[bi],simCtx->step); CHKERRQ(ierr);
645 }
646 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
647 // ANALYTICAL mode:Call the Analytical Solution Prescription Engine to enable a variety of analytical functions
648 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'analytical'. Updating Eulerian field via the Analytical Solution Engine ...\n");
649 ierr = AnalyticalSolutionEngine(simCtx); CHKERRQ(ierr);
650 }else if(strcmp(simCtx->eulerianSource,"solve")==0){
651 // SOLVE mode:Call the refactored, high-level legacy solver. This single function
652 // advances the entire multi-block fluid field from t_n to t_{n+1}.
653 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'solve'. Updating Eulerian field via Solver...\n");
654 ierr = FlowSolver(simCtx); CHKERRQ(ierr);
655 }
656 LOG_ALLOW(GLOBAL, LOG_INFO, "Eulerian Field Updated ...\n");
658 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post FlowSolver field states:\n");
659 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucat","PostFlowSolver"); CHKERRQ(ierr);
660 ierr = LOG_FIELD_ANATOMY(&user[0],"P","PostFlowSolver"); CHKERRQ(ierr);
661 ierr = LOG_FIELD_ANATOMY(&user[0],"Ucont","PostFlowSolver"); CHKERRQ(ierr);
662 }
663
664
665 // =================================================================
666 // 3. LAGRANGIAN PARTICLE STEP
667 // =================================================================
668
669 if (simCtx->np > 0) {
670 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Lagrangian particle system...\n");
671 simCtx->particlesLostLastStep = 0;
672
673 // a. Update Eulerian Transport Properties:
674 // Optimization: Only recalculate if turbulence is active (Nu_t changes).
675 // For Laminar flow, the value calculated at Setup is constant.
676 if (simCtx->les || simCtx->rans) {
677 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
678 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
679 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
680 }
681 }
682
683 // a.1 (Optional) Log Eulerian Diffusivity min/max and anatomy for debugging.
685 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Min/Max:\n");
686 ierr = LOG_FIELD_MIN_MAX(&user[0],"Diffusivity"); CHKERRQ(ierr);
687 ierr = LOG_FIELD_MIN_MAX(&user[0],"DiffusivityGradient"); CHKERRQ(ierr);
688 //LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Anatomy:\n");
689 ierr = LOG_FIELD_ANATOMY(&user[0],"Diffusivity","PostDiffusivityUpdate"); CHKERRQ(ierr);
690 }
691 // b. Advect particles using the velocity interpolated from the *previous* step.
692 // P(t_{n+1}) = P(t_n) + V_p(t_n) * dt
693 ierr = UpdateAllParticlePositions(user); CHKERRQ(ierr);
694
695 // c. Settle all particles: find their new host cells and migrate them across ranks.
696 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
697
698 // d. Remove any particles that are now lost or out of the global domain.
699 ierr = CheckAndRemoveLostParticles(user, &removed_local_lost, &removed_global_lost); CHKERRQ(ierr);
700 //ierr = CheckAndRemoveOutOfBoundsParticles(user, &removed_local_ob, &removed_global_ob, simCtx->bboxlist); CHKERRQ(ierr);
701 simCtx->particlesLostLastStep = removed_global_lost;
702 simCtx->particlesLostCumulative += removed_global_lost;
703 if (removed_global_lost> 0) { // if(removed_global_lost + removed_global_ob > 0){
704 LOG_ALLOW(GLOBAL, LOG_INFO, "Removed %d particles globally this step.\n", removed_global_lost); // removed_global_lost + removed_global_ob;
705 }
706
707 // e. Interpolate the NEW fluid velocity (just computed by FlowSolver) onto the
708 // particles' new positions. This gives them V_p(t_{n+1}) for the *next* advection step.
709 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
710
711 // f. Update the Particle Fields (e.g., temperature, concentration) if applicable.
712 // This can be extended to include reactions, growth, etc.
713 ierr = UpdateAllParticleFields(user); CHKERRQ(ierr);
714
715 // g. (For Two-Way Coupling) Scatter particle data back to the grid to act as a source term.
716 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
717 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
718
719 // h. (Optional) Calculate advanced particle metrics for logging/debugging.
720 ierr = CalculateAdvancedParticleMetrics(user); CHKERRQ(ierr);
721 ierr = LOG_SEARCH_METRICS(user); CHKERRQ(ierr);
722
723 ierr = LOG_PARTICLE_METRICS(user, "Timestep Metrics"); CHKERRQ(ierr);
724
725
727 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post Lagrangian update field states:\n");
728 ierr = LOG_FIELD_MIN_MAX(&user[0],"Psi"); CHKERRQ(ierr);
729 }
730 }
731
732 // =================================================================
733 // 4. UPDATE HISTORY & I/O
734 // =================================================================
735
736 // Copy the newly computed fields (Ucont, P, etc.) to the history vectors
737 // (_o, _rm1) to prepare for the next time step.
738 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
739 ierr = UpdateSolverHistoryVectors(&user[bi]); CHKERRQ(ierr);
740 }
741
742 //ierr = LOG_UCAT_ANATOMY(&user[0],"Final"); CHKERRQ(ierr);
743
744 // Handle periodic file output
745 if (ShouldWriteDataOutput(simCtx, simCtx->step)) {
746 LOG_ALLOW(GLOBAL, LOG_INFO, "Writing output for step %d.\n",simCtx->step);
747 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
748 ierr = WriteSimulationFields(&user[bi]); CHKERRQ(ierr);
749 }
750 if (simCtx->np > 0) {
751 ierr = WriteAllSwarmFields(user); CHKERRQ(ierr);
752 if (strcmp(simCtx->eulerianSource, "analytical") == 0 &&
755 }
756 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
757 }
758 }
759
760 if (ShouldEmitPeriodicParticleConsoleSnapshot(simCtx, simCtx->step)) {
761 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
762 }
763
764 ProfilingLogTimestepSummary(simCtx, simCtx->step);
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:1815
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Reads binary field data for velocity, pressure, and other required vectors.
Definition io.c:1126
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:1568
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:2248
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:1785
#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:779
#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:1367
void PrintProgressBar(PetscInt step, PetscInt startStep, PetscInt totalSteps, PetscReal currentTime)
Prints a progress bar to the console.
Definition logging.c:1320
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:1515
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:1121
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:2194
PetscErrorCode LOG_SCATTER_METRICS(UserCtx *user)
Logs particle-to-grid scatter verification metrics for the prescribed scalar truth path.
Definition logging.c:1861
PetscErrorCode LOG_SEARCH_METRICS(UserCtx *user)
Writes compact runtime search metrics to CSV and optionally to console.
Definition logging.c:2043
@ 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:770
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:572
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:319
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:526
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:380
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:456
#define __FUNCT__
Definition runloop.c:375
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:528
PetscBool inletFaceDefined
Definition variables.h:830
PetscMPIInt rank
Definition variables.h:646
PetscInt block_number
Definition variables.h:712
PetscBool walltimeGuardActive
Definition variables.h:782
PetscReal walltimeGuardWarmupTotalSeconds
Definition variables.h:790
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:814
PetscInt rans
Definition variables.h:732
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
Definition variables.h:509
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
Definition variables.h:512
PetscReal StartTime
Definition variables.h:657
PetscBool walltimeGuardHasEWMA
Definition variables.h:792
Vec K_Omega_o
Definition variables.h:865
PetscInt particlesLostLastStep
Definition variables.h:746
PetscInt tiout
Definition variables.h:655
UserMG usermg
Definition variables.h:764
PetscReal walltimeGuardMinSeconds
Definition variables.h:785
Vec K_Omega
Definition variables.h:865
Vec lUcont_rm1
Definition variables.h:845
PetscInt _this
Definition variables.h:824
PetscReal walltimeGuardLatestStepSeconds
Definition variables.h:794
PetscReal dt
Definition variables.h:658
PetscInt StepsToRun
Definition variables.h:654
PetscInt np
Definition variables.h:739
Vec Ucont
Definition variables.h:837
PetscInt StartStep
Definition variables.h:653
Vec lUcont_o
Definition variables.h:844
Vec Ucat_o
Definition variables.h:844
char particleRestartMode[16]
Definition variables.h:745
BoundingBox * bboxlist
Definition variables.h:742
PetscInt walltimeGuardCompletedSteps
Definition variables.h:789
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:663
PetscInt walltimeGuardWarmupSteps
Definition variables.h:783
ParticleInitializationType ParticleInitialization
Definition variables.h:743
Vec lK_Omega_o
Definition variables.h:865
Vec Ucat
Definition variables.h:837
Vec Ucont_o
Definition variables.h:844
PetscInt mglevels
Definition variables.h:535
Vec Nvert_o
Definition variables.h:844
PetscInt particlesLostCumulative
Definition variables.h:747
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:676
PetscReal walltimeGuardWarmupAverageSeconds
Definition variables.h:791
Vec Ucont_rm1
Definition variables.h:845
PetscInt step
Definition variables.h:651
PetscReal walltimeGuardEWMASeconds
Definition variables.h:793
PetscReal walltimeGuardLimitSeconds
Definition variables.h:788
PetscReal walltimeGuardEstimatorAlpha
Definition variables.h:786
PetscInt les
Definition variables.h:732
Vec Nvert
Definition variables.h:837
MGCtx * mgctx
Definition variables.h:538
Vec lNvert_o
Definition variables.h:844
PetscReal ti
Definition variables.h:652
PetscReal walltimeGuardMultiplier
Definition variables.h:784
PetscInt immersed
Definition variables.h:673
PetscReal walltimeGuardJobStartEpochSeconds
Definition variables.h:787
PetscInt LoggingFrequency
Definition variables.h:769
Vec P_o
Definition variables.h:844
Defines a 3D axis-aligned bounding box.
Definition variables.h:154
The master context for the entire simulation.
Definition variables.h:643
User-defined context containing data specific to a single computational grid level.
Definition variables.h:811
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.