PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
Functions
initialcondition.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 "AnalyticalSolutions.h"
#include "ParticleMotion.h"
#include "Boundaries.h"
#include "runloop.h"
Include dependency graph for initialcondition.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

PetscErrorCode SetInitialInteriorField (UserCtx *user, FieldId field_id)
 Sets the initial values for the INTERIOR of a specified Eulerian field.
 
PetscErrorCode PopulateInitialUcont (UserCtx *user)
 Populate Ucont for one fresh-start block from the configured IC mode.
 
PetscErrorCode InitializeEulerianState (SimCtx *simCtx)
 High-level orchestrator to set the complete initial state of the Eulerian solver.
 

Function Documentation

◆ SetInitialInteriorField()

PetscErrorCode SetInitialInteriorField ( UserCtx user,
FieldId  field_id 
)

Sets the initial values for the INTERIOR of a specified Eulerian field.

This function initializes the interior nodes of Ucont based on the mode selected by simCtx->initialConditionMode.

Supported profiles for "Ucont":

  • IC_MODE_ZERO: All interior contravariant components are set to zero.
  • IC_MODE_CONSTANT_CARTESIAN: UniformCart2Contra dots the Cartesian vector (InitialConstantContra.x/y/z) with the local metric vectors to fill all three contravariant components correctly across the entire interior.
  • IC_MODE_CONSTANT_STREAMWISE: Sets only the contravariant component along the streamwise axis (from flowDirection or the identified INLET face) proportional to icVelocityPhysical * |A_n|.
  • IC_MODE_POISEUILLE: Separable parabolic profile in the two cross-stream index directions; centerline speed is icVelocityPhysical; streamwise axis from flowDirection or the identified INLET face.
Parameters
userThe main UserCtx struct, containing all simulation data and configuration.
field_idTyped identity of the field to initialize.
Returns
PetscErrorCode 0 on success.

Sets the initial values for the INTERIOR of a specified Eulerian field.

Local to this translation unit.

Definition at line 14 of file initialcondition.c.

