NeoN
A framework for CFD software
Loading...
Searching...
No Matches
cellLimitedGrad.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <memory>
8#include <string>
9
10#include "NeoN/core/error.hpp"
12#include "NeoN/core/input.hpp"
19
21{
22
23/* @class CellLimitedGrad
24 * @brief Slope-limited cell gradient.
25 *
26 * Wraps a runtime-selected base gradient scheme and clips its reconstructed
27 * gradient so that values extrapolated from the cell centre to the surrounding
28 * faces stay bounded by the minimum and maximum of the cell's own value and its
29 * face-neighbour cell values. Uses the minmod limiter, limiter(r) = min(r, 1),
30 * applied identically to every gradient component.
31 *
32 * Scheme specification (gradSchemes / TokenList):
33 * cellLimited <baseScheme ...> <k>
34 * e.g. cellLimited Gauss linear 1
35 * where 0 <= k <= 1 sets the limiting strength: k = 0 disables limiting (returns
36 * the unlimited base gradient), k = 1 is the strongest, most stable limiting,
37 * and intermediate values widen the admissible bounds accordingly.
38 *
39 * Scheme specification (Dictionary): the base scheme cannot be looked up under
40 * the same "GradOperator" key used to select "cellLimited" (that would recurse),
41 * so it is nested under a separate "baseGradOperator" sub-dictionary:
42 * { GradOperator: cellLimited, baseGradOperator: { GradOperator: Gauss }, cellLimitedCoeff: 1 }
43 * "cellLimitedCoeff" defaults to DEFAULT_COEFF (1) when omitted.
44 *
45 * Both the scalar gradient (grad of a scalar field -> Vec3) and the tensor
46 * gradient (grad of a vector field -> Tensor, e.g. grad(U)) are limited. For the
47 * tensor case the limiter is per-component (three independent minmod limiters,
48 * one per field component), matching the standard cell-limited vector gradient.
49 *
50 * GPU-first: the tensor limiter uses a cell-based gather over each cell's
51 * internal-face stencil (atomic-free, coalesced writes) for the bulk of the work;
52 * only the small physical/processor boundary-face set uses an atomic scatter.
53 *
54 * v1 assembles the explicit gradient on cell-centred fields; the implicit
55 * (LinearSystem) path is not provided. CPU-serial is validated in v1.
56 */
57class CellLimitedGrad : public GradOperatorFactory<Vec3>::template Register<CellLimitedGrad>
58{
60
61 // Limiter strength used when no coefficient is supplied (strongest limiting).
62 static constexpr scalar DEFAULT_COEFF = scalar(1);
63
64public:
65
66 static std::string name() { return "cellLimited"; }
67
68 static std::string doc() { return "Cell limited gradient (minmod slope limiter)"; }
69
70 static std::string schema() { return "none"; }
71
72 CellLimitedGrad(const Executor& exec, const UnstructuredMesh& mesh, const Input& inputs);
73
74 /* @brief implicit gradient assembly — not supported for the cell-limited scheme */
75 virtual void
77 {
78 NF_ERROR_EXIT("Not implemented");
79 };
80
81 /* @brief explicit limited gradient assembled into the supplied vector */
82 virtual void grad(
83 const VolumeField<scalar>& phi, const dsl::Coeff operatorScaling, Vector<Vec3>& gradPhi
84 ) const override;
85
86 /* @brief explicit limited gradient returned as a new VolumeField */
88 const VolumeField<scalar>& phi, const dsl::Coeff operatorScaling = dsl::Coeff {}
89 ) const override;
90
91 /* @brief slope-limited tensor gradient of a vector field (e.g. grad(U)) */
93 const VolumeField<Vec3>& u, VolumeField<Tensor>& gradU, const dsl::Coeff operatorScaling
94 ) const override;
95
96 virtual std::unique_ptr<GradOperatorFactory<Vec3>> clone() const override
97 {
98 NF_ERROR_EXIT("Not implemented");
99 return nullptr;
100 };
101
102private:
103
104 /* @brief read the limiter coefficient k from the scheme Input */
105 static scalar readCoeff(const Input& inputs);
106
107 /* @brief construct the wrapped base gradient scheme from the scheme Input
108 *
109 * For TokenList input the base scheme reads its own tokens directly off the
110 * shared cursor. For Dictionary input the same key ("GradOperator") that
111 * selected "cellLimited" cannot be reused, so the base scheme is looked up
112 * under a separate "baseGradOperator" sub-dictionary instead.
113 */
114 static std::unique_ptr<GradOperatorFactory<Vec3>>
115 readBaseGradScheme(const Executor& exec, const UnstructuredMesh& mesh, const Input& inputs);
116
117 // Declared before coeff_ so the base scheme consumes its tokens from the
118 // shared Input cursor before readCoeff reads the trailing coefficient.
119 std::unique_ptr<GradOperatorFactory<Vec3>> baseGradScheme_;
120 scalar coeff_;
121 // Supplies the cached internal-face cell-to-face displacement vectors; the raw
122 // mesh centres are freed once the geometry scheme is built.
123 std::shared_ptr<GeometryScheme> geometryScheme_;
124 // Per-cell internal-face stencil for the atomic-free cell-based tensor gather.
125 SegmentedVector<localIdx, localIdx> cellInternalFaces_;
126};
127
128} // namespace NeoN::finiteVolume::cellCentred
Data structure that stores a segmented fields or a vector of vectors.
Represents an unstructured mesh in NeoN.
A class to contain the data and executors for a field and define some basic operations.
Definition vector.hpp:27
A class that represents a coefficient for the NeoN dsl.
Definition coeff.hpp:24
virtual void grad(const VolumeField< scalar > &, const dsl::Coeff, la::LinearSystem< Vec3 > &) const override
void gradTensor(const VolumeField< Vec3 > &u, VolumeField< Tensor > &gradU, const dsl::Coeff operatorScaling) const override
VolumeField< Vec3 > grad(const VolumeField< scalar > &phi, const dsl::Coeff operatorScaling=dsl::Coeff {}) const override
virtual void grad(const VolumeField< scalar > &phi, const dsl::Coeff operatorScaling, Vector< Vec3 > &gradPhi) const override
virtual std::unique_ptr< GradOperatorFactory< Vec3 > > clone() const override
CellLimitedGrad(const Executor &exec, const UnstructuredMesh &mesh, const Input &inputs)
Represents a volume field in a finite volume method.
A class representing a linear system of equations.
A template class for registering derived classes with a base class.
#define NF_ERROR_EXIT(message)
Macro for printing an error message and aborting the program.
Definition error.hpp:90
std::variant< Dictionary, TokenList > Input
Definition input.hpp:15
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20
float scalar
Definition scalar.hpp:17