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

Go to the source code of this file.

Macros

#define __FUNCT__   "AnalyticalSolutionEngine"
 

Functions

PetscErrorCode SetAnalyticalGridInfo (UserCtx *user)
 Sets the grid domain and resolution for analytical solution cases.
 
PetscBool AnalyticalTypeRequiresCustomGeometry (const char *analytical_type)
 Reports whether an analytical type requires custom geometry/decomposition logic.
 
PetscErrorCode AnalyticalSolutionEngine (SimCtx *simCtx)
 Dispatches to the appropriate analytical solution function based on simulation settings.
 
PetscErrorCode SetAnalyticalSolutionForParticles (Vec tempVec, SimCtx *simCtx)
 Applies the analytical solution to particle velocity vector.
 

Macro Definition Documentation

◆ __FUNCT__

#define __FUNCT__   "AnalyticalSolutionEngine"

Definition at line 61 of file AnalyticalSolutions.h.

Function Documentation

◆ SetAnalyticalGridInfo()

PetscErrorCode SetAnalyticalGridInfo ( UserCtx user)

Sets the grid domain and resolution for analytical solution cases.

This function is called when eulerianSource is "analytical". It is responsible for automatically configuring the grid based on the chosen AnalyticalSolutionType.

TGV3D Multi-Block Decomposition
If the analytical solution is "TGV3D", this function automatically decomposes the required [0, 2*PI] physical domain among the available blocks.
  • **Single Block (nblk=1):** The single block is assigned the full [0, 2*PI] domain.
  • **Multiple Blocks (nblk>1):** It requires that the number of blocks be a perfect square (e.g., 4, 9, 16). It then arranges the blocks in a sqrt(nblk) by sqrt(nblk) grid in the X-Y plane, partitioning the [0, 2*PI] domain in X and Y accordingly. The Z domain for all blocks remains [0, 2*PI]. If nblk is not a perfect square, the simulation is aborted with an error.

Grid resolution (IM/JM/KM) is expected to be pre-populated in user before this function is called.

Parameters
userPointer to the UserCtx for a specific block. The function will populate the geometric fields (IM, JM, KM, Min_X, Max_X, etc.) within this struct.
Returns
PetscErrorCode 0 on success, or a PETSc error code on failure.

Definition at line 70 of file AnalyticalSolutions.c.

71{
72 SimCtx *simCtx = user->simCtx;
73 PetscInt nblk = simCtx->block_number;
74 PetscInt block_index = user->_this;
75
76 PetscFunctionBeginUser;
78
80 SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
81 "SetAnalyticalGridInfo called for analytical type '%s' that does not require custom geometry.",
83 }
84 if (user->IM <= 0 || user->JM <= 0 || user->KM <= 0) {
85 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
86 "Analytical grid resolution is not initialized. Ensure IM/JM/KM are preloaded before SetAnalyticalGridInfo.");
87 }
88
89 if (strcmp(simCtx->AnalyticalSolutionType, "TGV3D") == 0) {
90 LOG_ALLOW_SYNC(GLOBAL, LOG_DEBUG, "Rank %d: Configuring grid for TGV3D analytical solution, block %d.\n", simCtx->rank, block_index);
91
92 if (nblk == 1) {
93 // --- Single Block Case ---
94 if (block_index == 0) {
95 LOG_ALLOW(GLOBAL, LOG_INFO, "Single block detected. Setting domain to [0, 2*PI].\n");
96 }
97 user->Min_X = 0.0; user->Max_X = 2.0 * PETSC_PI;
98 user->Min_Y = 0.0; user->Max_Y = 2.0 * PETSC_PI;
99 user->Min_Z = 0.0; user->Max_Z = 0.2 * PETSC_PI; //2.0 * PETSC_PI;
100
101 } else { // --- Multi-Block Case ---
102 PetscReal s = sqrt((PetscReal)nblk);
103
104 // Validate that nblk is a perfect square.
105 if (fabs(s - floor(s)) > 1e-9) {
106 SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP,
107 "\n\n*** CONFIGURATION ERROR FOR TGV3D ***\n"
108 "For multi-block TGV3D cases, the number of blocks must be a perfect square (e.g., 4, 9, 16).\n"
109 "You have specified %d blocks. Please adjust `-block_number`.\n", nblk);
110 }
111 PetscInt blocks_per_dim = (PetscInt)s;
112
113 if (block_index == 0) {
114 LOG_ALLOW(GLOBAL, LOG_INFO, "%d blocks detected. Decomposing domain into a %d x %d grid in the X-Y plane.\n", nblk, blocks_per_dim, blocks_per_dim);
115 }
116
117 // Determine the (row, col) position of this block in the 2D decomposition
118 PetscInt row = block_index / blocks_per_dim;
119 PetscInt col = block_index % blocks_per_dim;
120
121 // Calculate the width/height of each sub-domain
122 PetscReal block_width = (2.0 * PETSC_PI) / (PetscReal)blocks_per_dim;
123 PetscReal block_height = (2.0 * PETSC_PI) / (PetscReal)blocks_per_dim;
124
125 // Assign this block its specific sub-domain
126 user->Min_X = col * block_width;
127 user->Max_X = (col + 1) * block_width;
128 user->Min_Y = row * block_height;
129 user->Max_Y = (row + 1) * block_height;
130 user->Min_Z = 0.0;
131 user->Max_Z = 2.0 * PETSC_PI; // Z-domain is not decomposed
132 }
133 }
134 /*
135 * --- EXTENSIBILITY HOOK ---
136 * To add another analytical case with special grid requirements:
137 *
138 * else if (strcmp(simCtx->AnalyticalSolutionType, "ChannelFlow") == 0) {
139 * // ... implement logic to set domain for ChannelFlow case ...
140 * }
141 */
142 else {
143 SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_UNKNOWN_TYPE,
144 "Analytical type '%s' has no custom geometry implementation.",
145 simCtx->AnalyticalSolutionType);
146 }
147
148 // We can also read stretching ratios, as they are independent of the domain size
149 // For simplicity, we assume uniform grid unless specified.
150 user->rx = 1.0; user->ry = 1.0; user->rz = 1.0;
151
152 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d: Block %d grid resolution set: IM=%d, JM=%d, KM=%d\n",
153 simCtx->rank, block_index, user->IM, user->JM, user->KM);
154 LOG_ALLOW(LOCAL, LOG_DEBUG, "Rank %d: Block %d final bounds: X=[%.4f, %.4f], Y=[%.4f, %.4f], Z=[%.4f, %.4f]\n",
155 simCtx->rank, block_index, user->Min_X, user->Max_X, user->Min_Y, user->Max_Y, user->Min_Z, user->Max_Z);
156
158 PetscFunctionReturn(0);
159}
PetscBool AnalyticalTypeRequiresCustomGeometry(const char *analytical_type)
Reports whether an analytical type requires custom geometry/decomposition logic.
#define LOG_ALLOW_SYNC(scope, level, fmt,...)
----— DEBUG ---------------------------------------— #define LOG_ALLOW(scope, level,...
Definition logging.h:267
#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:746
@ LOG_INFO
Informational messages about program execution.
Definition logging.h:31
@ 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:737
PetscMPIInt rank
Definition variables.h:592
PetscInt block_number
Definition variables.h:654
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:736
PetscReal Min_X
Definition variables.h:743
PetscInt KM
Definition variables.h:742
PetscInt _this
Definition variables.h:746
PetscReal ry
Definition variables.h:747
PetscReal Max_Y
Definition variables.h:743
PetscReal rz
Definition variables.h:747
PetscInt JM
Definition variables.h:742
PetscReal Min_Z
Definition variables.h:743
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
Definition variables.h:621
PetscReal Max_X
Definition variables.h:743
PetscReal Min_Y
Definition variables.h:743
PetscInt IM
Definition variables.h:742
PetscReal rx
Definition variables.h:747
PetscReal Max_Z
Definition variables.h:743
The master context for the entire simulation.
Definition variables.h:589
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AnalyticalTypeRequiresCustomGeometry()

PetscBool AnalyticalTypeRequiresCustomGeometry ( const char *  analytical_type)

Reports whether an analytical type requires custom geometry/decomposition logic.

Analytical types returning PETSC_TRUE are expected to route through SetAnalyticalGridInfo. Types returning PETSC_FALSE should use the standard programmatic grid parser fallback.

Parameters
analytical_typeAnalytical solution type string.
Returns
PETSC_TRUE if custom geometry is required, PETSC_FALSE otherwise.

Definition at line 38 of file AnalyticalSolutions.c.

39{
40 if (!analytical_type) return PETSC_FALSE;
41 return (strcmp(analytical_type, "TGV3D") == 0) ? PETSC_TRUE : PETSC_FALSE;
42}
Here is the caller graph for this function:

◆ AnalyticalSolutionEngine()

PetscErrorCode AnalyticalSolutionEngine ( SimCtx simCtx)

Dispatches to the appropriate analytical solution function based on simulation settings.

This function acts as a router. It reads the AnalyticalSolutionType from the simulation context and calls the corresponding private implementation function (e.g., for Taylor-Green Vortex, lid-driven cavity, etc.). This design keeps the main simulation code clean and makes it easy to add new analytical test cases.

Parameters
simCtxThe main simulation context, containing configuration and state.
Returns
PetscErrorCode 0 on success.

This function acts as a router. It reads the AnalyticalSolutionType string from the simulation context and calls the corresponding private implementation function (e.g., for Taylor-Green Vortex). This design keeps the main simulation code clean and makes it easy to add new analytical test cases.

Parameters
[in]simCtxThe main simulation context, containing all configuration and state.
Returns
PetscErrorCode 0 on success, or a PETSc error code on failure.

Definition at line 179 of file AnalyticalSolutions.c.

180{
181 PetscErrorCode ierr;
182 PetscFunctionBeginUser;
184
185 // -- Before any operation, here is defensive test to ensure that the Corner->Center Interpolation method works
186 //ierr = TestCornerToCenterInterpolation(&(simCtx->usermg.mgctx[simCtx->usermg.mglevels - 1]->user[0]));
187
188 // --- Dispatch based on the string provided by the user ---
189 if (strcmp(simCtx->AnalyticalSolutionType, "TGV3D") == 0) {
190 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Applying Analytical Solution: 3D Taylor-Green Vortex (TGV3D).\n");
191 ierr = SetAnalyticalSolution_TGV3D(simCtx); CHKERRQ(ierr);
192 }
193 else if (strcmp(simCtx->AnalyticalSolutionType, "ZERO_FLOW") == 0) {
194 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Applying Analytical Solution: Zero Background Flow (ZERO_FLOW).\n");
195 ierr = SetAnalyticalSolution_ZeroFlow(simCtx); CHKERRQ(ierr);
196 }
197 /*
198 * --- EXTENSIBILITY HOOK ---
199 * To add a new analytical solution (e.g., "ChannelFlow"):
200 * 1. Add an `else if` block here:
201 *
202 * else if (strcmp(simCtx->AnalyticalSolutionType, "ChannelFlow") == 0) {
203 * LOG_ALLOW(GLOBAL, LOG_DEBUG, "Applying Analytical Solution: Channel Flow.\n");
204 * ierr = SetAnalyticalSolution_ChannelFlow(simCtx); CHKERRQ(ierr);
205 * }
206 *
207 * 2. Implement the static function `SetAnalyticalSolution_ChannelFlow(SimCtx *simCtx)`
208 * below, following the TGV3D pattern.
209 */
210 else {
211 // If the type is unknown, raise a fatal error to prevent silent failures.
212 SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown AnalyticalSolutionType specified: '%s'", simCtx->AnalyticalSolutionType);
213 }
214
216 PetscFunctionReturn(0);
217}
static PetscErrorCode SetAnalyticalSolution_ZeroFlow(SimCtx *simCtx)
Sets all fluid fields to zero for a quiescent (zero-flow) background.
static PetscErrorCode SetAnalyticalSolution_TGV3D(SimCtx *simCtx)
Sets the non-dimensional velocity and pressure fields to the 3D Taylor-Green Vortex solution.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetAnalyticalSolutionForParticles()

PetscErrorCode SetAnalyticalSolutionForParticles ( Vec  tempVec,
SimCtx simCtx 
)

Applies the analytical solution to particle velocity vector.

Dispatcher function that calls the appropriate analytical solution based on simCtx->AnalyticalSolutionType. Supports multiple solution types.

Parameters
tempVecThe PETSc Vec containing particle positions which will be used to store velocities.
simCtxThe simulation context.
Returns
PetscErrorCode Returns 0 on success.

Definition at line 485 of file AnalyticalSolutions.c.

486{
487 PetscErrorCode ierr;
488 PetscInt nLocal;
489 PetscReal *vels;
490
491 PetscFunctionBeginUser;
492
493 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Type: %s\n",
494 simCtx->AnalyticalSolutionType ? simCtx->AnalyticalSolutionType : "default");
495
496 // Check for specific analytical solution types
497 if (simCtx->AnalyticalSolutionType && strcmp(simCtx->AnalyticalSolutionType, "TGV3D") == 0) {
498 LOG_ALLOW(GLOBAL, LOG_DEBUG, "Using TGV3D solution.\n");
499 ierr = SetAnalyticalSolutionForParticles_TGV3D(tempVec, simCtx); CHKERRQ(ierr);
500 return 0;
501 }
502
503 ierr = VecRestoreArray(tempVec, &vels); CHKERRQ(ierr);
504
505 PetscFunctionReturn(0);
506}
static PetscErrorCode SetAnalyticalSolutionForParticles_TGV3D(Vec tempVec, SimCtx *simCtx)
Sets the TGV3D analytical velocity solution for particles.
Here is the call graph for this function:
Here is the caller graph for this function: