NeoN
A framework for CFD software
Loading...
Searching...
No Matches
laplacianOperator.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
8#include "NeoN/core/input.hpp"
11#include "NeoN/dsl/operator.hpp"
16
18{
19
20/* @class Factory class to create laplacian operators by a given name using
21 * using NeoNs runTimeFactory mechanism
22 */
23template<typename FieldValueType, typename AssemblyType = FieldValueType>
26 LaplacianOperatorFactory<FieldValueType, AssemblyType>,
27 Parameters<const Executor&, const UnstructuredMesh&, const Input&>>
28{
29
30public:
31
32 static std::unique_ptr<LaplacianOperatorFactory<FieldValueType, AssemblyType>>
33 create(const Executor& exec, const UnstructuredMesh& mesh, const Input& inputs)
34 {
35 std::string key = (std::holds_alternative<Dictionary>(inputs))
36 ? std::get<Dictionary>(inputs).get<std::string>("LaplacianOperator")
37 : std::get<TokenList>(inputs).next<std::string>();
40 exec, mesh, inputs
41 );
42 }
43
44 static std::string name() { return "LaplacianOperatorFactory"; }
45
47 : exec_(exec), mesh_(mesh) {};
48
49 virtual ~LaplacianOperatorFactory() {} // Virtual destructor
50
51 virtual void laplacian(
53 const SurfaceField<scalar>& gamma,
55 const dsl::Coeff operatorScaling
56 ) = 0;
57
59 const SurfaceField<scalar>& gamma,
61 const dsl::Coeff operatorScaling
62 ) const = 0;
63
64 virtual void laplacian(
66 const SurfaceField<scalar>& gamma,
68 const dsl::Coeff operatorScaling
69 ) = 0;
70
71 virtual void laplacian(
73 const SurfaceField<scalar>& gamma,
75 const dsl::Coeff operatorScaling
76 ) = 0;
77
78 // Pure virtual function for cloning
79 virtual std::unique_ptr<LaplacianOperatorFactory<FieldValueType, AssemblyType>>
80 clone() const = 0;
81
82protected:
83
85
87};
88
89template<typename FieldValueType>
90class LaplacianOperator : public dsl::OperatorMixin<VolumeField<FieldValueType>>
91{
92
93public:
94
95 using VectorValueType = FieldValueType;
96
97 // copy constructor
99 : dsl::OperatorMixin<VolumeField<FieldValueType>>(
100 lapOp.exec_, lapOp.coeffs_, lapOp.field_, lapOp.type_
101 ),
102 gamma_(lapOp.gamma_),
103 sameTypeStrategy_(lapOp.sameTypeStrategy_ ? lapOp.sameTypeStrategy_->clone() : nullptr),
104 scalarMtxStrategy_(
105 lapOp.scalarMtxStrategy_ ? lapOp.scalarMtxStrategy_->clone() : nullptr
106 ) {};
107
109 dsl::Operator::Type termType,
110 const SurfaceField<scalar>& gamma,
112 Input input
113 )
114 : dsl::OperatorMixin<VolumeField<FieldValueType>>(
115 phi.exec(), dsl::Coeff(1.0), phi, termType
116 ),
117 gamma_(gamma),
118 sameTypeStrategy_(LaplacianOperatorFactory<FieldValueType, FieldValueType>::create(
119 this->exec_, phi.mesh(), input
120 )),
121 scalarMtxStrategy_(nullptr)
122 {
123 if constexpr (!std::is_same_v<FieldValueType, scalar>)
124 {
125 // The first create() consumed tokens; rewind the cursor so the second
126 // strategy can read the same scheme tokens from the start.
127 if (std::holds_alternative<NeoN::TokenList>(input))
128 {
129 std::get<NeoN::TokenList>(input).reset();
130 }
132 this->exec_, phi.mesh(), input
133 );
134 }
135 };
136
138 dsl::Operator::Type termType,
139 const SurfaceField<scalar>& gamma,
141 )
142 : dsl::OperatorMixin<VolumeField<FieldValueType>>(
143 phi.exec(), dsl::Coeff(1.0), phi, termType
144 ),
145 gamma_(gamma), sameTypeStrategy_(nullptr), scalarMtxStrategy_(nullptr) {};
146
147
149 {
150 NF_ASSERT(sameTypeStrategy_, "LaplacianOperatorStrategy not initialized");
151 const auto operatorScaling = this->getCoefficient();
153 source.exec(), source.size(), zero<FieldValueType>()
154 );
155 sameTypeStrategy_->laplacian(tmpsource, gamma_, this->field_, operatorScaling);
156 source += tmpsource;
157 }
158
160 {
161 NF_ASSERT(sameTypeStrategy_, "LaplacianOperatorStrategy not initialized");
162 const auto operatorScaling = this->getCoefficient();
163 sameTypeStrategy_->laplacian(ls, gamma_, this->field_, operatorScaling);
164 }
165
166 /* @brief Implicit assembly into a scalar-matrix / FieldValueType-rhs linear system
167 * (segregated vector-solve form). Only present when FieldValueType != scalar.
168 */
169 template<typename F = FieldValueType>
170 requires(!std::is_same_v<F, scalar>)
172 {
173 NF_ASSERT(scalarMtxStrategy_, "Scalar-matrix LaplacianOperatorStrategy not initialized");
174 const auto operatorScaling = this->getCoefficient();
175 scalarMtxStrategy_->laplacian(ls, gamma_, this->field_, operatorScaling);
176 }
177
178 void read(const Input& input)
179 {
180 const UnstructuredMesh& mesh = this->field_.mesh();
181 NeoN::TokenList tokens;
182 if (std::holds_alternative<NeoN::Dictionary>(input))
183 {
184 auto dict = std::get<NeoN::Dictionary>(input);
185 std::string schemeName = "laplacian(" + gamma_.name + "," + this->field_.name + ")";
186 tokens = dict.subDict("laplacianSchemes").get<NeoN::TokenList>(schemeName);
187 }
188 else
189 {
190 tokens = std::get<NeoN::TokenList>(input);
191 }
193 this->exec(), mesh, tokens
194 );
195 if constexpr (!std::is_same_v<FieldValueType, scalar>)
196 {
197 tokens.reset();
199 this->exec(), mesh, tokens
200 );
201 }
202 }
203
204 std::string getName() const { return "LaplacianOperator"; }
205
206 // TODO make this private and let only friends use it
208 {
209 const auto& ret = this->getVector();
210 const auto& coeff = this->getCoefficient();
211 return {
213 {"coeff", detail::RefHolder<dsl::Coeff> {coeff}},
215 };
216 }
217
218private:
219
220 const SurfaceField<scalar>& gamma_;
221
222 std::unique_ptr<LaplacianOperatorFactory<FieldValueType, FieldValueType>> sameTypeStrategy_;
223 // Only initialized when FieldValueType != scalar; used to assemble into a
224 // LinearSystem<scalar, FieldValueType> for segregated vector solves.
225 std::unique_ptr<LaplacianOperatorFactory<FieldValueType, scalar>> scalarMtxStrategy_;
226};
227
228
229} // namespace NeoN
A class representing a dictionary that stores key-value pairs.
A factory class for runtime selection of derived classes.
A class representing a list of tokens.
Definition tokenList.hpp:31
ReturnType & get(const size_t &idx)
Retrieves the value associated with the given index, casting it to the specified type.
void reset() const
Rewind the read cursor used by next<>() so the list can be iterated again from the beginning.
Definition tokenList.hpp:92
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
const VolumeField< FieldValueType > & field_
Definition operator.hpp:69
const Executor exec_
Executor associated with the field. (CPU, GPU, openMP, etc.)
Definition operator.hpp:65
OperatorMixin(const Executor exec, const Coeff &coeffs, const VolumeField< FieldValueType > &field, Operator::Type type)
Definition operator.hpp:42
const VolumeField< FieldValueType > & getVector() const
Definition operator.hpp:58
virtual const Executor & exec() const final
Definition operator.hpp:52
const UnstructuredMesh & mesh() const
Returns a const reference to the unstructured mesh object.
Definition domain.hpp:122
virtual std::unique_ptr< LaplacianOperatorFactory< FieldValueType, AssemblyType > > clone() const =0
virtual void laplacian(la::LinearSystem< AssemblyType, FieldValueType > &ls, const SurfaceField< scalar > &gamma, const VolumeField< FieldValueType > &phi, const dsl::Coeff operatorScaling)=0
virtual VolumeField< FieldValueType > laplacian(const SurfaceField< scalar > &gamma, const VolumeField< FieldValueType > &phi, const dsl::Coeff operatorScaling) const =0
virtual void laplacian(Vector< FieldValueType > &lapPhi, const SurfaceField< scalar > &gamma, const VolumeField< FieldValueType > &phi, const dsl::Coeff operatorScaling)=0
static std::unique_ptr< LaplacianOperatorFactory< FieldValueType, AssemblyType > > create(const Executor &exec, const UnstructuredMesh &mesh, const Input &inputs)
virtual void laplacian(VolumeField< FieldValueType > &lapPhi, const SurfaceField< scalar > &gamma, const VolumeField< FieldValueType > &phi, const dsl::Coeff operatorScaling)=0
LaplacianOperatorFactory(const Executor &exec, const UnstructuredMesh &mesh)
void implicitOperation(la::LinearSystem< scalar, FieldValueType > &ls) const
void implicitOperation(la::LinearSystem< FieldValueType, FieldValueType > &ls) const
LaplacianOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &gamma, VolumeField< FieldValueType > &phi, Input input)
LaplacianOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &gamma, VolumeField< FieldValueType > &phi)
void explicitOperation(Vector< FieldValueType > &source) const
Represents a surface field in a finite volume method.
Represents a volume field in a finite volume method.
A class representing a linear system of equations.
#define NF_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false.
Definition error.hpp:118
std::variant< Dictionary, TokenList > Input
Definition input.hpp:15
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:20
A wrapper class to put references in dictionaries to overcome the issue that std::any cannot hold a r...