15{
16 PetscErrorCode ierr;
17 const char *fieldName = FieldCanonicalName(field_id);
18 PetscFunctionBeginUser;
19
21
22 SimCtx *simCtx = user->simCtx;
23
24 LOG_ALLOW(GLOBAL, LOG_INFO, "Setting initial INTERIOR field for '%s' with mode %d.\n", fieldName, simCtx->initialConditionMode);
25
26 // This function currently only implements logic for Ucont.
27 if (field_id != FIELD_ID_UCONT) {
28 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Skipping SetInitialInteriorField for non-Ucont field '%s'.\n", fieldName);
29
31
32 PetscFunctionReturn(0);
33 }
34
35 // --- 1. Get DMDA info and grid dimensions ---
36 DMDALocalInfo info;
37 ierr = DMDAGetLocalInfo(user->fda, &info); CHKERRQ(ierr);
38
39 const PetscInt im_phys = info.mx - 1;
40 const PetscInt jm_phys = info.my - 1;
41 const PetscInt km_phys = info.mz - 1;
42
43 const PetscReal u_cart = simCtx->InitialConstantContra.x;
44 const PetscReal v_cart = simCtx->InitialConstantContra.y;
45 const PetscReal w_cart = simCtx->InitialConstantContra.z;
46
47 LOG_ALLOW(GLOBAL, LOG_DEBUG, "IC cartesian=(%.3f,%.3f,%.3f) ic_velocity_physical=%.3f mode=%d\n",
48 (double)u_cart, (double)v_cart, (double)w_cart,
49 (double)simCtx->icVelocityPhysical, (int)simCtx->initialConditionMode);
50
51 // --- 2. Early dispatch: cartesian Constant delegates to the uniform converter ---
53 ierr = UniformCart2Contra(user, u_cart, v_cart, w_cart); CHKERRQ(ierr);
55 PetscFunctionReturn(0);
56 }
57
58 // --- 3. Resolve flow direction for streamwise Constant and Poiseuille ---
59 const PetscBool needs_flow_dir = (PetscBool)(
63 PetscInt flow_axis = 0;
64 PetscReal flow_dir_sign = 1.0;
65
66 if (needs_flow_dir) {
67 if (user->inletFaceDefined)
69 else if (simCtx->flowDirection != FLOW_DIR_UNSET)
70 fd = simCtx->flowDirection;
71 else
72 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_USER,
73 "Streamwise Constant and Poiseuille IC modes require either an INLET face or -flow_direction.");
74 flow_axis = (PetscInt)fd / 2;
75 flow_dir_sign = ((PetscInt)fd % 2 == 0) ? 1.0 : -1.0;
76 LOG_ALLOW(GLOBAL, LOG_DEBUG, "IC flow_direction=%d (axis=%d sign=%.1f)\n",
77 (int)fd, (int)flow_axis, (double)flow_dir_sign);
78 }
79
80 // --- 4. Open arrays for non-cartesian modes ---
81 Cmpnts ***csi_arr, ***eta_arr, ***zet_arr;
82 ierr = DMDAVecGetArrayRead(user->fda, user->lCsi, &csi_arr); CHKERRQ(ierr);
83 ierr = DMDAVecGetArrayRead(user->fda, user->lEta, &eta_arr); CHKERRQ(ierr);
84 ierr = DMDAVecGetArrayRead(user->fda, user->lZet, &zet_arr); CHKERRQ(ierr);
85
86 Cmpnts ***ucont_arr;
87 ierr = DMDAVecGetArray(user->fda, user->Ucont, &ucont_arr); CHKERRQ(ierr);
88
89 PetscInt i, j, k;
90 const PetscInt xs = info.xs, xe = info.xs + info.xm;
91 const PetscInt ys = info.ys, ye = info.ys + info.ym;
92 const PetscInt zs = info.zs, ze = info.zs + info.zm;
93
94 for (k = zs; k < ze; k++) {
95 for (j = ys; j < ye; j++) {
96 for (i = xs; i < xe; i++) {
97
98 // Check to ensure we only set initial conditions for PHYSICAL cells, not ghost cells.
99 // Ghost cells (at indices 0 and n) will be set later by ApplyBoundaryConditions.
100 //
101 // Grid structure: For n physical grid points, DMDA has size n+1
102 // - im_phys = mx - 1 = n (number of coordinate points, also equals number of cells + 1)
103 // - Physical cell indices: [1, im_phys-1] = [1, n-1] (gives n-1 physical cells)
104 // - Ghost cells at boundaries: index 0 and index im_phys (= n)
105 //
106 // Example: n=25 physical points → im_phys=25
107 // - Physical cells: indices 1..24 (24 cells)
108 // - Ghost cells: indices 0 and 25
109 const PetscBool is_interior = (i > 0 && i < im_phys &&
110 j > 0 && j < jm_phys &&
111 k > 0 && k < km_phys);
112
113 if (is_interior) {
114 Cmpnts ucont_val = {0.0, 0.0, 0.0}; // Default to zero velocity
115 PetscReal normal_velocity_mag = 0.0;
116
117 switch (simCtx->initialConditionMode) {
118 case IC_MODE_ZERO:
119 break;
121 normal_velocity_mag = simCtx->icVelocityPhysical;
122 break;
124 {
125 PetscInt cs1, cs2, n1, n2;
126 if (flow_axis == 0) { cs1 = j; cs2 = k; n1 = jm_phys; n2 = km_phys; }
127 else if (flow_axis == 1) { cs1 = i; cs2 = k; n1 = im_phys; n2 = km_phys; }
128 else { cs1 = i; cs2 = j; n1 = im_phys; n2 = jm_phys; }
129 const PetscReal w1 = (PetscReal)(n1 - 2);
130 const PetscReal w2 = (PetscReal)(n2 - 2);
131 const PetscReal n1_norm = (cs1 - (1.0 + w1 / 2.0)) / (w1 / 2.0);
132 const PetscReal n2_norm = (cs2 - (1.0 + w2 / 2.0)) / (w2 / 2.0);
133 normal_velocity_mag = simCtx->icVelocityPhysical *
134 (1.0 - n1_norm * n1_norm) * (1.0 - n2_norm * n2_norm);
135 if (normal_velocity_mag < 0.0) normal_velocity_mag = 0.0;
136 }
137 break;
138 default:
139 LOG_ALLOW(LOCAL, LOG_WARNING, "Unrecognized initial-condition mode %d. Defaulting to zero.\n", simCtx->initialConditionMode);
140 break;
141 }
142
143 // Step B: apply flow direction and set the single contravariant flux component.
144 if (normal_velocity_mag != 0.0) {
145 const PetscReal signed_vel = normal_velocity_mag * flow_dir_sign * user->GridOrientation;
146 if (flow_axis == 0) {
147 const PetscReal area = sqrt(csi_arr[k][j][i].x * csi_arr[k][j][i].x +
148 csi_arr[k][j][i].y * csi_arr[k][j][i].y +
149 csi_arr[k][j][i].z * csi_arr[k][j][i].z);
150 ucont_val.x = signed_vel * area;
151 } else if (flow_axis == 1) {
152 const PetscReal area = sqrt(eta_arr[k][j][i].x * eta_arr[k][j][i].x +
153 eta_arr[k][j][i].y * eta_arr[k][j][i].y +
154 eta_arr[k][j][i].z * eta_arr[k][j][i].z);
155 ucont_val.y = signed_vel * area;
156 } else {
157 const PetscReal area = sqrt(zet_arr[k][j][i].x * zet_arr[k][j][i].x +
158 zet_arr[k][j][i].y * zet_arr[k][j][i].y +
159 zet_arr[k][j][i].z * zet_arr[k][j][i].z);
160 ucont_val.z = signed_vel * area;
161 }
162 }
163 ucont_arr[k][j][i] = ucont_val;
164 } // end if(is_interior)
165 }
166 }
167 }
168 ierr = DMDAVecRestoreArray(user->fda, user->Ucont, &ucont_arr); CHKERRQ(ierr);
169
170 // --- 5. Restore arrays ---
171 ierr = DMDAVecRestoreArrayRead(user->fda, user->lCsi, &csi_arr); CHKERRQ(ierr);
172 ierr = DMDAVecRestoreArrayRead(user->fda, user->lEta, &eta_arr); CHKERRQ(ierr);
173 ierr = DMDAVecRestoreArrayRead(user->fda, user->lZet, &zet_arr); CHKERRQ(ierr);
174
176
177 PetscFunctionReturn(0);
178}
const char * FieldCanonicalName(FieldId field_id)
Return the canonical printable name for an ID.
@ FIELD_ID_UCONT
#define LOCAL
Logging scope definitions for controlling message output.
Definition logging.h:45
#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
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:859
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:31
@ LOG_WARNING
Non-critical issues that warrant attention.
Definition logging.h:30
@ LOG_DEBUG
Detailed debugging information.
Definition logging.h:32
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:850
PetscErrorCode UniformCart2Contra(UserCtx *user, PetscReal u, PetscReal v, PetscReal w)
Populate contravariant fluxes from one uniform Cartesian velocity.
Definition setup.c:2853
PetscReal icVelocityPhysical
Definition variables.h:759
PetscBool inletFaceDefined
Definition variables.h:932
BCFace identifiedInletBCFace
Definition variables.h:933
InitialConditionMode initialConditionMode
Definition variables.h:754
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:909
FlowDirection flowDirection
Definition variables.h:758
Vec lZet
Definition variables.h:974
Vec Ucont
Definition variables.h:939
PetscScalar x
Definition variables.h:103
Vec lCsi
Definition variables.h:974
PetscScalar z
Definition variables.h:103
FlowDirection
Primary flow direction for streamwise IC and Poiseuille modes.
Definition variables.h:272
@ FLOW_DIR_UNSET
Definition variables.h:279
@ IC_MODE_CONSTANT_CARTESIAN
Definition variables.h:153
@ IC_MODE_POISEUILLE
Definition variables.h:154
@ IC_MODE_CONSTANT_STREAMWISE
Definition variables.h:155
@ IC_MODE_ZERO
Definition variables.h:152
Cmpnts InitialConstantContra
Definition variables.h:757
PetscInt GridOrientation
Definition variables.h:924
PetscScalar y
Definition variables.h:103
Vec lEta
Definition variables.h:974
A 3D point or vector with PetscScalar components.
Definition variables.h:102
The master context for the entire simulation.
Definition variables.h:695
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PopulateInitialUcont()

