PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
Functions
runloop.h File Reference
#include <petscpf.h>
#include <petscdmswarm.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <petsctime.h>
#include <petscsys.h>
#include <petscdmcomposite.h>
#include <petscsystypes.h>
#include "variables.h"
#include "ParticleSwarm.h"
#include "walkingsearch.h"
#include "grid.h"
#include "logging.h"
#include "io.h"
#include "interpolation.h"
#include "initialcondition.h"
#include "AnalyticalSolutions.h"
#include "ParticleMotion.h"
#include "ParticlePhysics.h"
#include "Boundaries.h"
#include "setup.h"
#include "solvers.h"
Include dependency graph for runloop.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

PetscErrorCode InitializeRuntimeSignalHandlers (void)
 Installs lightweight signal handlers for graceful shutdown requests.
 
PetscReal RuntimeWalltimeGuardUpdateEWMA (PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
 Update an EWMA estimate for timestep wall-clock duration.
 
PetscReal RuntimeWalltimeGuardConservativeEstimate (PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
 Return the conservative timestep estimate used by the walltime guard.
 
PetscReal RuntimeWalltimeGuardRequiredHeadroom (PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
 Compute the required shutdown headroom from timestep estimate and floor.
 
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)
 Decide whether the runtime walltime guard should stop before another step.
 
PetscErrorCode UpdateSolverHistoryVectors (UserCtx *user)
 Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o, U_o -> U_rm1) for the next time step's calculations.
 
PetscErrorCode AdvanceSimulation (SimCtx *simCtx)
 Executes the main time-marching loop for the particle simulation.
 
PetscErrorCode PerformInitializedParticleSetup (SimCtx *simCtx)
 Finalizes the simulation setup at t=0, ensuring a consistent state before time marching.
 
PetscErrorCode PerformLoadedParticleSetup (SimCtx *simCtx)
 Finalizes the simulation state after particle and fluid data have been loaded from a restart.
 
PetscErrorCode FinalizeRestartState (SimCtx *simCtx)
 Performs post-load/post-init consistency checks for a restarted simulation.
 

Function Documentation

◆ InitializeRuntimeSignalHandlers()

PetscErrorCode InitializeRuntimeSignalHandlers ( void  )

Installs lightweight signal handlers for graceful shutdown requests.

The handlers only record that a shutdown signal was received. The actual output flush and exit path happens later at safe checkpoints in the run loop.

Returns
PetscErrorCode 0 on success.

Installs lightweight signal handlers for graceful shutdown requests.

Full API contract (arguments, ownership, side effects) is documented with the matching public header declaration.

See also
InitializeRuntimeSignalHandlers()

Definition at line 123 of file runloop.c.

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}
static PetscBool g_runtime_shutdown_auto_requested
Definition runloop.c:13
static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
Internal helper implementation: RegisterRuntimeSignalHandler().
Definition runloop.c:98
static volatile sig_atomic_t g_runtime_shutdown_signal
Definition runloop.c:12
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardUpdateEWMA()

PetscReal RuntimeWalltimeGuardUpdateEWMA ( PetscBool  has_previous,
PetscReal  previous_ewma_seconds,
PetscReal  latest_step_seconds,
PetscReal  alpha 
)

Update an EWMA estimate for timestep wall-clock duration.

Parameters
[in]has_previousWhether a previous EWMA estimate exists.
[in]previous_ewma_secondsPrior EWMA estimate in seconds.
[in]latest_step_secondsLatest completed timestep duration in seconds.
[in]alphaEWMA weighting factor in (0, 1].
Returns
PetscReal Updated EWMA estimate in seconds.

Update an EWMA estimate for timestep wall-clock duration.

Full API contract (arguments, ownership, side effects) is documented with the matching public header declaration.

See also
RuntimeWalltimeGuardUpdateEWMA()

Definition at line 150 of file runloop.c.

