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, const char *fieldName)
 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,
const char *  fieldName 
)

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

220{
221 PetscErrorCode ierr;
222 SimCtx *simCtx = user->simCtx;
223
224 PetscFunctionBeginUser;
225 if (simCtx->initialConditionMode == IC_MODE_FILE) {
226 ierr = LoadInitialUcont(user); CHKERRQ(ierr);
227 } else {
228 ierr = SetInitialInteriorField(user, "Ucont"); CHKERRQ(ierr);
229 }
230 PetscFunctionReturn(0);
231}
PetscErrorCode SetInitialInteriorField(UserCtx *user, const char *fieldName)
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:154
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 360 of file initialcondition.c.

361{
362 PetscErrorCode ierr;
363 UserCtx *user_finest = simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1].user;
364
365 PetscFunctionBeginUser;
366
368
369 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Initializing Eulerian State ---\n");
370
371 if (simCtx->StartStep > 0) {
372 if(strcmp(simCtx->eulerianSource,"analytical")==0){
373 LOG_ALLOW(GLOBAL,LOG_INFO,"Initializing Analytical Solution type: %s (t=%.4f, step=%d).\n",simCtx->AnalyticalSolutionType,simCtx->StartTime,simCtx->StartStep);
374 ierr = AnalyticalSolutionEngine(simCtx);
375 }
376 else{
377 LOG_ALLOW(GLOBAL, LOG_INFO, "Starting from RESTART files (t=%.4f, step=%d).\n",
378 simCtx->StartTime, simCtx->StartStep);
379 ierr = SetInitialFluidState_Load(simCtx); CHKERRQ(ierr);
380 }
381 } else { // StartStep = 0
382 LOG_ALLOW(GLOBAL, LOG_INFO, "Performing a FRESH START (t=0, step=0).\n");
383 if(strcmp(simCtx->eulerianSource,"solve")==0){
384 ierr = SetInitialFluidState_FreshStart(simCtx); CHKERRQ(ierr);
385 }else if(strcmp(simCtx->eulerianSource,"load")==0){
386 LOG_ALLOW(GLOBAL,LOG_INFO,"FRESH START in LOAD mode. Reading files (t=%.4f,step=%d).\n",
387 simCtx->StartTime,simCtx->StartStep);
388 ierr=SetInitialFluidState_Load(simCtx);CHKERRQ(ierr);
389 }else if(strcmp(simCtx->eulerianSource,"analytical")==0){
390 LOG_ALLOW(GLOBAL,LOG_INFO,"FRESH START in ANALYTICAL mode. Initializing Analytical Solution type: %s (t=%.4f,step=%d).\n",
391 simCtx->AnalyticalSolutionType,simCtx->StartTime,simCtx->StartStep);
392 ierr=AnalyticalSolutionEngine(simCtx);CHKERRQ(ierr);
393 }
394 }
395
396 // This crucial step, taken from the end of the legacy setup, ensures
397 // that the history vectors (Ucont_o, Ucont_rm1, etc.) are correctly
398 // populated before the first call to the time-stepping loop.
399 for (PetscInt bi = 0; bi < simCtx->block_number; bi++) {
400 ierr = UpdateSolverHistoryVectors(&user_finest[bi]); CHKERRQ(ierr);
401 }
402
403 LOG_ALLOW(GLOBAL, LOG_INFO, "--- Eulerian State Initialized and History Vectors Populated ---\n");
404
406 PetscFunctionReturn(0);
407}
PetscErrorCode AnalyticalSolutionEngine(SimCtx *simCtx)
Dispatches to the appropriate analytical solution function based on simulation settings.
static PetscErrorCode SetInitialFluidState_Load(SimCtx *simCtx)
Internal helper implementation: SetInitialFluidState_Load().
static PetscErrorCode SetInitialFluidState_FreshStart(SimCtx *simCtx)
Internal helper implementation: SetInitialFluidState_FreshStart().
PetscErrorCode UpdateSolverHistoryVectors(UserCtx *user)
Copies the current time step's solution fields into history vectors (e.g., U(t_n) -> U_o,...
Definition runloop.c:321
UserCtx * user
Definition variables.h:569
PetscInt block_number
Definition variables.h:768
PetscReal StartTime
Definition variables.h:698
UserMG usermg
Definition variables.h:821
PetscInt StartStep
Definition variables.h:694
char eulerianSource[PETSC_MAX_PATH_LEN]
Definition variables.h:704
PetscInt mglevels
Definition variables.h:576
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:717
MGCtx * mgctx
Definition variables.h:579
User-defined context containing data specific to a single computational grid level.
Definition variables.h:876
Here is the call graph for this function:
Here is the caller graph for this function: