PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Macros | Functions | Variables
runloop.c File Reference

Test program for DMSwarm interpolation using the fdf-curvIB method. More...

#include <signal.h>
#include "runloop.h"
#include "statistics_window.h"
#include "verification_sources.h"
#include "ParticleInitialConditions.h"
Include dependency graph for runloop.c:

Go to the source code of this file.

Macros

#define __FUNCT__   "PerformInitialSetup"
 
#define __FUNCT__   "PerformLoadedParticleSetup"
 
#define __FUNCT__   "FinalizeRestartState"
 
#define __FUNCT__   "AdvanceSimulation"
 

Functions

static void RuntimeShutdownSignalHandler (int signum)
 Record receipt of a termination signal for safe handling by the run loop.
 
static void RuntimeRequestAutoWalltimeGuard (void)
 Request a controlled shutdown because the estimated walltime margin is exhausted.
 
static PetscBool RuntimeShutdownRequested (void)
 Report whether a signal or walltime guard has requested run-loop shutdown.
 
static PetscErrorCode RefreshScatteredParticleState (UserCtx *user)
 Makes the Eulerian particle averages consistent with the particles before step 1.
 
static const char * RuntimeShutdownSignalName (PetscInt signum)
 Translate a recorded termination signal into a user-facing signal name.
 
static const char * RuntimeShutdownReasonName (void)
 Translate the current shutdown reason into a user-facing diagnostic label.
 
static PetscErrorCode RegisterRuntimeSignalHandler (int signum)
 Install the process signal handler used to request graceful simulation shutdown.
 
PetscErrorCode InitializeRuntimeSignalHandlers (void)
 Implementation of InitializeRuntimeSignalHandlers().
 
PetscReal RuntimeWalltimeGuardUpdateEWMA (PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
 Implementation of RuntimeWalltimeGuardUpdateEWMA().
 
PetscReal RuntimeWalltimeGuardConservativeEstimate (PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
 Implementation of RuntimeWalltimeGuardConservativeEstimate().
 
PetscReal RuntimeWalltimeGuardRequiredHeadroom (PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
 Implementation of RuntimeWalltimeGuardRequiredHeadroom().
 
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().
 
static PetscReal RuntimeWalltimeGuardRemainingSeconds (const SimCtx *simCtx)
 Estimate the remaining scheduler walltime after reserving the configured shutdown margin.
 
static void UpdateRuntimeWalltimeGuardEstimator (SimCtx *simCtx, PetscReal completed_step_seconds)
 Update the timestep-duration estimate used by the automatic walltime guard.
 
static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown (SimCtx *simCtx, const char *checkpoint_name)
 Request graceful shutdown when another timestep would exceed the walltime budget.
 
static PetscErrorCode WriteForcedTerminationOutput (SimCtx *simCtx, UserCtx *user, const char *phase)
 Write restart-safe output when a controlled shutdown interrupts the run loop.
 
PetscErrorCode UpdateSolverHistoryVectors (UserCtx *user, PetscBool preserve_previous_state)
 Internal helper implementation: UpdateSolverHistoryVectors().
 
PetscErrorCode PerformInitializedParticleSetup (SimCtx *simCtx)
 Internal helper implementation: PerformInitializedParticleSetup().
 
PetscErrorCode PerformLoadedParticleSetup (SimCtx *simCtx)
 Internal helper implementation: PerformLoadedParticleSetup().
 
PetscErrorCode FinalizeRestartState (SimCtx *simCtx)
 Internal helper implementation: FinalizeRestartState().
 
PetscErrorCode AdvanceSimulation (SimCtx *simCtx)
 Internal helper implementation: AdvanceSimulation().
 

Variables

static volatile sig_atomic_t g_runtime_shutdown_signal = 0
 
static PetscBool g_runtime_shutdown_auto_requested = PETSC_FALSE
 

Detailed Description

Test program for DMSwarm interpolation using the fdf-curvIB method.

Provides the setup to start any simulation with DMSwarm and DMDAs.

Definition in file runloop.c.

Macro Definition Documentation

◆ __FUNCT__ [1/4]

#define __FUNCT__   "PerformInitialSetup"

Definition at line 359 of file runloop.c.

◆ __FUNCT__ [2/4]

#define __FUNCT__   "PerformLoadedParticleSetup"

Definition at line 359 of file runloop.c.

◆ __FUNCT__ [3/4]

#define __FUNCT__   "FinalizeRestartState"

Definition at line 359 of file runloop.c.

◆ __FUNCT__ [4/4]

#define __FUNCT__   "AdvanceSimulation"

Definition at line 359 of file runloop.c.

Function Documentation

◆ RuntimeShutdownSignalHandler()

static void RuntimeShutdownSignalHandler ( int  signum)
static

Record receipt of a termination signal for safe handling by the run loop.

Definition at line 20 of file runloop.c.

21{
24 }
25}
static volatile sig_atomic_t g_runtime_shutdown_signal
Definition runloop.c:14
Here is the caller graph for this function:

◆ RuntimeRequestAutoWalltimeGuard()

static void RuntimeRequestAutoWalltimeGuard ( void  )
static

Request a controlled shutdown because the estimated walltime margin is exhausted.

Definition at line 30 of file runloop.c.

31{
34 }
35}
static PetscBool g_runtime_shutdown_auto_requested
Definition runloop.c:15
Here is the caller graph for this function:

◆ RuntimeShutdownRequested()

static PetscBool RuntimeShutdownRequested ( void  )
static

Report whether a signal or walltime guard has requested run-loop shutdown.

Definition at line 40 of file runloop.c.

41{
43}
Here is the caller graph for this function:

◆ RefreshScatteredParticleState()

static PetscErrorCode RefreshScatteredParticleState ( UserCtx *  user)
static

Makes the Eulerian particle averages consistent with the particles before step 1.

The first step's particle update relaxes each particle toward the scattered Eulerian mean, and its own scatter comes only after that update. So whatever the particles hold at setup - an initial condition, a loaded state, or the verification profile - must be scattered here, or step 1 relaxes toward a mean that never saw it. The verification profile, when active, is applied first. Local to this translation unit.

Definition at line 54 of file runloop.c.

55{
56 PetscFunctionBeginUser;
57 if (!user) PetscFunctionReturn(0);
60 }
62 PetscFunctionReturn(0);
63}
PetscErrorCode ScatterAllParticleFieldsToEulerFields(UserCtx *user)
Scatters a predefined set of particle fields to their corresponding Eulerian fields.
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:1077
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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RuntimeShutdownSignalName()