PetscErrorCode PopulateInitialUcont ( UserCtx user)

Populate Ucont for one fresh-start block from the configured IC mode.

Built-in modes generate Ucont directly. File mode loads either Ucat or Ucont from the staged IC directory and converts Ucat when necessary.

Parameters
[in,out]userBlock context whose velocity field is populated.
Returns
PETSc error code.

Populate Ucont for one fresh-start block from the configured IC mode.

Definition at line 220 of file initialcondition.c.

221{
222 PetscErrorCode ierr;
223 SimCtx *simCtx = user->simCtx;
224
225 PetscFunctionBeginUser;
226 if (simCtx->initialConditionMode == IC_MODE_FILE) {
227 ierr = LoadInitialUcont(user); CHKERRQ(ierr);
228 } else {
229 ierr = SetInitialInteriorField(user, FIELD_ID_UCONT); CHKERRQ(ierr);
230 }
231 PetscFunctionReturn(0);
232}
PetscErrorCode SetInitialInteriorField(UserCtx *user, FieldId field_id)
Internal helper implementation: SetInitialInteriorField().
static PetscErrorCode LoadInitialUcont(UserCtx *user)
Load a staged file IC and return with Ucont populated.
@ IC_MODE_FILE
Definition variables.h:156
Here is the call graph for this function:
Here is the caller graph for this function:

◆ InitializeEulerianState()

PetscErrorCode InitializeEulerianState ( SimCtx simCtx)

