PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
interpolation.h
Go to the documentation of this file.
1#ifndef INTERPOLATION_H
2#define INTERPOLATION_H
3
4#include <petscpf.h>
5#include <petscdmswarm.h>
6#include <stdlib.h>
7#include <time.h>
8#include <math.h>
9#include <petsctime.h>
10#include <petscdmcomposite.h>
11#include <petscerror.h>
12#include <petscsys.h>
13
14// Include additional headers
15#include "variables.h" // Shared type definitions
16#include "ParticleSwarm.h" // Particle swarm functions
17#include "walkingsearch.h" // Particle location functions
18#include "grid.h" // Grid functions
19#include "logging.h" // Logging macros
20#include "io.h" // Data Input and Output functions
21#include "setup.h" // Setup functions that are used across the codebase
22
23// Macros and constants
24#define NUM_WEIGHTS 8 // Number of weights in trilinear interpolation
25
26/**
27 * @brief Generic macro to call the appropriate interpolation function based on the field type.
28 *
29 * This macro will select either the scalar or vector interpolation function based on
30 * the type of the 'field' pointer. It also performs a compile-time check that 'centfield'
31 * is of the same type as 'field'. If the types are not the same, a compile-time error is produced.
32 *
33 * Usage:
34 * InterpolateFieldFromCornerToCenter(field, centfield, user);
35 */
36#define InterpolateFieldFromCornerToCenter(field, centfield, user) \
37 ( (void)sizeof(char[1 - 2*!!(!__builtin_types_compatible_p(typeof(field), typeof(centfield)))]),\
38 _Generic((field), \
39 PetscReal ***: InterpolateFieldFromCornerToCenter_Scalar, \
40 Cmpnts ***: InterpolateFieldFromCornerToCenter_Vector \
41 )(field, centfield, user) )
42
43/*
44#define InterpolateFieldFromCenterToCorner(centfield, field, info) \
45 _Generic((centfield), \
46 PetscReal ***: InterpolateFieldFromCenterToCorner_Scalar, \
47 Cmpnts ***: InterpolateFieldFromCenterToCorner_Vector \
48 )(centfield, field, info)
49*/
50
51/**
52 * @brief Macro to dispatch to the correct scalar or vector center-to-corner function
53 * based on a runtime block size variable.
54 *
55 * This macro uses a ternary operator to inspect the runtime value of 'blockSize' and
56 * select the appropriate implementation. It expects the input and output pointers to be void*
57 * and handles casting them to the correct, strongly-typed pointers.
58 *
59 * @param blockSize The runtime block size (1 for scalar, 3 for vector).
60 * @param centfield_ptr The input void* pointer to the 3D cell-centered data array.
61 * @param corner_ptr The output void* pointer to the 3D corner data array.
62 * @param user_ctx The UserCtx structure.
63 */
64#define InterpolateFieldFromCenterToCorner(blockSize, centfield_ptr, corner_ptr, user_ctx) \
65 ( (blockSize) == 1 ? \
66 InterpolateFieldFromCenterToCorner_Scalar_Petsc((PetscReal***)(centfield_ptr), (PetscReal***)(corner_ptr), (user_ctx)) : \
67 InterpolateFieldFromCenterToCorner_Vector_Petsc((Cmpnts***)(centfield_ptr), (Cmpnts***)(corner_ptr), (user_ctx)) \
68 )
69
70
71/**
72 * @brief A type-generic macro that interpolates a field from corner nodes to all face centers.
73 *
74 * This macro uses C11's _Generic feature to dispatch to the appropriate underlying
75 * function based on the type of the input `corner_arr`.
76 *
77 * - If `corner_arr` is of type `PetscReal***`, it calls `InterpolateCornerToFaceCenter_Scalar`.
78 * - If `corner_arr` is of type `Cmpnts***`, it calls `InterpolateCornerToFaceCenter_Vector`.
79 *
80 * @param corner_arr Ghosted node-centered array (global indexing). The type of this
81 * argument determines which function is called.
82 * @param faceX_arr Local array for X-faces.
83 * @param faceY_arr Local array for Y-faces.
84 * @param faceZ_arr Local array for Z-faces.
85 * @param user_ctx User context containing DMDA 'fda'.
86 */
87#define InterpolateCornerToFaceCenter(corner_arr, faceX_arr, faceY_arr, faceZ_arr, user_ctx) \
88 _Generic((corner_arr), \
89 PetscReal***: InterpolateCornerToFaceCenter_Scalar, \
90 Cmpnts***: InterpolateCornerToFaceCenter_Vector \
91 )(corner_arr, faceX_arr, faceY_arr, faceZ_arr, user_ctx)
92
93/**
94 * @brief Macro that calls either the scalar or vector piecewise interpolation function
95 * based on the type of the `fieldPtr` parameter (3D array).
96 *
97 * Usage example:
98 *
99 * // For scalar:
100 * PetscReal ***fieldScal;
101 * PetscReal outVal;
102 * PieceWiseLinearInterpolation(fieldName, fieldScal, i, j, k, &outVal);
103 *
104 * // For vector:
105 * Cmpnts ***fieldVec;
106 * Cmpnts vec;
107 * PieceWiseLinearInterpolation(fieldName, fieldVec, i, j, k, &vec);
108 */
109#define PieceWiseLinearInterpolation(fieldName, fieldPtr, i, j, k, outPtr) \
110 _Generic((fieldPtr), \
111 PetscReal ***: PieceWiseLinearInterpolation_Scalar, \
112 Cmpnts ***: PieceWiseLinearInterpolation_Vector \
113 )(fieldName, fieldPtr, i, j, k, outPtr)
114
115/**
116 * @brief Macro that calls either the scalar or vector trilinear interpolation function
117 * based on the type of the `fieldPtr` parameter (3D array).
118 *
119 * Usage example:
120 *
121 * PetscReal result;
122 * Cmpnts vec;
123 *
124 * // For scalars:
125 * TrilinearInterpolation(fieldName, fieldScal, i, j, k, a1, a2, a3, &result);
126 *
127 * // For vectors:
128 * TrilinearInterpolation(fieldName, fieldVec, i, j, k, a1, a2, a3, &vec);
129 */
130#define TrilinearInterpolation(fieldName, fieldPtr, i, j, k, a1, a2, a3, outPtr) \
131 _Generic((fieldPtr), \
132 PetscReal ***: TrilinearInterpolation_Scalar, \
133 Cmpnts ***: TrilinearInterpolation_Vector \
134 )(fieldName, fieldPtr, i, j, k, a1, a2, a3, outPtr)
135
136// Function declarations
137
138/**
139 * @brief Computes the trilinear interpolated scalar at a given point.
140 *
141 * @param[in] fieldName A string representing the name of the scalar field (e.g., "temperature").
142 * @param[in] fieldScal 3D array of the field from a DMDA (indexed as [k][j][i]),
143 * each cell a PetscReal.
144 * @param[in] i, j, k Integral cell indices (the "lower" corner in each dimension).
145 * @param[in] a1, a2, a3 Normalized coordinates within the cell ([0,1] range).
146 * @param[out] val Pointer to a PetscReal that will store the interpolated scalar.
147 *
148 * This function uses the standard 8-corner trilinear formula via `ComputeTrilinearWeights()`.
149 * If a different scheme is desired, implement a new function with the same interface.
150 */
151PetscErrorCode TrilinearInterpolation_Scalar(
152 const char *fieldName,
153 PetscReal ***fieldScal,
154 PetscInt i,
155 PetscInt j,
156 PetscInt k,
157 PetscReal a1,
158 PetscReal a2,
159 PetscReal a3,
160 PetscReal *val);
161
162/**
163 * @brief Computes the trilinear interpolated vector (e.g., velocity) at a given point.
164 *
165 * @param[in] fieldName A string representing the name of the vector field (e.g., "velocity").
166 * @param[in] fieldVec 3D array of the field from a DMDA (indexed as [k][j][i]),
167 * each cell of type Cmpnts.
168 * @param[in] i, j, k Integral cell indices (the "lower" corner in each dimension).
169 * @param[in] a1, a2, a3 Normalized coordinates within the cell ([0,1] range).
170 * @param[out] vec Pointer to a Cmpnts struct that will store the interpolated vector (x, y, z).
171 *
172 * This function uses the standard 8-corner trilinear formula via `ComputeTrilinearWeights()`.
173 * If a different scheme is desired, implement a new function with the same interface.
174 */
175PetscErrorCode TrilinearInterpolation_Vector(
176 const char *fieldName,
177 Cmpnts ***fieldVec,
178 PetscInt i,
179 PetscInt j,
180 PetscInt k,
181 PetscReal a1,
182 PetscReal a2,
183 PetscReal a3,
184 Cmpnts *vec);
185
186/**
187 * @brief Interpolates a cell-centered field (scalar or vector) onto DMSwarm particles,
188 * using a robust, PETSc-idiomatic two-stage process.
189 *
190 * This function first converts the cell-centered input data to corner-node data,
191 * storing this intermediate result in a PETSc Vec to correctly handle the communication
192 * of ghost-point information across parallel ranks. It then performs a final trilinear
193 * interpolation from the ghosted corner data to each particle's location.
194 *
195 * Workflow:
196 * 1. Create temporary PETSc Vecs (`cornerGlobal`, `cornerLocal`) to manage the
197 * intermediate corner-node data, using the existing nodal DMDA (`user->fda`).
198 * 2. Call a dispatch macro that uses the runtime block size (`bs`) to select the
199 * correct underlying center-to-corner function, writing results into `cornerGlobal`.
200 * 3. Perform a ghost-point exchange (`DMGlobalToLocal`) to transfer the boundary
201 * data from `cornerGlobal` into the ghost regions of `cornerLocal`.
202 * 4. Loop over all local particles. For each particle:
203 * a. Convert its global cell index to a local index relative to the ghosted array.
204 * b. Check if the particle's interpolation stencil is fully contained within
205 * the owned+ghost region. If not, log a warning and set the result to zero.
206 * c. Perform the final trilinear interpolation using the ghosted `cornerLocal` data.
207 * 5. Restore all PETSc objects to prevent memory leaks.
208 *
209 * @param[in] user User context with DMDA, DMSwarm, etc.
210 * @param[in] fieldGlobal_cellCentered Vec (from fda) with cell-centered data (e.g., Ucat).
211 * @param[in] fieldName Human-readable field name for logging (e.g., "Ucat").
212 * @param[in] swarmOutFieldName Name of the DMSwarm field where interpolation results go.
213 *
214 * @return PetscErrorCode 0 on success.
215 */
216PetscErrorCode InterpolateEulerFieldToSwarm(
217 UserCtx *user,
218 Vec fieldLocal_cellCentered,
219 const char *fieldName,
220 const char *swarmOutFieldName);
221
222
223/**
224 * @brief Interpolates all relevant fields from the DMDA to the DMSwarm.
225 *
226 * Currently, it interpolates:
227 * - user->Ucat (vector field) into the DMSwarm field "swarmVelocity".
228 *
229 * To add more fields, duplicate the call to InterpolateOneFieldOverSwarm and provide:
230 * - The global Vec for that field (e.g. user->Tcat for temperature),
231 * - A human-readable field name (for logging),
232 * - A DMSwarm output field name (e.g. "swarmTemperature").
233 *
234 * @param[in,out] user Pointer to a UserCtx containing:
235 * - user->da (DM for the grid),
236 * - user->swarm (DMSwarm for particles),
237 * - user->Ucat (Vec for the vector field),
238 * - possibly more fields like user->Tcat, user->Pcat, etc.
239 *
240 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
241 */
242PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user);
243
244/**
245 * @brief Interpolates particle velocities using trilinear interpolation.
246 *
247 * @param[in] user Pointer to the user-defined context containing grid and swarm information.
248 * @return PetscErrorCode Returns 0 on success, non-zero on failure.
249 */
250
252
253/**
254 * @brief Safely interpolate a scalar field from corner nodes (from the coordinate DM)
255 * to cell centers (from the cell-centered DM) using the provided UserCtx.
256 *
257 * For each cell center in the physical region of the cell-centered DM (fda), this function
258 * averages the up to 8 surrounding scalar values from the coordinate DM (da). On boundaries,
259 * where fewer corners are available, a partial average is computed.
260 *
261 * The coordinate DM (da) is built on corners (IM+1 x JM+1 x KM+1) while the cell-centered DM (fda)
262 * covers the physical cells (IM x JM x KM). Index offsets are adjusted via DMDAGetLocalInfo.
263 *
264 * @param[in] field 3D array of corner-based scalar data (from user->da).
265 * @param[out] centfield 3D array for the interpolated cell-center scalar data (for user->fda).
266 * @param[in] user User context containing:
267 * - da : DM for the coordinate (corner) data.
268 * - fda : DM for the cell-centered data.
269 *
270 * @return PetscErrorCode 0 on success.
271 */
273 PetscReal ***field,
274 PetscReal ***centfield,
275 UserCtx *user);
276
277/**
278 * @brief Safely interpolate a vector field from corner nodes (from the coordinate DM)
279 * to cell centers (from the cell-centered DM) using the provided UserCtx.
280 *
281 * For each cell center in the physical region of the cell-centered DM (fda), this function
282 * averages the 8 surrounding corner values from the coordinate DM (da). The coordinate DM
283 * (da) is built on corners (IM+1 x JM+1 x KM+1) while the cell-centered DM (fda) covers
284 * the physical cells (IM x JM x KM). Index offsets are adjusted using DMDAGetLocalInfo.
285 *
286 * @param[in] field 3D array of corner-based vector data (from user->da).
287 * @param[out] centfield 3D array for the interpolated cell-center vector data (for user->fda).
288 * @param[in] user User context containing:
289 * - da : DM for the coordinate (corner) data.
290 * - fda : DM for the cell-centered data.
291 *
292 * @return PetscErrorCode 0 on success.
293 */
295 Cmpnts ***field,
296 Cmpnts ***centfield,
297 UserCtx *user);
298
299/**
300 * @brief Interpolates a scalar field from cell centers to corner nodes.
301 *
302 * This function estimates the value of a scalar field at each grid node by averaging
303 * the values from the cell centers of the cells surrounding that node (up to 8).
304 * It handles physical boundaries by averaging only the available adjacent cells.
305 *
306 * Assumes input `centfield_arr` is from a ghosted local vector associated with `user->da` (DOF=1, s=2)
307 * and output `field_arr` is from a ghosted local vector also associated with `user->da` (DOF=1, s=2).
308 * Input array uses GLOBAL cell indices, output array uses GLOBAL node indices.
309 *
310 * @param[in] centfield_arr Input: 3D array (ghosted) of scalar data at cell centers,
311 * accessed via GLOBAL cell indices (k=0..KM-1, j=0..JM-1, i=0..IM-1).
312 * @param[out] field_arr Output: 3D array (ghosted) where interpolated node values are stored,
313 * accessed via GLOBAL node indices (k=0..KM, j=0..JM, i=0..IM).
314 * @param[in] user User context containing DMDA information (da).
315 *
316 * @return PetscErrorCode 0 on success.
317 */
318PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar(PetscReal ***field_arr,
319 PetscReal ***centfield_arr,
320 UserCtx *user);
321
322/**
323 * @brief Interpolates a vector field from cell centers to corner nodes.
324 *
325 * This function estimates the value of a vector field at each grid node by averaging
326 * the vector values from the cell centers of the cells surrounding that node (up to 8).
327 * It handles physical boundaries by averaging only the available adjacent cells.
328 *
329 * Assumes input `centfield_arr` is from a ghosted local vector (e.g., representing ucat,
330 * stored using node-indexing convention) and output `field_arr` is a ghosted local
331 * vector associated with `user->fda` (DOF=3, s=2), accessed using global node indices.
332 *
333 * @param[in] centfield_arr Input: 3D array (ghosted) of vector data conceptually at cell centers,
334 * accessed via GLOBAL indices respecting the storage convention
335 * (e.g., `ucat[k][j][i]` uses node index `i` but represents cell `C(i,j,k)` for interior).
336 * @param[out] field_arr Output: 3D array (ghosted) where interpolated node values are stored,
337 * accessed via GLOBAL node indices (k=0..KM, j=0..JM, i=0..IM).
338 * @param[in] user User context containing DMDA information (da and fda).
339 *
340 * @return PetscErrorCode 0 on success.
341 */
343 Cmpnts ***centfield_arr,
344 UserCtx *user);
345
346/**
347 * @brief Interpolates a vector field from cell centers to corner nodes.
348 *
349 * This version is adapted to write directly into a ghosted local array obtained from DMDAVecGetArray(),
350 * which allows using GLOBAL indices for writing to the OWNED portion of the array.
351 *
352 * @param[in] centfield_arr Input: 3D array (ghosted) of cell-centered data, accessed via GLOBAL indices.
353 * @param[out] corner_arr Output: 3D array (ghosted) where interpolated node values are stored,
354 * also accessed via GLOBAL indices for the owned part.
355 * @param[in] user User context containing DMDA information.
356 *
357 * @return PetscErrorCode 0 on success.
358 */
360 Cmpnts ***centfield_arr, /* Input: Ghosted local array from Vec (read) */
361 Cmpnts ***corner_arr, /* Output: Ghosted local array from Vec (write) */
362 UserCtx *user);
363
364/**
365 * @brief Interpolates a scalar field from cell centers to corner nodes.
366 *
367 * This version is adapted to write directly into a ghosted local array obtained from DMDAVecGetArray(),
368 * which allows using GLOBAL indices for writing to the OWNED portion of the array.
369 *
370 * @param[in] centfield_arr Input: 3D array (ghosted) of scalar data at cell centers, accessed via GLOBAL indices.
371 * @param[out] corner_arr Output: 3D array (ghosted) where interpolated node values are stored,
372 * also accessed via GLOBAL indices for the owned part.
373 * @param[in] user User context containing DMDA information.
374 *
375 * @return PetscErrorCode 0 on success.
376 */
378 PetscReal ***centfield_arr, /* Input: Ghosted local array from Vec (read) */
379 PetscReal ***corner_arr, /* Output: Ghosted local array from Vec (write) */
380 UserCtx *user);
381
382/**
383 * @brief Determines the target Eulerian DM and expected DOF for scattering a given particle field.
384 * @ingroup scatter_module
385 *
386 * Based on hardcoded rules mapping particle field names to user context DMs (da/fda).
387 * This function encapsulates the policy of where different fields should be scattered.
388 *
389 * @param[in] user Pointer to the UserCtx containing da and fda.
390 * @param[in] particleFieldName Name of the particle field (e.g., "P", "Ucat").
391 * @param[out] targetDM Pointer to store the determined target DM (da or fda).
392 * @param[out] expected_dof Pointer to store the expected DOF (1 or 3) for this field.
393 *
394 * @return PetscErrorCode Returns 0 on success, PETSC_ERR_ARG_UNKNOWN if field name is not recognized,
395 * or PETSC_ERR_ARG_NULL for NULL inputs.
396 */
397PetscErrorCode GetScatterTargetInfo(UserCtx *user, const char *particleFieldName,
398 DM *targetDM, PetscInt *expected_dof);
399
400
401/**
402 * @brief Accumulates a particle field (scalar or vector) into a target grid sum vector.
403 * @ingroup scatter_module_internal
404 *
405 * This function iterates through local particles, identifies their cell using the
406 * "DMSwarm_CellID" field, and adds the particle's field value (`particleFieldName`)
407 * to the corresponding cell location in the `gridSumVec`. It handles both scalar
408 * (DOF=1) and vector (DOF=3) fields automatically based on the DOF of `gridSumDM`.
409 *
410 * IMPORTANT: The caller must ensure `gridSumVec` is zeroed before calling this
411 * function if a fresh sum calculation is desired.
412 *
413 * @param[in] swarm The DMSwarm containing particles.
414 * @param[in] particleFieldName Name of the field on the particles (must match DOF).
415 * @param[in] gridSumDM The DMDA associated with `gridSumVec`. Its DOF determines
416 * how many components are accumulated.
417 * @param[in,out] gridSumVec The Vec (associated with `gridSumDM`) to accumulate sums into.
418 *
419 * @return PetscErrorCode 0 on success. Errors if fields don't exist or DMs are incompatible.
420 */
421PetscErrorCode AccumulateParticleField(DM swarm, const char *particleFieldName,
422 DM gridSumDM, Vec gridSumVec);
423
424/**
425 * @brief Normalizes a grid vector of sums by a grid vector of counts to produce an average.
426 * @ingroup scatter_module_internal
427 *
428 * Calculates avgVec[i] = sumVec[i] / countVec[i] for each component of each
429 * OWNED cell where countVec[i] > 0. Sets avgVec[i] = 0 otherwise.
430 * Handles both scalar (DOF=1) and vector (DOF=3) data fields based on `dataDM`.
431 * Uses basic `VecGetArray`/`VecGetArrayRead` and manual index calculation.
432 *
433 * @param[in] countDM The DMDA associated with `countVec` (must have DOF=1).
434 * @param[in] countVec The Vec containing particle counts per cell (read-only).
435 * @param[in] dataDM The DMDA associated with `sumVec` and `avgVec` (must have DOF=1 or DOF=3).
436 * @param[in] sumVec The Vec containing the accumulated sums per cell (read-only).
437 * @param[in,out] avgVec The Vec where the calculated averages will be stored (overwritten).
438 *
439 * @return PetscErrorCode 0 on success.
440 */
441PetscErrorCode NormalizeGridVectorByCount(DM countDM, Vec countVec,
442 DM dataDM, Vec sumVec, Vec avgVec);
443
444/**
445 * @brief Scatters a particle field (scalar or vector) to the corresponding Eulerian field average.
446 * @ingroup scatter_module
447 *
448 * This is the main user-facing function. It determines the target Eulerian DM
449 * based on the `particleFieldName`, validates the provided `eulerFieldAverageVec`
450 * against the target DM, and then orchestrates the scatter operation by calling
451 * the internal helper function `ScatterParticleFieldToEulerField_Internal`.
452 * The final averaged result is stored IN-PLACE in `eulerFieldAverageVec`.
453 *
454 * @param[in] user Pointer to UserCtx containing da, fda, swarm, ParticleCount.
455 * @param[in] particleFieldName Name of the field in the DMSwarm (e.g., "P", "Ucat").
456 * @param[in,out] eulerFieldAverageVec Pre-created Vec associated with the correct target DM
457 * (implicitly da or fda). Result stored here.
458 *
459 * @return PetscErrorCode 0 on success. Errors on NULL input, unrecognized field name,
460 * or incompatible target vector.
461 */
462PetscErrorCode ScatterParticleFieldToEulerField(UserCtx *user,
463 const char *particleFieldName,
464 Vec eulerFieldAverageVec);
465
466/**
467 * @brief Scatters a predefined set of particle fields to their corresponding Eulerian fields.
468 * @ingroup scatter_module
469 *
470 * This convenience function calls the unified `ScatterParticleFieldToEulerField`
471 * for a standard set of fields ("P", potentially others). It assumes the target
472 * Eulerian Vec objects (e.g., `user->P`, `user->Ucat`) exist in the UserCtx structure
473 * and are correctly associated with their respective DMs (`user->da` or `user->fda`).
474 * It zeros the target Vecs before scattering.
475 *
476 * @param[in,out] user Pointer to the UserCtx structure containing all required DMs,
477 * Vecs (`ParticleCount`, target Eulerian fields like `P`, `Ucat`), and `swarm`.
478 *
479 * @return PetscErrorCode 0 on success. Errors if prerequisites (like ParticleCount)
480 * are missing or if underlying scatter calls fail.
481 */
483
484/**
485 * @brief Interpolates a scalar field from corner nodes to all face centers.
486 *
487 * This routine computes the average of the four corner-node values
488 * defining each face of a hexahedral cell:
489 * - X-faces (perpendicular to X): face between (i-1,i) in X-dir
490 * - Y-faces (perpendicular to Y): face between (j-1,j) in Y-dir
491 * - Z-faces (perpendicular to Z): face between (k-1,k) in Z-dir
492 *
493 * @param[in] corner_arr Ghosted node-centered array (global indexing) from user->fda.
494 * @param[out] faceX_arr Local array for X-faces sized [zm][ym][xm+1].
495 * @param[out] faceY_arr Local array for Y-faces sized [zm][ym+1][xm].
496 * @param[out] faceZ_arr Local array for Z-faces sized [zm+1][ym][xm].
497 * @param[in] user User context containing DMDA 'fda' and GetOwnedCellRange.
498 *
499 * @return PetscErrorCode 0 on success, non-zero on failure.
500 */
502 PetscReal ***corner_arr,
503 PetscReal ***faceX_arr,
504 PetscReal ***faceY_arr,
505 PetscReal ***faceZ_arr,
506 UserCtx *user);
507
508/**
509 * @brief Interpolates a vector field from corner nodes to all face centers.
510 *
511 * Identical to the scalar version, except it averages each component of the
512 * Cmpnts struct at the four corner-nodes per face.
513 *
514 * @param[in] corner_arr Ghosted 3-component array (global node indices).
515 * @param[out] faceX_arr Local array of Cmpnts for X-faces sized [zm][ym][xm+1].
516 * @param[out] faceY_arr Local array of Cmpnts for Y-faces sized [zm][ym+1][xm].
517 * @param[out] faceZ_arr Local array of Cmpnts for Z-faces sized [zm+1][ym][xm].
518 * @param[in] user User context containing DMDA 'fda'.
519 *
520 * @return PetscErrorCode 0 on success.
521 */
523 Cmpnts ***corner_arr,
524 Cmpnts ***faceX_arr,
525 Cmpnts ***faceY_arr,
526 Cmpnts ***faceZ_arr,
527 UserCtx *user);
528
529#endif // INTERPOLATION_H
530
Header file for Particle Swarm management functions.
Public interface for grid, solver, and metric setup routines.
PetscErrorCode NormalizeGridVectorByCount(DM countDM, Vec countVec, DM dataDM, Vec sumVec, Vec avgVec)
Normalizes a grid vector of sums by a grid vector of counts to produce an average.
PetscErrorCode AccumulateParticleField(DM swarm, const char *particleFieldName, DM gridSumDM, Vec gridSumVec)
Accumulates a particle field (scalar or vector) into a target grid sum vector.
PetscErrorCode GetScatterTargetInfo(UserCtx *user, const char *particleFieldName, DM *targetDM, PetscInt *expected_dof)
Determines the target Eulerian DM and expected DOF for scattering a given particle field.
PetscErrorCode ScatterAllParticleFieldsToEulerFields(UserCtx *user)
Scatters a predefined set of particle fields to their corresponding Eulerian fields.
PetscErrorCode ScatterParticleFieldToEulerField(UserCtx *user, const char *particleFieldName, Vec eulerFieldAverageVec)
Scatters a particle field (scalar or vector) to the corresponding Eulerian field average.
PetscErrorCode InterpolateFieldFromCenterToCorner_Vector(Cmpnts ***field_arr, Cmpnts ***centfield_arr, UserCtx *user)
Interpolates a vector field from cell centers to corner nodes.
PetscErrorCode InterpolateCornerToFaceCenter_Vector(Cmpnts ***corner_arr, Cmpnts ***faceX_arr, Cmpnts ***faceY_arr, Cmpnts ***faceZ_arr, UserCtx *user)
Interpolates a vector field from corner nodes to all face centers.
PetscErrorCode InterpolateAllFieldsToSwarm(UserCtx *user)
Interpolates all relevant fields from the DMDA to the DMSwarm.
PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar(PetscReal ***field_arr, PetscReal ***centfield_arr, UserCtx *user)
Interpolates a scalar field from cell centers to corner nodes.
PetscErrorCode TrilinearInterpolation_Vector(const char *fieldName, Cmpnts ***fieldVec, PetscInt i, PetscInt j, PetscInt k, PetscReal a1, PetscReal a2, PetscReal a3, Cmpnts *vec)
Computes the trilinear interpolated vector (e.g., velocity) at a given point.
PetscErrorCode InterpolateFieldFromCenterToCorner_Vector_Petsc(Cmpnts ***centfield_arr, Cmpnts ***corner_arr, UserCtx *user)
Interpolates a vector field from cell centers to corner nodes.
PetscErrorCode InterpolateParticleVelocities(UserCtx *user)
Interpolates particle velocities using trilinear interpolation.
PetscErrorCode TrilinearInterpolation_Scalar(const char *fieldName, PetscReal ***fieldScal, PetscInt i, PetscInt j, PetscInt k, PetscReal a1, PetscReal a2, PetscReal a3, PetscReal *val)
Computes the trilinear interpolated scalar at a given point.
PetscErrorCode InterpolateFieldFromCornerToCenter_Vector(Cmpnts ***field, Cmpnts ***centfield, UserCtx *user)
Safely interpolate a vector field from corner nodes (from the coordinate DM) to cell centers (from th...
PetscErrorCode InterpolateFieldFromCornerToCenter_Scalar(PetscReal ***field, PetscReal ***centfield, UserCtx *user)
Safely interpolate a scalar field from corner nodes (from the coordinate DM) to cell centers (from th...
PetscErrorCode InterpolateCornerToFaceCenter_Scalar(PetscReal ***corner_arr, PetscReal ***faceX_arr, PetscReal ***faceY_arr, PetscReal ***faceZ_arr, UserCtx *user)
Interpolates a scalar field from corner nodes to all face centers.
PetscErrorCode InterpolateEulerFieldToSwarm(UserCtx *user, Vec fieldLocal_cellCentered, const char *fieldName, const char *swarmOutFieldName)
Interpolates a cell-centered field (scalar or vector) onto DMSwarm particles, using a robust,...
PetscErrorCode InterpolateFieldFromCenterToCorner_Scalar_Petsc(PetscReal ***centfield_arr, PetscReal ***corner_arr, UserCtx *user)
Interpolates a scalar field from cell centers to corner nodes.
Public interface for data input/output routines.
Logging utilities and macros for PETSc-based applications.
Main header file for a complex fluid dynamics solver.
A 3D point or vector with PetscScalar components.
Definition variables.h:100
User-defined context containing data specific to a single computational grid level.
Definition variables.h:661
Header file for particle location functions using the walking search algorithm.