static const char * RuntimeShutdownSignalName ( PetscInt  signum)
static

Translate a recorded termination signal into a user-facing signal name.

Definition at line 68 of file runloop.c.

69{
70 switch (signum) {
71#ifdef SIGTERM
72 case SIGTERM: return "SIGTERM";
73#endif
74#ifdef SIGUSR1
75 case SIGUSR1: return "SIGUSR1";
76#endif
77#ifdef SIGINT
78 case SIGINT: return "SIGINT";
79#endif
80 default: return "UNKNOWN";
81 }
82}
Here is the caller graph for this function:

◆ RuntimeShutdownReasonName()

static const char * RuntimeShutdownReasonName ( void  )
static

Translate the current shutdown reason into a user-facing diagnostic label.

Definition at line 87 of file runloop.c.

88{
91 }
93 return "AUTO_WALLTIME_GUARD";
94 }
95 return "NONE";
96}
static const char * RuntimeShutdownSignalName(PetscInt signum)
Translate a recorded termination signal into a user-facing signal name.
Definition runloop.c:68
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RegisterRuntimeSignalHandler()

static PetscErrorCode RegisterRuntimeSignalHandler ( int  signum)
static

Install the process signal handler used to request graceful simulation shutdown.

Definition at line 101 of file runloop.c.

102{
103 struct sigaction action;
104
105 PetscFunctionBeginUser;
106 memset(&action, 0, sizeof(action));
107 action.sa_handler = RuntimeShutdownSignalHandler;
108
109 if (sigemptyset(&action.sa_mask) != 0) {
110 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigemptyset failed for signal %d.", signum);
111 }
112
113 if (sigaction(signum, &action, NULL) != 0) {
114 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SYS, "sigaction failed for signal %d.", signum);
115 }
116
117 PetscFunctionReturn(0);
118}
static void RuntimeShutdownSignalHandler(int signum)
Record receipt of a termination signal for safe handling by the run loop.
Definition runloop.c:20
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitializeRuntimeSignalHandlers()

PetscErrorCode InitializeRuntimeSignalHandlers ( void  )

Implementation of InitializeRuntimeSignalHandlers().

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 126 of file runloop.c.

127{
128 PetscErrorCode ierr;
129
130 PetscFunctionBeginUser;
133
134#ifdef SIGTERM
135 ierr = RegisterRuntimeSignalHandler(SIGTERM); CHKERRQ(ierr);
136#endif
137#ifdef SIGUSR1
138 ierr = RegisterRuntimeSignalHandler(SIGUSR1); CHKERRQ(ierr);
139#endif
140#ifdef SIGINT
141 ierr = RegisterRuntimeSignalHandler(SIGINT); CHKERRQ(ierr);
142#endif
143
144 PetscFunctionReturn(0);
145}
static PetscErrorCode RegisterRuntimeSignalHandler(int signum)
Install the process signal handler used to request graceful simulation shutdown.
Definition runloop.c:101
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 
)

Implementation of RuntimeWalltimeGuardUpdateEWMA().

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 153 of file runloop.c.

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

◆ RuntimeWalltimeGuardConservativeEstimate()

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

Implementation of RuntimeWalltimeGuardConservativeEstimate().

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 165 of file runloop.c.

166{
167 return PetscMax(warmup_average_seconds, PetscMax(ewma_seconds, latest_step_seconds));
168}
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardRequiredHeadroom()

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

Implementation of RuntimeWalltimeGuardRequiredHeadroom().

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 176 of file runloop.c.

177{
178 return PetscMax(min_seconds, multiplier * conservative_estimate_seconds);
179}
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 
)

Implementation of RuntimeWalltimeGuardShouldTrigger().

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 187 of file runloop.c.

188{
189 PetscReal conservative_estimate = 0.0;
190 PetscReal required_headroom = 0.0;
191
192 if (required_headroom_seconds_out) *required_headroom_seconds_out = 0.0;
193 if (completed_steps < warmup_steps) return PETSC_FALSE;
194
195 conservative_estimate = RuntimeWalltimeGuardConservativeEstimate(warmup_average_seconds, ewma_seconds, latest_step_seconds);
196 required_headroom = RuntimeWalltimeGuardRequiredHeadroom(min_seconds, multiplier, conservative_estimate);
197 if (required_headroom_seconds_out) *required_headroom_seconds_out = required_headroom;
198 return (PetscBool)(remaining_seconds <= required_headroom);
199}
PetscReal RuntimeWalltimeGuardConservativeEstimate(PetscReal warmup_average_seconds, PetscReal ewma_seconds, PetscReal latest_step_seconds)
Implementation of RuntimeWalltimeGuardConservativeEstimate().
Definition runloop.c:165
PetscReal RuntimeWalltimeGuardRequiredHeadroom(PetscReal min_seconds, PetscReal multiplier, PetscReal conservative_estimate_seconds)
Implementation of RuntimeWalltimeGuardRequiredHeadroom().
Definition runloop.c:176
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RuntimeWalltimeGuardRemainingSeconds()

static PetscReal RuntimeWalltimeGuardRemainingSeconds ( const SimCtx *  simCtx)
static

Estimate the remaining scheduler walltime after reserving the configured shutdown margin.

Definition at line 204 of file runloop.c.

205{
206 time_t now = time(NULL);
207
208 if (now == (time_t)-1) return -1.0;
209 return simCtx->walltimeGuardLimitSeconds - ((PetscReal)now - simCtx->walltimeGuardJobStartEpochSeconds);
210}
PetscReal walltimeGuardLimitSeconds
Definition variables.h:1044
PetscReal walltimeGuardJobStartEpochSeconds
Definition variables.h:1043
Here is the caller graph for this function:

◆ UpdateRuntimeWalltimeGuardEstimator()

static void UpdateRuntimeWalltimeGuardEstimator ( SimCtx *  simCtx,
PetscReal  completed_step_seconds 
)
static

Update the timestep-duration estimate used by the automatic walltime guard.

Definition at line 215 of file runloop.c.

