Loading...
Searching...
No Matches
DMD.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2020-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "DMD.H"
29#include "DMDModel.H"
32// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33
34namespace Foam
35{
36namespace functionObjects
37{
40}
41}
42
43
44// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45
46void Foam::functionObjects::DMD::snapshot()
47{
48 bool processed = false;
49 processed = processed || getSnapshot<scalar>();
50 processed = processed || getSnapshot<vector>();
51 processed = processed || getSnapshot<sphericalTensor>();
52 processed = processed || getSnapshot<symmTensor>();
53 processed = processed || getSnapshot<tensor>();
54
55 if (!processed)
56 {
58 << " functionObjects::" << type() << " " << name() << ":"
59 << " cannot find required input field during snapshot loading: "
60 << fieldName_ << nl
61 << " Do you execute required functionObjects"
62 << " before executing DMD, e.g. mapFields?"
63 << exit(FatalError);
64 }
65}
66
67
68Foam::label Foam::functionObjects::DMD::nComponents(const word& fieldName) const
69{
70 label nComps = 0;
71 bool processed = false;
72 processed = processed || nComponents<scalar>(fieldName, nComps);
73 processed = processed || nComponents<vector>(fieldName, nComps);
74 processed = processed || nComponents<sphericalTensor>(fieldName, nComps);
75 processed = processed || nComponents<symmTensor>(fieldName, nComps);
76 processed = processed || nComponents<tensor>(fieldName, nComps);
77
78 if (!processed)
79 {
81 << "Unknown type of input field during initialisation: "
82 << fieldName << nl
83 << exit(FatalError);
84 }
85
86 return nComps;
87}
88
89
90void Foam::functionObjects::DMD::initialise()
91{
92 const label nComps = nComponents(fieldName_);
93
94 if (patches_.empty())
95 {
96 nSnap_ = nComps*mesh_.nCells();
97 }
98 else
99 {
100 const labelList patchis
101 (
102 mesh_.boundaryMesh().patchSet(patches_).sortedToc()
103 );
104
105 for (const label patchi : patchis)
106 {
107 nSnap_ += nComps*(mesh_.C().boundaryField()[patchi]).size();
108 }
109 }
110
111 const label nSnapTotal = returnReduce(nSnap_, sumOp<label>());
112
113 if (nSnapTotal <= 0)
114 {
116 << "Zero-size input field = " << fieldName_
117 << exit(FatalError);
118 }
119
120 if (nSnap_ > 0)
121 {
122 z_ = RMatrix(2*nSnap_, 1, Zero);
123 }
124 else
125 {
126 z_ = RMatrix(1, 1, Zero);
127 }
128}
129
130
131// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
132
134(
135 const word& name,
136 const Time& runTime,
137 const dictionary& dict
138)
139:
140 fvMeshFunctionObject(name, runTime, dict),
141 DMDModelPtr_(DMDModel::New(mesh_, name, dict)),
142 z_(),
143 patches_
144 (
145 dict.getOrDefault<wordRes>
146 (
147 "patches",
148 dict.found("patch") ? wordRes(1,dict.get<word>("patch")) : wordRes()
149 )
150 ),
151 fieldName_(dict.get<word>("field")),
152 nSnap_(0),
153 step_(0)
154{
155 // Check if computation time-step is varying
156 if (runTime.isAdjustTimeStep())
157 {
158 WarningInFunction
159 << "DMD is available only for fixed time-step computations."
160 << endl;
161 }
162
163 // Check if mesh topology is changing
165 {
166 FatalErrorInFunction
167 << "DMD is available only for non-changing mesh topology."
168 << exit(FatalError);
169 }
171 read(dict);
172}
173
174
175// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
176
178{
179 Info<< type() << " " << name() << ":" << endl;
180
181 if (fvMeshFunctionObject::read(dict) && DMDModelPtr_->read(dict))
182 {
183 return true;
184 }
185
186 return false;
187}
188
189
191{
192 Log << type() << " " << name() << " execute:" << endl;
193
194 snapshot();
195
196 if (step_ == 1)
197 {
198 DMDModelPtr_->initialise(z_);
199 }
200
201 if (step_ > 1)
202 {
203 DMDModelPtr_->update(z_);
204 }
205
206 ++step_;
207
208 Log << tab << "Execution index = " << step_ << " for field: " << fieldName_
209 << endl;
210
211 return true;
212}
213
214
216{
217 if (postProcess)
218 {
219 return true;
220 }
221
222 return end();
223}
224
225
227{
228 if (step_ == 0)
229 {
230 // Avoid double execution of write() when writeControl=onEnd
231 return true;
232 }
233
234 Log << type() << " " << name() << " write:" << endl;
235
236 if (step_ < 2)
237 {
239 << "DMD needs at least three snapshots to produce output" << nl
240 << " Only " << step_ + 1 << " snapshots are available" << nl
241 << " Skipping DMD output calculation and write"
242 << endl;
243
244 return false;
245 }
246
247 z_.clear();
248
249 DMDModelPtr_->fit();
250
251 mesh_.time().printExecutionTime(Info);
252
253 // Restart the incremental orthonormal basis update
254 step_ = 0;
255
256 return true;
257}
258
259
260// ************************************************************************* //
#define Log
Definition PDRblock.C:28
bool found
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
if(patchID !=-1)
Abstract base class for DMD models to handle DMD characteristics for the DMD function object.
Definition DMDModel.H:65
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Abstract base-class for Time/database function objects.
const word & name() const noexcept
Return the name of this functionObject.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
static bool postProcess
Global post-processing mode switch.
virtual const word & type() const =0
Runtime type information.
Computes a dynamic mode decomposition model on a specified field.
Definition DMD.H:240
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
Definition DMD.C:170
DMD(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
Definition DMD.C:127
virtual bool execute()
Execute the function-object operations.
Definition DMD.C:183
virtual bool write()
Write the function-object results.
Definition DMD.C:208
virtual bool end()
Write DMD results.
Definition DMD.C:219
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
bool topoChanging() const noexcept
Is mesh topology changing.
Definition polyMesh.H:750
A List of wordRe with additional matching capabilities.
Definition wordRes.H:56
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
engineTime & runTime
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
#define WarningInFunction
Report a warning using Foam::Warning.
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
Definition exprTraits.C:40
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
Namespace for OpenFOAM.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
List< label > labelList
A List of labels.
Definition List.H:62
messageStream Info
Information stream (stdout output on master, null elsewhere).
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
constexpr char tab
The tab '\t' character(0x09).
Definition Ostream.H:49
dictionary dict