NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
laplacianOperator.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 NeoFOAM authors
3
4#pragma once
5
14
16{
17
18/* @class Factory class to create divergence operators by a given name using
19 * using NeoFOAMs runTimeFactory mechanism
20 */
21template<typename ValueType>
24 LaplacianOperatorFactory<ValueType>,
25 Parameters<const Executor&, const UnstructuredMesh&, const Input&>>
26{
27
28public:
29
30 static std::unique_ptr<LaplacianOperatorFactory<ValueType>>
31 create(const Executor& exec, const UnstructuredMesh& uMesh, const Input& inputs)
32 {
33 std::string key = (std::holds_alternative<Dictionary>(inputs))
34 ? std::get<Dictionary>(inputs).get<std::string>("LaplacianOperator")
35 : std::get<TokenList>(inputs).next<std::string>();
37 return LaplacianOperatorFactory<ValueType>::table().at(key)(exec, uMesh, inputs);
38 }
39
40 static std::string name() { return "LaplacianOperatorFactory"; }
41
43 : exec_(exec), mesh_(mesh) {};
44
45 virtual ~LaplacianOperatorFactory() {} // Virtual destructor
46
48
49 virtual void laplacian(
51 const SurfaceField<scalar>& gamma,
53 const dsl::Coeff operatorScaling
54 ) = 0;
55
56 virtual void laplacian(
57 Field<ValueType>& lapPhi,
58 const SurfaceField<scalar>& gamma,
60 const dsl::Coeff operatorScaling
61 ) = 0;
62
63 virtual void laplacian(
65 const SurfaceField<scalar>& gamma,
67 const dsl::Coeff operatorScaling
68 ) = 0;
69
70 // Pure virtual function for cloning
71 virtual std::unique_ptr<LaplacianOperatorFactory<ValueType>> clone() const = 0;
72
73protected:
74
76
78};
79
80template<typename ValueType>
81class LaplacianOperator : public dsl::OperatorMixin<VolumeField<ValueType>>
82{
83
84public:
85
86 using FieldValueType = ValueType;
87
88 // copy constructor
90 : dsl::OperatorMixin<VolumeField<ValueType>>(
91 lapOp.exec_, lapOp.coeffs_, lapOp.field_, lapOp.type_
92 ),
93 gamma_(lapOp.gamma_),
94 laplacianOperatorStrategy_(
95 lapOp.laplacianOperatorStrategy_ ? lapOp.laplacianOperatorStrategy_->clone() : nullptr
96 ) {};
97
99 dsl::Operator::Type termType,
100 const SurfaceField<scalar>& gamma,
102 Input input
103 )
104 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
105 gamma_(gamma),
106 laplacianOperatorStrategy_(
107 LaplacianOperatorFactory<ValueType>::create(this->exec_, phi.mesh(), input)
108 ) {};
109
111 dsl::Operator::Type termType,
112 const SurfaceField<scalar>& gamma,
114 std::unique_ptr<LaplacianOperatorFactory<ValueType>> laplacianOperatorStrategy
115 )
116 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
117 gamma_(gamma), laplacianOperatorStrategy_(std::move(laplacianOperatorStrategy)) {};
118
121 )
122 : dsl::OperatorMixin<VolumeField<ValueType>>(phi.exec(), dsl::Coeff(1.0), phi, termType),
123 gamma_(gamma), laplacianOperatorStrategy_(nullptr) {};
124
125
127 {
128 NF_ASSERT(laplacianOperatorStrategy_, "LaplacianOperatorStrategy not initialized");
129 const auto operatorScaling = this->getCoefficient();
130 NeoFOAM::Field<ValueType> tmpsource(source.exec(), source.size(), zero<ValueType>());
131 laplacianOperatorStrategy_->laplacian(tmpsource, gamma_, this->field_, operatorScaling);
132 source += tmpsource;
133 }
134
136 {
137 NF_ASSERT(laplacianOperatorStrategy_, "LaplacianOperatorStrategy not initialized");
138 return laplacianOperatorStrategy_->createEmptyLinearSystem();
139 }
140
142 {
143 NF_ASSERT(laplacianOperatorStrategy_, "LaplacianOperatorStrategy not initialized");
144 const auto operatorScaling = this->getCoefficient();
145 laplacianOperatorStrategy_->laplacian(ls, gamma_, this->field_, operatorScaling);
146 }
147
148 // void laplacian(Field<scalar>& lapPhi)
149 // {
150 // laplacianOperatorStrategy_->laplacian(lapPhi, gamma_, getField());
151 // }
152
153 // void laplacian(la::LinearSystem<scalar, localIdx>& ls)
154 // {
155 // laplacianOperatorStrategy_->laplacian(ls, gamma_, getField());
156 // };
157
159 {
160 const auto operatorScaling = this->getCoefficient();
161 laplacianOperatorStrategy_->laplacian(lapPhi, gamma_, this->getField(), operatorScaling);
162 }
163
164
165 void build(const Input& input)
166 {
167 const UnstructuredMesh& mesh = this->field_.mesh();
168 if (std::holds_alternative<NeoFOAM::Dictionary>(input))
169 {
170 auto dict = std::get<NeoFOAM::Dictionary>(input);
171 std::string schemeName = "laplacian(" + gamma_.name + "," + this->field_.name + ")";
172 auto tokens = dict.subDict("laplacianSchemes").get<NeoFOAM::TokenList>(schemeName);
173 laplacianOperatorStrategy_ =
175 }
176 else
177 {
178 auto tokens = std::get<NeoFOAM::TokenList>(input);
179 laplacianOperatorStrategy_ =
181 }
182 }
183
184 std::string getName() const { return "LaplacianOperator"; }
185
186private:
187
188 const SurfaceField<NeoFOAM::scalar>& gamma_;
189
190 std::unique_ptr<LaplacianOperatorFactory<ValueType>> laplacianOperatorStrategy_;
191};
192
193
194} // namespace NeoFOAM
A class to contain the data and executors for a field and define some basic operations.
Definition field.hpp:49
size_t size() const
Gets the size of the field.
Definition field.hpp:357
const Executor & exec() const
Gets the executor associated with the field.
Definition field.hpp:351
A factory class for runtime selection of derived classes.
A class representing a list of tokens.
Definition tokenList.hpp:27
Represents an unstructured mesh in NeoFOAM.
A class that represents a coefficient for the NeoFOAM dsl.
Definition coeff.hpp:22
OperatorMixin(const Executor exec, const Coeff &coeffs, VolumeField< ValueType > &field, Operator::Type type)
Definition operator.hpp:32
virtual const Executor & exec() const final
Definition operator.hpp:40
const Executor exec_
Executor associated with the field. (CPU, GPU, openMP, etc.)
Definition operator.hpp:55
virtual void laplacian(la::LinearSystem< ValueType, localIdx > &ls, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling)=0
LaplacianOperatorFactory(const Executor &exec, const UnstructuredMesh &mesh)
virtual la::LinearSystem< ValueType, localIdx > createEmptyLinearSystem() const =0
virtual std::unique_ptr< LaplacianOperatorFactory< ValueType > > clone() const =0
virtual void laplacian(VolumeField< ValueType > &lapPhi, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling)=0
virtual void laplacian(Field< ValueType > &lapPhi, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi, const dsl::Coeff operatorScaling)=0
static std::unique_ptr< LaplacianOperatorFactory< ValueType > > create(const Executor &exec, const UnstructuredMesh &uMesh, const Input &inputs)
LaplacianOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi, std::unique_ptr< LaplacianOperatorFactory< ValueType > > laplacianOperatorStrategy)
LaplacianOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi, Input input)
LaplacianOperator(dsl::Operator::Type termType, const SurfaceField< scalar > &gamma, VolumeField< ValueType > &phi)
la::LinearSystem< ValueType, localIdx > createEmptyLinearSystem() const
void implicitOperation(la::LinearSystem< ValueType, localIdx > &ls)
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:142
std::variant< Dictionary, TokenList > Input
Definition input.hpp:13
std::variant< SerialExecutor, CPUExecutor, GPUExecutor > Executor
Definition executor.hpp:16