216{
218 simCtx->walltimeGuardLatestStepSeconds = completed_step_seconds;
219
221 simCtx->walltimeGuardWarmupTotalSeconds += completed_step_seconds;
225 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
226 }
227 return;
228 }
229
231 simCtx->walltimeGuardHasEWMA,
233 completed_step_seconds,
235 );
236 simCtx->walltimeGuardHasEWMA = PETSC_TRUE;
237}
PetscReal RuntimeWalltimeGuardUpdateEWMA(PetscBool has_previous, PetscReal previous_ewma_seconds, PetscReal latest_step_seconds, PetscReal alpha)
Implementation of RuntimeWalltimeGuardUpdateEWMA().
Definition runloop.c:153
PetscReal walltimeGuardWarmupTotalSeconds
Definition variables.h:1046
PetscBool walltimeGuardHasEWMA
Definition variables.h:1048
PetscReal walltimeGuardLatestStepSeconds
Definition variables.h:1050
PetscInt walltimeGuardCompletedSteps
Definition variables.h:1045
PetscInt walltimeGuardWarmupSteps
Definition variables.h:1039
PetscReal walltimeGuardWarmupAverageSeconds
Definition variables.h:1047
PetscReal walltimeGuardEWMASeconds
Definition variables.h:1049
PetscReal walltimeGuardEstimatorAlpha
Definition variables.h:1042
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MaybeRequestRuntimeWalltimeGuardShutdown()

static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown ( SimCtx *  simCtx,
const char *  checkpoint_name 
)
static

Request graceful shutdown when another timestep would exceed the walltime budget.

Definition at line 242 of file runloop.c.

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}
#define GLOBAL
Scope for global logging across all processes.
Definition logging.h:46
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
Definition logging.h:200
@ LOG_WARNING
Non-critical issues that warrant attention.
Definition logging.h:30
static PetscReal RuntimeWalltimeGuardRemainingSeconds(const SimCtx *simCtx)
Estimate the remaining scheduler walltime after reserving the configured shutdown margin.
Definition runloop.c:204
static void RuntimeRequestAutoWalltimeGuard(void)
Request a controlled shutdown because the estimated walltime margin is exhausted.
Definition runloop.c:30
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:187
static PetscBool RuntimeShutdownRequested(void)
Report whether a signal or walltime guard has requested run-loop shutdown.
Definition runloop.c:40
PetscBool walltimeGuardActive
Definition variables.h:1038
PetscReal walltimeGuardMinSeconds
Definition variables.h:1041
PetscInt step
Definition variables.h:867
PetscReal ti
Definition variables.h:868
PetscReal walltimeGuardMultiplier
Definition variables.h:1040
Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteForcedTerminationOutput()

static PetscErrorCode WriteForcedTerminationOutput ( SimCtx *  simCtx,
UserCtx *  user,
const char *  phase 
)
static

Write restart-safe output when a controlled shutdown interrupts the run loop.

Definition at line 286 of file runloop.c.

287{
288 PetscErrorCode ierr;
289
290 PetscFunctionBeginUser;
291
292 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Shutdown", RuntimeShutdownReasonName()); CHKERRQ(ierr);
293
295 "[T=%.4f, Step=%d] Shutdown requested by %s during %s. Writing final output outside the normal cadence before exiting.\n",
296 simCtx->ti, simCtx->step, RuntimeShutdownReasonName(), phase);
297
298 ierr = WriteCheckpointBundle(simCtx, "signal"); CHKERRQ(ierr);
299
301 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
302 }
303
304 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRMPI(ierr);
305 fflush(stdout);
306
307 PetscFunctionReturn(0);
308}
PetscErrorCode WriteCheckpointBundle(SimCtx *simCtx, const char *reason)
Write and atomically publish one complete checkpoint bundle.
Definition io.c:2554
PetscBool IsParticleConsoleSnapshotEnabled(const SimCtx *simCtx)
Returns whether periodic particle console snapshots are enabled.
Definition logging.c:528
PetscErrorCode EmitParticleConsoleSnapshot(UserCtx *user, SimCtx *simCtx, PetscInt step)
Emits one particle console snapshot into the main solver log.
Definition logging.c:559
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
Definition logging.h:84
PetscErrorCode RuntimeMemoryLogSample(SimCtx *simCtx, PetscInt step, const char *event, const char *reason)
Append a reduced runtime memory sample to the configured memory log.
Definition logging.c:2195
static const char * RuntimeShutdownReasonName(void)
Translate the current shutdown reason into a user-facing diagnostic label.
Definition runloop.c:87
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateSolverHistoryVectors()

PetscErrorCode UpdateSolverHistoryVectors ( UserCtx *  user,
PetscBool  preserve_previous_state 
)

Internal helper implementation: UpdateSolverHistoryVectors().

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 314 of file runloop.c.

315{
316 PetscErrorCode ierr;
317 SimCtx *simCtx = user->simCtx; // Access global settings if needed
318
319 PetscFunctionBeginUser;
320 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d, Block %d: Updating solver history vectors.\n",
321 simCtx->rank, user->_this);
322
323 // --- Primary Contravariant Velocity History ---
324 // The order is critical here.
325 // 1. Move n-1 into n-2 during normal advancement. A restored checkpoint
326 // already supplied the authoritative n-1 state in Ucont_rm1.
327 if (!preserve_previous_state) {
328 ierr = VecCopy(user->Ucont_o, user->Ucont_rm1); CHKERRQ(ierr);
329 }
330 // 2. Then, move the new n state (Ucont) to the n-1 slot (Ucont_o).
331 ierr = VecCopy(user->Ucont, user->Ucont_o); CHKERRQ(ierr);
332
333 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucont history updated.\n",simCtx->rank,user->_this);
334
335 // --- Update History for Other Fields ---
336 // These are typically only needed at the n-1 state.
337 ierr = VecCopy(user->Ucat, user->Ucat_o); CHKERRQ(ierr);
338 ierr = VecCopy(user->P, user->P_o); CHKERRQ(ierr);
339 LOG_ALLOW(LOCAL,LOG_DEBUG, "Rank %d, Block %d, Ucat & P history updated.\n",simCtx->rank,user->_this);
340
341 if (simCtx->immersed) {
342 ierr = VecCopy(user->Nvert, user->Nvert_o); CHKERRQ(ierr);
343 }
344
345 // --- Synchronize Local Ghost Regions for the new history vectors ---
346 // This is essential so that stencils in the next time step's calculations
347 // have correct values from neighboring processes.
348 ierr = UpdateLocalGhosts(user, FIELD_ID_UCONT_O); CHKERRQ(ierr);
349 ierr = UpdateLocalGhosts(user, FIELD_ID_UCONT_RM1); CHKERRQ(ierr);
350
351 if (simCtx->immersed) {
352 ierr = UpdateLocalGhosts(user, FIELD_ID_NVERT_O); CHKERRQ(ierr);
353 }
354
355 PetscFunctionReturn(0);
356}
@ FIELD_ID_NVERT_O
@ FIELD_ID_UCONT_O
@ FIELD_ID_UCONT_RM1
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:45
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
PetscErrorCode UpdateLocalGhosts(UserCtx *user, FieldId field_id)
Updates the local vector (including ghost points) from its corresponding global vector.
Definition setup.c:2489
PetscMPIInt rank
Definition variables.h:862
PetscInt _this
Definition variables.h:1092
Vec Ucont
Definition variables.h:1113
Vec Ucat_o
Definition variables.h:1120
Vec Ucont_o
Definition variables.h:1120
Vec Nvert_o
Definition variables.h:1120
Vec Ucont_rm1
Definition variables.h:1121
Vec Nvert
Definition variables.h:1113
PetscInt immersed
Definition variables.h:891
The master context for the entire simulation.
Definition variables.h:859
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformInitializedParticleSetup()