High-level orchestrator to set the complete initial state of the Eulerian solver.

This function is called once from main() before the time loop begins. It inspects the simulation context to determine whether to perform a fresh start (t=0) or restart from saved files. It then delegates to the appropriate helper function. Finally, it initializes the solver's history vectors (Ucont_o, P_o, etc.) to ensure the first time step has the necessary data.

Parameters
simCtxSimulation context controlling the operation.
Returns
PetscErrorCode 0 on success.

High-level orchestrator to set the complete initial state of the Eulerian solver.

Local to this translation unit.

Definition at line 358 of file initialcondition.c.

359{
360 PetscErrorCode ierr;
361 UserCtx *user_finest = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
362
363 PetscFunctionBeginUser;
364
366
367 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initializing Eulerian State ---\n");
368
369 if (simCtx->StartStep > 0) {
370 if(strcmp(simCtx->eulerianSource,"analytical")==0){
371 LOG_ALLOW(GLOBAL,LOG_INFO,"Initializing Analytical Solution type: %s (t=%.4f, step=%d).\n",simCtx->AnalyticalSolutionType,simCtx->StartTime,simCtx->StartStep);
372 ierr = AnalyticalSolutionEngine(simCtx);
373 }
374 else{
375 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting from RESTART files (t=%.4f, step=%d).\n",
376 simCtx->StartTime, simCtx->StartStep);
377 ierr = SetInitialFluidState_Load(simCtx); CHKERRQ(ierr);
378 }
379 /* Statistics resume from the same bundle the flow state came from, and are
380 * restored regardless of the Eulerian source: an analytical restart still
381 * continues a window that was accumulating before it. */
382 ierr = RestoreFieldStatisticsState(simCtx, simCtx->StartStep); CHKERRQ(ierr);
383 } else { // StartStep = 0
384 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing a FRESH START (t=0, step=0).\n");
385 if(strcmp(simCtx->eulerianSource,"solve")==0){
386 ierr = SetInitialFluidState_FreshStart(simCtx); CHKERRQ(ierr);
387 }else if(strcmp(simCtx->eulerianSource,"load")==0){
388 LOG_ALLOW(GLOBAL,LOG_INFO,"FRESH START in LOAD mode. Reading files (t=%.4f,step=%d).\n",
389 simCtx->StartTime,simCtx->StartStep);
390 ierr=SetInitialFluidState_Load(simCtx);CHKERRQ(ierr);
391 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
392 LOG_ALLOW(GLOBAL,LOG_INFO,"FRESH START in ANALYTICAL mode. Initializing Analytical Solution type: %s (t=%.4f,step=%d).\n",
393 simCtx->AnalyticalSolutionType,simCtx->StartTime,simCtx->StartStep);
394 ierr=AnalyticalSolutionEngine(simCtx);CHKERRQ(ierr);
395 }
396 }
397
398 // This crucial step, taken from the end of the legacy setup, ensures
399 // that the history vectors (Ucont_o, Ucont_rm1, etc.) are correctly
400 // populated before the first call to the time-stepping loop.
401 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
402 ierr = UpdateSolverHistoryVectors(&user_finest[bi],
403 (PetscBool)(simCtx->StartStep > 0 && simCtx->restartHistoryAvailable)); CHKERRQ(ierr);
404 }
405
406 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Eulerian State Initialized and History Vectors Populated ---\n");
407
409 PetscFunctionReturn(0);
410}
PetscErrorCode AnalyticalSolutionEngine(SimCtx *simCtx)
Dispatches to the appropriate analytical solution function based on simulation settings.
static PetscErrorCode SetInitialFluidState_Load(SimCtx *simCtx)
Restore Eulerian fields from checkpoint files for a restart simulation.
static PetscErrorCode SetInitialFluidState_FreshStart(SimCtx *simCtx)
Initialize Eulerian fields for a new simulation without restart data.
PetscErrorCode RestoreFieldStatisticsState(SimCtx *simCtx, PetscInt ti)
Restores field-statistics window state and accumulators from a checkpoint.
Definition io.c:1667
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user, PetscBool preserve_previous_state)
Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o,...
Definition runloop.c:306
UserCtx * user
Definition variables.h:571
PetscInt block_number
Definition variables.h:790
PetscReal StartTime
Definition variables.h:709
UserMG usermg
Definition variables.h:852
PetscInt StartStep
Definition variables.h:705
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:715
PetscInt mglevels
Definition variables.h:578
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:729
MGCtx * mgctx
Definition variables.h:581
PetscBool restartHistoryAvailable
Definition variables.h:723
User-defined context containing data specific to a single computational grid level.
Definition variables.h:906
Here is the call graph for this function:
Here is the caller graph for this function: