PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
BodyForces.h
Go to the documentation of this file.
1#ifndef BODYFORCES_H
2#define BODYFORCES_H
3
4#include "variables.h" // Provides definitions for UserCtx, SimCtx, IBMNodes, etc.
5#include "logging.h"
6#include "Metric.h"
7
8/**
9 * @file BodyForces.h
10 * @brief Momentum source terms added to the contravariant RHS.
11 *
12 * @section bf_contract Contract for a body force
13 *
14 * Every body force here is invoked from `ComputeBodyForces()` (`src/rhs.c`),
15 * which is the single extension point. A new force should:
16 *
17 * 1. take `(UserCtx *user, Vec Rct)`,
18 * 2. detect for itself whether it is active and return early if not,
19 * 3. **accumulate** into `Rct` with `+=`, never assign.
20 *
21 * @section bf_state RULE: DO NOT ADVANCE PER-TIMESTEP STATE HERE
22 *
23 * `ComputeBodyForces()` is called from `ComputeRHS()`, which runs **once per
24 * residual evaluation** - that is, once per Jameson RK stage under the Picard
25 * solver and once per Newton residual evaluation (including every finite
26 * difference probe) under Newton-Krylov. It is emphatically NOT called once per
27 * physical timestep.
28 *
29 * Any force that carries state across calls - a filter, a ramp, a moving
30 * average, an integral controller term - must therefore gate its update on
31 * `simCtx->step` and reuse the resolved value for the rest of that step:
32 *
33 * @code
34 * if (simCtx->myForceStep != simCtx->step) {
35 * ... advance the state ...
36 * simCtx->myForceStep = simCtx->step;
37 * }
38 * @endcode
39 *
40 * Advancing it unconditionally makes the applied force depend on how many
41 * residual evaluations preceded it. That is history dependence, and it breaks
42 * two things at once: `MomentumNewtonKrylov_FormResidual()` requires `F(X)` to
43 * be a deterministic function of the trial vector alone, and the Picard
44 * shadow-Jacobian estimate assumes body forces are a constant forcing with zero
45 * velocity Jacobian.
46 *
47 * This is not hypothetical. The driven-flow smoothing EMA in
48 * `ComputeDrivenChannelFlowSource()` had exactly this defect: the applied force
49 * walked 0.5, 0.75, 0.875 ... of the way toward its target across evaluations
50 * within a single timestep. `tests/smoke/run_driven_periodic_regression.sh`
51 * asserts the force is piecewise constant per step; extend it when adding a
52 * stateful force.
53 */
54
55/**
56 * @brief Applies a momentum source term to drive flow in a periodic channel or pipe.
57 *
58 * This function is the "engine" of the driven flow control system. It operates by:
59 * 1. Introspecting the boundary condition handlers to see if a `DRIVEN_` flow
60 * handler is active on any face. This determines if a driven flow is enabled
61 * and in which direction ('X', 'Y', or 'Z').
62 * 2. If a driven flow is active, it reads the `bulkVelocityCorrection` value that
63 * was computed by the handler's `PreStep` method and stored in the `SimCtx`.
64 * 3. It translates this velocity correction into a momentum source term.
65 * 4. It adds this source term to the appropriate component of the contravariant
66 * RHS vector (`Rct`) for all fluid cells in the domain.
67 *
68 * If no driven flow handler is found, this function does nothing.
69 *
70 * @param user The UserCtx containing the simulation state for a single block.
71 * @param Rct The PETSc Vec for the contravariant RHS, which will be modified in-place.
72 * @return PetscErrorCode 0 on success.
73 */
74PetscErrorCode ComputeDrivenChannelFlowSource(UserCtx *user, Vec Rct);
75
76#endif // BODYFORCES_H
PetscErrorCode ComputeDrivenChannelFlowSource(UserCtx *user, Vec Rct)
Applies a momentum source term to drive flow in a periodic channel or pipe.
Definition BodyForces.c:14
Logging utilities and macros for PETSc-based applications.
Main header file for a complex fluid dynamics solver.
User-defined context containing data specific to a single computational grid level.
Definition variables.h:906