PetscErrorCode PerformInitializedParticleSetup ( SimCtx *  simCtx)

Internal helper implementation: PerformInitializedParticleSetup().

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

Local to this translation unit.

Definition at line 364 of file runloop.c.

365{
366 PetscErrorCode ierr;
367 // --- Get pointers from SimCtx instead of passing them as arguments ---
368 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
369 BoundingBox *bboxlist = simCtx->bboxlist;
370
371 PetscFunctionBeginUser;
372
373 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Performing initial particle setup procedures.\n", simCtx->ti, simCtx->step);
374
375 // --- 0. Loop over all blocks to compute Eulerian diffusivity.
376 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
377 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
378 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
379 }
380
381 // --- 1. Initial Particle Settlement (Location and Migration) ---
382 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Initial Settlement: Locating and migrating all particles...\n", simCtx->ti, simCtx->step);
383 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
384
386 LOG_ALLOW(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after Initial settlement...\n", simCtx->ti, simCtx->step);
387 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
388 }
389
390 // --- 2. Re-initialize Particles on Inlet Surface (if applicable) ---
393 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Re-initializing particles on inlet surface...\n", simCtx->ti, simCtx->step);
394 ierr = ReinitializeParticlesOnInletSurface(user, simCtx->ti, simCtx->step); CHKERRQ(ierr);
395
396 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Resetting statuses for post-reinitialization settlement.\n", simCtx->ti, simCtx->step);
397 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
398
399 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Post-Reinitialization Settlement...\n", simCtx->ti, simCtx->step);
400 ierr = LocateAllParticlesInGrid(user, bboxlist); CHKERRQ(ierr);
401
402 }
403
404 // --- 2b. Configured initial particle-field values, once positions are final ---
405 // Surface seeding places particles in step 2, so this comes after it; the scatter
406 // below then carries the values to the Eulerian mean before the first update.
407 if (simCtx->particleFieldPlan) {
408 PetscInt nlocal = 0;
409 ParticleFieldEvent event = {0.0, 0};
410
411 ierr = PicurvPhysicalTime(simCtx, simCtx->ti, &event.physical_time); CHKERRQ(ierr);
412 ierr = DMSwarmGetLocalSize(user->swarm, &nlocal); CHKERRQ(ierr);
413 ierr = ParticleFieldPlanApply(user, simCtx->particleFieldPlan, &event, 0, nlocal); CHKERRQ(ierr);
414 ierr = ParticleFieldPlanSummarize(user, simCtx->particleFieldPlan); CHKERRQ(ierr);
415 }
416
417 // --- 3. Finalize State for t=0 ---
418 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
419 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
420 ierr = RefreshScatteredParticleState(user); CHKERRQ(ierr);
421
422 // --- 4. Initial History and Output ---
423 // Update solver history vectors with the t=0 state before the first real step
424 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
425 ierr = UpdateSolverHistoryVectors(&user[bi],
426 (PetscBool)(simCtx->StartStep > 0 && simCtx->restartHistoryAvailable)); CHKERRQ(ierr);
427 }
428
429 {
430 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing initialized checkpoint.\n", simCtx->ti, simCtx->step);
431 ierr = WriteCheckpointBundle(simCtx, simCtx->StartStep == 0 ? "initial" : "branch_start"); CHKERRQ(ierr);
432 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
433 }
434
436 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
437 }
438
439 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
440 PetscFunctionReturn(0);
441}
PetscErrorCode ParticleFieldPlanSummarize(UserCtx *user, const ParticleFieldPlan *plan)
Log and record the realized initial values of every planned field.
PetscErrorCode ParticleFieldPlanApply(UserCtx *user, const ParticleFieldPlan *plan, const ParticleFieldEvent *event, PetscInt first, PetscInt end)
Write the plan's values into swarm entries [first, end) of this rank.
When and why a plan is applied.
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 InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
PetscErrorCode PicurvPhysicalTime(const SimCtx *simCtx, PetscReal solver_time, PetscReal *physical)
Convert a solver time to physical seconds, t * L_ref / U_ref.
Definition io.c:3177
PetscBool is_function_allowed(const char *functionName)
Checks if a given function is in the allow-list.
Definition logging.c:186
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
Definition logging.c:87
PetscErrorCode LOG_PARTICLE_FIELDS(UserCtx *user, PetscInt printInterval)
Prints particle fields in a table that automatically adjusts its column widths.
Definition logging.c:400
PetscErrorCode LOG_SCATTER_METRICS(UserCtx *user)
Logs particle-to-grid scatter verification metrics for the prescribed scalar truth path.
Definition logging.c:3056
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:31
PetscErrorCode ComputeEulerianDiffusivity(UserCtx *user)
Computes the effective diffusivity scalar field (Gamma_eff) on the Eulerian grid.
Definition rhs.c:1867
PetscErrorCode ComputeEulerianDiffusivityGradient(UserCtx *user)
Computes the Eulerian gradient of the effective diffusivity field.
Definition rhs.c:1999
static PetscErrorCode RefreshScatteredParticleState(UserCtx *user)
Makes the Eulerian particle averages consistent with the particles before step 1.
Definition runloop.c:54
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user, PetscBool preserve_previous_state)
Internal helper implementation: UpdateSolverHistoryVectors().
Definition runloop.c:314
#define __FUNCT__
Definition runloop.c:359
UserCtx * user
Definition variables.h:729
PetscBool inletFaceDefined
Definition variables.h:1100
PetscInt block_number
Definition variables.h:952
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
Definition variables.h:710
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
Definition variables.h:713
UserMG usermg
Definition variables.h:1015
PetscInt StartStep
Definition variables.h:869
BoundingBox * bboxlist
Definition variables.h:993
ParticleInitializationType ParticleInitialization
Definition variables.h:994
PetscInt mglevels
Definition variables.h:736
MGCtx * mgctx
Definition variables.h:739
PetscBool restartHistoryAvailable
Definition variables.h:888
PetscInt LoggingFrequency
Definition variables.h:1020
struct ParticleFieldPlan * particleFieldPlan
Configured initial particle-field values, or NULL.
Definition variables.h:1000
Defines a 3D axis-aligned bounding box.
Definition variables.h:197
User-defined context containing data specific to a single computational grid level.
Definition variables.h:1074
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PerformLoadedParticleSetup()

PetscErrorCode PerformLoadedParticleSetup ( SimCtx *  simCtx)

Internal helper implementation: PerformLoadedParticleSetup().

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

Local to this translation unit.

Definition at line 449 of file runloop.c.

450{
451 PetscErrorCode ierr;
452 PetscFunctionBeginUser;
453 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
454
455 // --- 0. Re-compute Eulerian Diffusivity from loaded fields.
456 LOG_ALLOW(GLOBAL, LOG_INFO, "Re-computing Eulerian Diffusivity from loaded fields...\n");
457 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
458 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
459 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
460 }
461
462 // 0.1 This moves particles to their correct ranks immediately using the loaded Cell ID.
463 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing fast restart migration using preloaded Cell IDs...\n");
464 ierr = MigrateRestartParticlesUsingCellID(user); CHKERRQ(ierr);
465
466 // 1. To catch any edge cases (particles with invalid CellIDs or newcomers).
467 // Because we kept the statuses, this function will now SKIP all the particles
468 // that are already on the correct rank,
469 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
470
471 if(get_log_level() == LOG_DEBUG){
472 LOG(GLOBAL, LOG_DEBUG, "[T=%.4f, Step=%d] Particle field states after locating loaded particles...\n", simCtx->ti, simCtx->step);
473 ierr = LOG_PARTICLE_FIELDS(user,simCtx->LoggingFrequency); CHKERRQ(ierr);
474 }
475
476 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Interpolating initial fields to settled particles.\n", simCtx->ti, simCtx->step);
477
478 // 2. Ensure particles have velocity from the authoritative loaded grid for consistency.
479 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
480
481 // 3. Update Eulerian source terms from the loaded particle data.
482 ierr = RefreshScatteredParticleState(user); CHKERRQ(ierr);
483
484 // --- 4. Initial History and Output ---
485 // Update solver history vectors with the t=0 state before the first real step
486 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
487 ierr = UpdateSolverHistoryVectors(&user[bi],
488 (PetscBool)(simCtx->StartStep > 0 && simCtx->restartHistoryAvailable)); CHKERRQ(ierr);
489 }
490
491 {
492 LOG_ALLOW(GLOBAL, LOG_INFO, "[T=%.4f, Step=%d] Writing restored checkpoint.\n", simCtx->ti, simCtx->step);
493 ierr = WriteCheckpointBundle(simCtx, "branch_start"); CHKERRQ(ierr);
494 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
495 }
496
498 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
499 }
500
501 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initial setup complete. Ready for time marching. ---\n");
502 PetscFunctionReturn(0);
503}
PetscErrorCode MigrateRestartParticlesUsingCellID(UserCtx *user)
Fast-path migration for restart particles using preloaded Cell IDs.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FinalizeRestartState()

PetscErrorCode FinalizeRestartState ( SimCtx *  simCtx)

Internal helper implementation: FinalizeRestartState().

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

Local to this translation unit.

Definition at line 511 of file runloop.c.

512{
513 PetscErrorCode ierr;
514 PetscFunctionBeginUser;
515
516 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Finalizing RESTART from state (step=%d, t=%.4f) ---\n", simCtx->StartStep, simCtx->ti);
517
518 // This function only needs to handle the particle finalization logic.
519 // The Eulerian state is assumed to be fully loaded and consistent at this point.
520 if (simCtx->np > 0) {
521
522 // Use the particle restart mode to decide the workflow.
523 if (strcmp(simCtx->particleRestartMode, "load") == 0) {
524 // PARTICLES WERE LOADED: The state is complete, but we must verify
525 // the loaded CellIDs and build the in-memory grid-to-particle links.
526 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'load': Verifying particle locations and building grid links...\n");
527 ierr = PerformLoadedParticleSetup(simCtx); CHKERRQ(ierr);
528
529 } else { // Mode must be "init"
530 // PARTICLES WERE RE-INITIALIZED: They need to be fully settled and coupled
531 // to the surrounding (restarted) fluid state.
532 LOG_ALLOW(GLOBAL, LOG_INFO, "Particle Mode 'init': Running full initial setup for new particles in restarted flow.\n");
533 ierr = PerformInitializedParticleSetup(simCtx); CHKERRQ(ierr);
534 }
535 } else {
536 LOG_ALLOW(GLOBAL, LOG_INFO, "No particles in simulation, restart finalization is complete.\n");
537
538 ierr = WriteCheckpointBundle(simCtx, "branch_start"); CHKERRQ(ierr);
539 }
540
541 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Restart state successfully finalized. --\n");
542
543 PetscFunctionReturn(0);
544}
PetscErrorCode PerformInitializedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformInitializedParticleSetup().
Definition runloop.c:364
PetscErrorCode PerformLoadedParticleSetup(SimCtx *simCtx)
Internal helper implementation: PerformLoadedParticleSetup().
Definition runloop.c:449
PetscInt np
Definition variables.h:990
char particleRestartMode[16]
Definition variables.h:996
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AdvanceSimulation()

PetscErrorCode AdvanceSimulation ( SimCtx *  simCtx)

Internal helper implementation: AdvanceSimulation().

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

Local to this translation unit.

Definition at line 552 of file runloop.c.