151{
152 if (!has_previous) return latest_step_seconds;
153 return alpha * latest_step_seconds + (1.0 - alpha) * previous_ewma_seconds;
154}
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardConservativeEstimate()

PetscReal RuntimeWalltimeGuardConservativeEstimate ( PetscReal  warmup_average_seconds,
PetscReal  ewma_seconds,
PetscReal  latest_step_seconds 
)

Return the conservative timestep estimate used by the walltime guard.

Parameters
[in]warmup_average_secondsAverage duration across warmup steps.
[in]ewma_secondsCurrent EWMA duration estimate.
[in]latest_step_secondsMost recent completed timestep duration.
Returns
PetscReal Conservative timestep estimate in seconds.

Return the conservative timestep estimate used by the walltime guard.

Full API contract (arguments, ownership, side effects) is documented with the matching public header declaration.

See also
RuntimeWalltimeGuardConservativeEstimate()

Definition at line 162 of file runloop.c.

163{
164 return PetscMax(warmup_average_seconds, PetscMax(ewma_seconds, latest_step_seconds));
165}
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardRequiredHeadroom()

PetscReal RuntimeWalltimeGuardRequiredHeadroom ( PetscReal  min_seconds,
PetscReal  multiplier,
PetscReal  conservative_estimate_seconds 
)

Compute the required shutdown headroom from timestep estimate and floor.

Parameters
[in]min_secondsAbsolute minimum shutdown headroom.
[in]multiplierSafety multiplier applied to the timestep estimate.
[in]conservative_estimate_secondsConservative timestep estimate in seconds.
Returns
PetscReal Required headroom in seconds.

Compute the required shutdown headroom from timestep estimate and floor.

Full API contract (arguments, ownership, side effects) is documented with the matching public header declaration.

See also
RuntimeWalltimeGuardRequiredHeadroom()

Definition at line 173 of file runloop.c.

174{
175 return PetscMax(min_seconds, multiplier * conservative_estimate_seconds);
176}
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardShouldTrigger()

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 
)

Decide whether the runtime walltime guard should stop before another step.

Parameters
[in]completed_stepsNumber of completed timesteps observed so far.
[in]warmup_stepsMinimum completed timesteps required before guarding.
[in]remaining_secondsRemaining walltime in seconds.
[in]min_secondsAbsolute minimum shutdown headroom.
[in]multiplierSafety multiplier applied to timestep estimate.
[in]warmup_average_secondsAverage duration across warmup steps.
[in]ewma_secondsCurrent EWMA duration estimate.
[in]latest_step_secondsLatest completed timestep duration.
[out]required_headroom_seconds_outComputed required headroom in seconds.
Returns
PetscBool PETSC_TRUE when shutdown should be requested.

Decide whether the runtime walltime guard should stop before another step.

Full API contract (arguments, ownership, side effects) is documented with the matching public header declaration.

See also
RuntimeWalltimeGuardShouldTrigger()

Definition at line 184 of file runloop.c.

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}
PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
Implementation of RuntimeWalltimeGuardConservativeEstimate().
Definition runloop.c:162
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Implementation of RuntimeWalltimeGuardRequiredHeadroom().
Definition runloop.c:173
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateSolverHistoryVectors()

PetscErrorCode UpdateSolverHistoryVectors ( UserCtx user)

Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o, U_o -> U_rm1) for the next time step's calculations.

This function is critical for multi-step time integration schemes (like BDF2) used by the legacy solver. It must be called at the end of every time step, after the new solution has been fully computed.

The order of operations is important to avoid overwriting data prematurely.

Parameters
userThe UserCtx for a single block. The function modifies the history vectors (Ucont_o, Ucont_rm1, etc.) within this context.
Returns
PetscErrorCode 0 on success.

Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o, U_o -> U_rm1) for the next time step's calculations.

Local to this translation unit.

Definition at line 319 of file runloop.c.

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}
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:44
#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
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:31
PetscMPIInt rank
Definition variables.h:646
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:814
PetscInt rans
Definition variables.h:732
Vec K_Omega_o
Definition variables.h:865
Vec K_Omega
Definition variables.h:865
Vec lUcont_rm1
Definition variables.h:845
PetscInt _this
Definition variables.h:824
Vec Ucont
Definition variables.h:837
Vec lUcont_o
Definition variables.h:844
Vec Ucat_o
Definition variables.h:844
Vec lK_Omega_o
Definition variables.h:865
Vec Ucat
Definition variables.h:837
Vec Ucont_o
Definition variables.h:844
Vec Nvert_o
Definition variables.h:844
Vec Ucont_rm1
Definition variables.h:845
Vec Nvert
Definition variables.h:837
Vec lNvert_o
Definition variables.h:844
PetscInt immersed
Definition variables.h:673
Vec P_o
Definition variables.h:844
The master context for the entire simulation.
Definition variables.h:643
Here is the caller graph for this function:

◆ AdvanceSimulation()

PetscErrorCode AdvanceSimulation ( SimCtx simCtx)

Executes the main time-marching loop for the particle simulation.

This version uses the new, integrated LocateAllParticlesInGrid orchestrator and the ResetAllParticleStatuses helper for a clean, robust, and understandable workflow.

For each timestep, it performs:

  1. Sets the background fluid velocity field (Ucat) for the current step.
  2. Updates particle positions using velocity from the previous step's interpolation.
  3. Removes any particles that have left the global domain.
  4. A single call to ‘LocateAllParticlesInGrid’, which handles all particle location and migration until the swarm is fully settled.
  5. Interpolates the current fluid velocity to the newly settled particle locations.
  6. Scatters particle data back to Eulerian fields.
  7. Outputs data at specified intervals.
Parameters
simCtxPointer to the master simulation context.
Returns
PetscErrorCode 0 on success, non-zero on failure.

Executes the main time-marching loop for the particle simulation.

Local to this translation unit.

Definition at line 572 of file runloop.c.

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 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 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
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
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
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 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_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
static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
Internal helper implementation: MaybeRequestRuntimeWalltimeGuardShutdown().
Definition runloop.c:242
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user)
Internal helper implementation: UpdateSolverHistoryVectors().
Definition runloop.c:319
static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
Internal helper implementation: WriteForcedTerminationOutput().
Definition runloop.c:287
static const char * RuntimeShutdownReasonName(void)
Internal helper implementation: RuntimeShutdownReasonName().
Definition runloop.c:83
static PetscBool RuntimeShutdownRequested(void)
Internal helper implementation: RuntimeShutdownRequested().
Definition runloop.c:41
#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
PetscInt block_number
Definition variables.h:712
PetscBool walltimeGuardActive
Definition variables.h:782
PetscReal StartTime
Definition variables.h:657
PetscInt particlesLostLastStep
Definition variables.h:746
UserMG usermg
Definition variables.h:764
PetscReal dt
Definition variables.h:658
PetscInt StepsToRun
Definition variables.h:654
PetscInt np
Definition variables.h:739
PetscInt StartStep
Definition variables.h:653
BoundingBox * bboxlist
Definition variables.h:742
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:663
PetscInt mglevels
Definition variables.h:535
PetscInt particlesLostCumulative
Definition variables.h:747
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:676
PetscInt step
Definition variables.h:651
PetscInt les
Definition variables.h:732
MGCtx * mgctx
Definition variables.h:538
PetscReal ti
Definition variables.h:652
User-defined context containing data specific to a single computational grid level.
Definition variables.h:811
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformInitializedParticleSetup()

PetscErrorCode PerformInitializedParticleSetup ( SimCtx simCtx)

Finalizes the simulation setup at t=0, ensuring a consistent state before time marching.