553{
554 PetscErrorCode ierr;
555 PetscReal step_start_seconds = 0.0;
556 PetscReal step_elapsed_local = 0.0;
557 PetscReal step_elapsed_max = 0.0;
558 // Get the master context from the first block. All blocks share it.
559 UserCtx *user = simCtx->usermg.mgctx[simCtx->usermg.mglevels-1].user;
560
561 // Retrieve control parameters from SimCtx for clarity
562 const PetscInt StartStep = simCtx->StartStep;
563 const PetscInt StepsToRun = simCtx->StepsToRun;
564 const PetscReal dt = simCtx->dt;
565
566 // Variables for particle removal statistics
567 //PetscInt removed_local_ob, removed_global_ob;
568 PetscInt removed_local_lost, removed_global_lost;
569 PetscReal removed_scalar_lost = 0.0;
570 PetscBool terminated_early = PETSC_FALSE;
571 PetscInt last_completed_loop_index = StartStep - 1;
572
573 PetscFunctionBeginUser;
575 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting main time-marching loop: %d steps from step %d (t=%.4f), dt=%.4f\n",
576 StepsToRun, StartStep, simCtx->StartTime, dt);
577
578 // --- Main Time-Marching Loop ---
579 for (PetscInt step = StartStep; step < StartStep + StepsToRun; step++) {
580 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "pre-step checkpoint"); CHKERRQ(ierr);
582 ierr = WriteForcedTerminationOutput(simCtx, user, "pre-step checkpoint"); CHKERRQ(ierr);
583 terminated_early = PETSC_TRUE;
584 break;
585 }
586
587 step_start_seconds = MPI_Wtime();
588
589 // =================================================================
590 // 1. PRE-STEP SETUP
591 // =================================================================
592
593 // Update simulation time and step counters in the master context
594 simCtx->step = step + 1;
595 simCtx->ti += simCtx->dt; //simCtx->StartTime + step * simCtx->dt;
596
597 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Advancing Step %d (To t=%.4f) ---\n", simCtx->step, simCtx->ti);
598
599
600 // For particles, reset their status to prepare for the new advection/location cycle
601 if (simCtx->np > 0) {
602 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Resetting all particle statuses to NEEDS_LOCATION.\n");
603 ierr = ResetAllParticleStatuses(user); CHKERRQ(ierr);
604 }
605
606 // =================================================================
607 // 2. EULERIAN SOLVER STEP
608 // =================================================================
610 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_COORDINATES, "PreFlowSolver"); CHKERRQ(ierr);
611 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CSI, "PreFlowSolver"); CHKERRQ(ierr);
612 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_ETA, "PreFlowSolver"); CHKERRQ(ierr);
613 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_ZET, "PreFlowSolver"); CHKERRQ(ierr);
614 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENT, "PreFlowSolver"); CHKERRQ(ierr);
615 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTX, "PreFlowSolver"); CHKERRQ(ierr);
616 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTY, "PreFlowSolver"); CHKERRQ(ierr);
617 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CENTZ, "PreFlowSolver"); CHKERRQ(ierr);
618 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCAT, "PreFlowSolver"); CHKERRQ(ierr);
619 }
620 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Eulerian Field ...\n");
621 if(strcmp(simCtx->eulerianSource,"load")==0){
622 //LOAD mode: Read pre-computed fields for the current step.
623 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'load': Reading fields (t=%.4f,step=%d)...\n",simCtx->ti,simCtx->step);
624 for(PetscInt bi = 0; bi < simCtx->block_number;bi++){
625 ierr = ReadSimulationFields(&user[bi],simCtx->step); CHKERRQ(ierr);
626 }
627 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
628 // ANALYTICAL mode:Call the Analytical Solution Prescription Engine to enable a variety of analytical functions
629 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'analytical'. Updating Eulerian field via the Analytical Solution Engine ...\n");
630 ierr = AnalyticalSolutionEngine(simCtx); CHKERRQ(ierr);
631 }else if(strcmp(simCtx->eulerianSource,"solve")==0){
632 // SOLVE mode:Call the refactored, high-level legacy solver. This single function
633 // advances the entire multi-block fluid field from t_n to t_{n+1}.
634 LOG_ALLOW(GLOBAL,LOG_INFO,"Eulerian Source 'solve'. Updating Eulerian field via Solver...\n");
635 ierr = FlowSolver(simCtx); CHKERRQ(ierr);
636 }
637 LOG_ALLOW(GLOBAL, LOG_INFO, "Eulerian Field Updated ...\n");
639 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post FlowSolver field states:\n");
640 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCAT, "PostFlowSolver"); CHKERRQ(ierr);
641 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_P, "PostFlowSolver"); CHKERRQ(ierr);
642 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_UCONT, "PostFlowSolver"); CHKERRQ(ierr);
643 /* Model fields exist only when their model is active. */
644 if (simCtx->les) {
645 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_NU_T, "PostFlowSolver"); CHKERRQ(ierr);
646 }
647 if (simCtx->les == DYNAMIC_SMAGORINSKY) {
648 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_CS, "PostFlowSolver"); CHKERRQ(ierr);
649 }
650 if (simCtx->wallfunction) {
651 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_U_TAU, "PostFlowSolver"); CHKERRQ(ierr);
652 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_NU_WALL, "PostFlowSolver"); CHKERRQ(ierr);
653 }
654 }
655
656
657 // =================================================================
658 // 3. LAGRANGIAN PARTICLE STEP
659 // =================================================================
660
661 if (simCtx->np > 0) {
662 LOG_ALLOW(GLOBAL, LOG_INFO, "Updating Lagrangian particle system...\n");
663 simCtx->particlesLostLastStep = 0;
664 simCtx->particlesLostScalarLastStep = 0.0;
665
666 // a. Update Eulerian Transport Properties:
667 // Optimization: Only recalculate if turbulence is active (Nu_t changes).
668 // For Laminar flow, the value calculated at Setup is constant.
669 if (simCtx->les) {
670 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
671 ierr = ComputeEulerianDiffusivity(&user[bi]); CHKERRQ(ierr);
672 ierr = ComputeEulerianDiffusivityGradient(&user[bi]); CHKERRQ(ierr);
673 }
674 }
675
676 // a.1 (Optional) Log Eulerian Diffusivity min/max and anatomy for debugging.
678 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Min/Max:\n");
679 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_DIFFUSIVITY); CHKERRQ(ierr);
680 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_DIFFUSIVITY_GRADIENT); CHKERRQ(ierr);
681 //LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Updated Diffusivity Anatomy:\n");
682 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_DIFFUSIVITY, "PostDiffusivityUpdate"); CHKERRQ(ierr);
683 }
684 // b. Advect particles using the velocity interpolated from the *previous* step.
685 // P(t_{n+1}) = P(t_n) + V_p(t_n) * dt
686 ierr = UpdateAllParticlePositions(user); CHKERRQ(ierr);
687
688 // c. Settle all particles: find their new host cells and migrate them across ranks.
689 ierr = LocateAllParticlesInGrid(user, simCtx->bboxlist); CHKERRQ(ierr);
690
691 // d. Remove any particles that are now lost or out of the global domain.
692 ierr = CheckAndRemoveLostParticles(user, &removed_local_lost, &removed_global_lost,
693 &removed_scalar_lost); CHKERRQ(ierr);
694 //ierr = CheckAndRemoveOutOfBoundsParticles(user, &removed_local_ob, &removed_global_ob, simCtx->bboxlist); CHKERRQ(ierr);
695 simCtx->particlesLostLastStep = removed_global_lost;
696 simCtx->particlesLostScalarLastStep = removed_scalar_lost;
697 simCtx->particlesLostCumulative += removed_global_lost;
698 if (removed_global_lost> 0) { // if(removed_global_lost + removed_global_ob > 0){
699 LOG_ALLOW(GLOBAL, LOG_INFO, "Removed %d particles globally this step.\n", removed_global_lost); // removed_global_lost + removed_global_ob;
700 }
701
702 // e. Interpolate the NEW fluid velocity (just computed by FlowSolver) onto the
703 // particles' new positions. This gives them V_p(t_{n+1}) for the *next* advection step.
704 ierr = InterpolateAllFieldsToSwarm(user); CHKERRQ(ierr);
705
706 // f. Update the Particle Fields (e.g., temperature, concentration) if applicable.
707 // This can be extended to include reactions, growth, etc.
708 ierr = UpdateAllParticleFields(user); CHKERRQ(ierr);
709
710 // g. (For Two-Way Coupling) Scatter particle data back to the grid to act as a source term.
711 ierr = CalculateParticleCountPerCell(user); CHKERRQ(ierr);
712 ierr = ScatterAllParticleFieldsToEulerFields(user); CHKERRQ(ierr);
713
714 // h. (Optional) Calculate advanced particle metrics for logging/debugging.
715 ierr = CalculateAdvancedParticleMetrics(user); CHKERRQ(ierr);
716 ierr = LOG_SEARCH_METRICS(user); CHKERRQ(ierr);
717
718 ierr = LOG_PARTICLE_METRICS(user, "Timestep Metrics"); CHKERRQ(ierr);
719
720
722 LOG_ALLOW(GLOBAL, LOG_VERBOSE, "Post Lagrangian update field states:\n");
723 ierr = LOG_FIELD_MIN_MAX(&user[0], FIELD_ID_PSI); CHKERRQ(ierr);
724 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_PSI, "PostScatter"); CHKERRQ(ierr);
725 ierr = LOG_FIELD_ANATOMY(&user[0], FIELD_ID_PARTICLE_COUNT, "PostScatter"); CHKERRQ(ierr);
726 }
727 }
728
729 // =================================================================
730 // 4. UPDATE HISTORY & I/O
731 // =================================================================
732
733 // The completed-state event feeds statistics windows before physical-solution
734 // monitoring, and before history rotation replaces the state just computed.
735 ierr = FieldStatisticsUpdateWindows(simCtx, simCtx->step, simCtx->ti); CHKERRQ(ierr);
737 ierr = EmitStatisticsConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
738 }
739
740 PetscCall(LOG_SOLUTION_CONVERGENCE(simCtx));
741
742 // Copy the newly computed fields (Ucont, P, etc.) to the history vectors
743 // (_o, _rm1) to prepare for the next time step.
744 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
745 ierr = UpdateSolverHistoryVectors(&user[bi], PETSC_FALSE); CHKERRQ(ierr);
746 }
747
748 //ierr = LOG_UCAT_ANATOMY(&user[0],"Final"); CHKERRQ(ierr);
749
750 // Handle periodic file output
751 if (ShouldWriteDataOutput(simCtx, simCtx->step)) {
752 LOG_ALLOW(GLOBAL, LOG_INFO, "Writing output for step %d.\n",simCtx->step);
753 ierr = WriteCheckpointBundle(simCtx, "cadence"); CHKERRQ(ierr);
754 if (simCtx->np > 0) {
755 if (strcmp(simCtx->eulerianSource, "analytical") == 0 &&
758 }
759 ierr = LOG_SCATTER_METRICS(user); CHKERRQ(ierr);
760 }
761 }
762
763 if (ShouldEmitPeriodicParticleConsoleSnapshot(simCtx, simCtx->step)) {
764 ierr = EmitParticleConsoleSnapshot(user, simCtx, simCtx->step); CHKERRQ(ierr);
765 }
766
767 ProfilingLogTimestepSummary(simCtx, simCtx->step);
768 ierr = RuntimeMemoryLogSample(simCtx, simCtx->step, "Step", "-"); CHKERRQ(ierr);
769
770 // Update Progress Bar
771 if(simCtx->rank == 0) {
772 PrintProgressBar(step,StartStep,StepsToRun,simCtx->ti);
773 if(get_log_level()>=LOG_WARNING) PetscPrintf(PETSC_COMM_SELF,"\n");
774 }
775
776 last_completed_loop_index = step;
777
778 step_elapsed_local = MPI_Wtime() - step_start_seconds;
779 step_elapsed_max = step_elapsed_local;
780 ierr = MPI_Allreduce(&step_elapsed_local, &step_elapsed_max, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
781 if (simCtx->walltimeGuardActive) {
782 UpdateRuntimeWalltimeGuardEstimator(simCtx, step_elapsed_max);
783 ierr = MaybeRequestRuntimeWalltimeGuardShutdown(simCtx, "post-step checkpoint"); CHKERRQ(ierr);
784 }
785
787 ierr = WriteForcedTerminationOutput(simCtx, user, "post-step checkpoint"); CHKERRQ(ierr);
788 terminated_early = PETSC_TRUE;
789 break;
790 }
791 } // --- End of Time-Marching Loop ---
792
793 // After the loop, print the final progress state on rank 0 and add a newline
794 // to ensure subsequent terminal output starts on a fresh line.
795 if (simCtx->rank == 0 && StepsToRun > 0) {
796 if (!terminated_early && last_completed_loop_index >= StartStep) {
797 PrintProgressBar(StartStep + StepsToRun - 1, StartStep, StepsToRun, simCtx->ti);
798 } else if (terminated_early && last_completed_loop_index >= StartStep) {
799 PrintProgressBar(last_completed_loop_index, StartStep, StepsToRun, simCtx->ti);
800 }
801 PetscPrintf(PETSC_COMM_SELF, "\n");
802 fflush(stdout);
803 }
804
805 if (terminated_early) {
807 "Time marching stopped early after %s. Final retained state is step %d at t=%.4f.\n",
808 RuntimeShutdownReasonName(), simCtx->step, simCtx->ti);
809 } else {
810 if (StepsToRun > 0) {
811 ierr = WriteCheckpointBundle(simCtx, "final"); CHKERRQ(ierr);
812 }
813 LOG_ALLOW(GLOBAL, LOG_INFO, "Time marching completed. Final time t=%.4f.\n", simCtx->ti);
814 }
816 PetscFunctionReturn(0);
817}
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 CheckAndRemoveLostParticles(UserCtx *user, PetscInt *removedCountLocal, PetscInt *removedCountGlobal, PetscReal *removedScalarSumGlobal)
Removes particles that have been definitively flagged as LOST by the location algorithm.
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 UpdateAllParticleFields(UserCtx *user)
Orchestrates the update of all physical properties for particles.
@ FIELD_ID_PSI
@ FIELD_ID_CENTZ
@ FIELD_ID_CSI
@ FIELD_ID_UCAT
@ FIELD_ID_COORDINATES
@ FIELD_ID_NU_T
@ FIELD_ID_CENTY
@ FIELD_ID_DIFFUSIVITY_GRADIENT
@ FIELD_ID_UCONT
@ FIELD_ID_U_TAU
@ FIELD_ID_ETA
@ FIELD_ID_NU_WALL
@ FIELD_ID_CS
@ FIELD_ID_CENT
@ FIELD_ID_P
@ FIELD_ID_ZET
@ FIELD_ID_CENTX
@ FIELD_ID_PARTICLE_COUNT
@ FIELD_ID_DIFFUSIVITY
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Reads binary field data for velocity, pressure, and other required vectors.
Definition io.c:1471
PetscBool ShouldWriteDataOutput(const SimCtx *simCtx, PetscInt completed_step)
Returns whether full field/restart output should be written for the.
Definition io.c:426
PetscErrorCode LOG_FIELD_MIN_MAX(UserCtx *user, FieldId field_id)
Computes and logs the local and global min/max values of a 3-component vector field.
Definition logging.c:2458
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:3458
PetscBool ShouldEmitPeriodicStatisticsConsoleSnapshot(const struct SimCtx *simCtx, PetscInt completed_step)
Reports whether a completed step falls on the console snapshot cadence.
PetscErrorCode LOG_INTERPOLATION_ERROR(UserCtx *user)
Logs the interpolation error between the analytical and computed solutions.
Definition logging.c:2974
PetscBool ShouldEmitPeriodicParticleConsoleSnapshot(const SimCtx *simCtx, PetscInt completed_step)
Returns whether a particle console snapshot should be emitted for the.
Definition logging.c:545
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:894
PetscErrorCode EmitStatisticsConsoleSnapshot(UserCtx *user, const struct SimCtx *simCtx, PetscInt step)
Emits one console snapshot of window progress.
void PrintProgressBar(PetscInt step, PetscInt startStep, PetscInt totalSteps, PetscReal currentTime)
Prints a progress bar to the console.
Definition logging.c:2411
PetscErrorCode ProfilingLogTimestepSummary(SimCtx *simCtx, PetscInt step)
Logs the performance summary for the current timestep and resets timers.
Definition logging.c:2100
PetscErrorCode CalculateAdvancedParticleMetrics(UserCtx *user)
Computes advanced particle statistics and stores them in SimCtx.
Definition logging.c:3404
PetscErrorCode LOG_SOLUTION_CONVERGENCE(SimCtx *simCtx)
Logs physical solution-convergence metrics once per completed timestep.
Definition logging.c:1695
PetscErrorCode LOG_FIELD_ANATOMY(UserCtx *user, FieldId field_id, const char *stage_name)
Logs the anatomy of a specified field at key boundary locations, respecting the solver's specific gri...
Definition logging.c:2861
PetscErrorCode LOG_SEARCH_METRICS(UserCtx *user)
Writes compact runtime search metrics to CSV and optionally to console.
Definition logging.c:3245
@ LOG_VERBOSE
Extremely detailed logs, typically for development use only.
Definition logging.h:34
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:885
static PetscErrorCode MaybeRequestRuntimeWalltimeGuardShutdown(SimCtx *simCtx, const char *checkpoint_name)
Request graceful shutdown when another timestep would exceed the walltime budget.
Definition runloop.c:242
static PetscErrorCode WriteForcedTerminationOutput(SimCtx *simCtx, UserCtx *user, const char *phase)
Write restart-safe output when a controlled shutdown interrupts the run loop.
Definition runloop.c:286
static void UpdateRuntimeWalltimeGuardEstimator(SimCtx *simCtx, PetscReal completed_step_seconds)
Update the timestep-duration estimate used by the automatic walltime guard.
Definition runloop.c:215
PetscErrorCode FlowSolver(SimCtx *simCtx)
Orchestrates a single time step of the Eulerian fluid solver.
Definition solvers.c:11
PetscErrorCode FieldStatisticsUpdateWindows(struct SimCtx *simCtx, PetscInt step, PetscReal time)
Offers one completed state to every configured window.
@ DYNAMIC_SMAGORINSKY
Definition variables.h:551
PetscReal StartTime
Definition variables.h:873
PetscInt particlesLostLastStep
Definition variables.h:997
PetscReal dt
Definition variables.h:874
PetscInt StepsToRun
Definition variables.h:870
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:879
PetscInt wallfunction
Enable wall functions on WALL faces.
Definition variables.h:985
PetscInt particlesLostCumulative
Definition variables.h:998
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:893
PetscInt les
Active LES closure; an LESModelType value.
Definition variables.h:984
PetscReal particlesLostScalarLastStep
Sum of Psi over the particles removed this step.
Definition variables.h:999
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ g_runtime_shutdown_signal

volatile sig_atomic_t g_runtime_shutdown_signal = 0
static

Definition at line 14 of file runloop.c.

◆ g_runtime_shutdown_auto_requested

PetscBool g_runtime_shutdown_auto_requested = PETSC_FALSE
static

Definition at line 15 of file runloop.c.