This function is called from main() after the initial Eulerian and Lagrangian states have been created but before the main time loop begins. Its responsibilities are:

  1. Settling the particle swarm: Migrates particles to their correct owner ranks and finds their initial host cells. This includes handling special surface initializations.
  2. Coupling the fields: Interpolates the initial Eulerian fields to the settled particle locations.
  3. Preparing for the first step: Scatters particle data back to the grid.
  4. Writing the initial output for step 0.
Parameters
simCtxPointer to the main simulation context structure.
Returns
PetscErrorCode 0 on success, non-zero on failure.

Finalizes the simulation setup at t=0, ensuring a consistent state before time marching.

Local to this translation unit.

Definition at line 380 of file runloop.c.

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}
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...
PetscBool IsParticleConsoleSnapshotEnabled(const SimCtx *simCtx)
Returns whether periodic particle console snapshots are enabled.
Definition logging.c:525
PetscErrorCode LOG_PARTICLE_FIELDS(UserCtx *user, PetscInt printInterval)
Prints particle fields in a table that automatically adjusts its column widths.
Definition logging.c:397
static PetscErrorCode RefreshVerificationScalarScatterState(UserCtx *user)
Applies verification-only scalar truth and refreshes the scattered Eulerian scalar state.
Definition runloop.c:50
PetscBool inletFaceDefined
Definition variables.h:830
@ 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
PetscInt tiout
Definition variables.h:655
ParticleInitializationType ParticleInitialization
Definition variables.h:743
PetscInt LoggingFrequency
Definition variables.h:769
Defines a 3D axis-aligned bounding box.
Definition variables.h:154
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformLoadedParticleSetup()

PetscErrorCode PerformLoadedParticleSetup ( SimCtx simCtx)

Finalizes the simulation state after particle and fluid data have been loaded from a restart.

This helper function performs the critical sequence of operations required to ensure the loaded Lagrangian and Eulerian states are fully consistent and the solver is ready to proceed. This includes:

  1. Verifying particle locations in the grid and building runtime links.
  2. Synchronizing particle velocity with the authoritative grid velocity via interpolation.
  3. Scattering particle source terms (e.g., volume fraction) back to the grid.
  4. Updating the solver's history vectors with the final, fully-coupled state.
  5. Writing the complete, consistent state to output files for the restart step.
Parameters
simCtxThe main simulation context.
Returns
PetscErrorCode 0 on success.

Finalizes the simulation state after particle and fluid data have been loaded from a restart.

Local to this translation unit.

Definition at line 456 of file runloop.c.

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}
PetscErrorCode MigrateRestartParticlesUsingCellID(UserCtx *user)
Fast-path migration for restart particles using preloaded Cell IDs.
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
Definition logging.h:83
PetscBool VerificationScalarOverrideActive(const SimCtx *simCtx)
Reports whether a verification-only scalar override is active.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FinalizeRestartState()

PetscErrorCode FinalizeRestartState ( SimCtx simCtx)

Performs post-load/post-init consistency checks for a restarted simulation.

This function is called from main() ONLY when a restart is being performed (i.e., StartStep > 0). It inspects the particle restart mode to determine the correct finalization procedure for the Lagrangian swarm.

  • If particles were loaded from a file (mode == "load"), it verifies their locations within the grid to establish necessary runtime links.
  • If new particles were initialized into the restarted flow (mode == "init"), it runs the full PerformInitialSetup sequence to migrate, locate, and couple the new particles with the existing fluid state.
Parameters
simCtxThe main simulation context.
Returns
PetscErrorCode 0 on success.

Performs post-load/post-init consistency checks for a restarted simulation.

Local to this translation unit.

Definition at line 526 of file runloop.c.

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}
PetscErrorCode PerformInitializedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformInitializedParticleSetup().
Definition runloop.c:380
PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformLoadedParticleSetup().
Definition runloop.c:456
char particleRestartMode[16]
Definition variables.h:745
Here is the call graph for this function:
Here is the caller graph for this function: