optimisationManager.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) 2007-2019 PCOpt/NTUA
9 Copyright (C) 2013-2019 FOSS GP
10 Copyright (C) 2019-2021 OpenCFD Ltd.
11-------------------------------------------------------------------------------
12License
13 This file is part of OpenFOAM.
14
15 OpenFOAM is free software: you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27
28\*---------------------------------------------------------------------------*/
29
30#include "optimisationManager.H"
31
32// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33
34namespace Foam
35{
38}
39
40
41// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
42
44:
46 (
48 (
49 "optimisationDict",
50 mesh.time().system(),
51 mesh,
52 IOobject::MUST_READ_IF_MODIFIED,
53 IOobject::NO_WRITE,
54 true
55 )
56 ),
57 mesh_(mesh),
58 time_(const_cast<Time&>(mesh.time())),
59 primalSolvers_(),
60 adjointSolverManagers_(),
61 managerType_(get<word>("optimisationManager")),
62 optType_(nullptr)
63{
64 dictionary& primalSolversDict = subDict("primalSolvers");
65 const wordList& primalSolverNames = primalSolversDict.toc();
66
67 // Construct primal solvers
68 primalSolvers_.setSize(primalSolverNames.size());
69 forAll(primalSolvers_, solveri)
70 {
71 dictionary& solverDict =
72 primalSolversDict.subDict(primalSolverNames[solveri]);
73 if (primalSolvers_.size() > 1)
74 {
75 solverDict.add<bool>("useSolverNameForFields", true);
76 }
78 (
79 solveri,
81 (
82 mesh,
84 solverDict
85 )
86 );
87 }
88
89 // Construct adjointSolverManagers
90 const dictionary& adjointManagersDict = subDict("adjointManagers");
91 const wordList& adjointManagerNames = adjointManagersDict.toc();
92 adjointSolverManagers_.setSize(adjointManagerNames.size());
93
94 label nAdjointSolvers(0);
95 bool overrideUseSolverName(adjointSolverManagers_.size() > 1);
97 {
99 (
100 manageri,
102 (
103 mesh,
105 adjointManagersDict.subDict(adjointManagerNames[manageri]),
106 overrideUseSolverName
107 )
108 );
109 nAdjointSolvers += adjointSolverManagers_[manageri].nAdjointSolvers();
110 }
111
112 // Sanity checks on the naming convention
113 if (primalSolvers_.size() > 1)
114 {
115 for (const primalSolver& solveri : primalSolvers_)
116 {
117 if (!solveri.useSolverNameForFields())
118 {
120 << "Multiple primal solvers are present but "
121 << "useSolverNameForFields is set to false in "
122 << "primal solver " << solveri.solverName() << nl
123 << "This is considered fatal."
124 << exit(FatalError);
125 }
126 }
127 }
128
129 if (nAdjointSolvers > 1)
130 {
132 {
133 const PtrList<adjointSolver>& adjointSolvers = amI.adjointSolvers();
134 for (const adjointSolver& asI : adjointSolvers)
135 {
136 if (!asI.useSolverNameForFields())
137 {
139 << "Multiple adjoint solvers are present but "
140 << "useSolverNameForFields is set to false in "
141 << "adjoint solver " << asI.solverName() << nl
142 << "This is considered fatal."
143 << exit(FatalError);
144 }
145 }
146 }
147 }
148}
149
150
151// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
152
154(
155 fvMesh& mesh
156)
157{
158 const IOdictionary dict
159 (
161 (
162 "optimisationDict",
163 mesh.time().system(),
164 mesh,
167 false // Do not register
168 )
169 );
170
171 const word modelType(dict.get<word>("optimisationManager"));
172
173 Info<< "optimisationManager type : " << modelType << endl;
174
175 auto* ctorPtr = dictionaryConstructorTable(modelType);
176
177 if (!ctorPtr)
178 {
180 (
181 dict,
182 "optimisationManager",
183 modelType,
184 *dictionaryConstructorTablePtr_
185 ) << exit(FatalIOError);
186 }
187
188 return autoPtr<optimisationManager>(ctorPtr(mesh));
189}
190
191
192// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
193
195{
196 if (regIOobject::read())
197 {
198 // Note: Only changing existing solvers - not adding any new
199 const dictionary& primalSolversDict = subDict("primalSolvers");
200 for (primalSolver& sol : primalSolvers_)
201 {
202 sol.readDict(primalSolversDict.subDict(sol.solverName()));
203 }
204
205 const dictionary& adjointManagersDict = subDict("adjointManagers");
206 for (adjointSolverManager& man : adjointSolverManagers_)
207 {
208 man.readDict(adjointManagersDict.subDict(man.managerName()));
209 }
210
211 return true;
212 }
213
214 return false;
215}
216
217
219{
220 return primalSolvers_;
221}
222
223
226{
227 return adjointSolverManagers_;
228}
229
230
232{
233 // Solve all primal equations
234 forAll(primalSolvers_, psI)
235 {
236 primalSolvers_[psI].solve();
237 }
238}
239
240
242{
243 // Solve all adjoint solver equations
244 forAll(adjointSolverManagers_, amI)
245 {
246 adjointSolverManagers_[amI].solveAdjointEquations();
247 }
248}
249
250
252{
253 // Compute senstivities from all adjoint solvers
254 forAll(adjointSolverManagers_, amI)
255 {
256 adjointSolverManagers_[amI].computeAllSensitivities();
257 }
258}
259
260
262{
263 forAll(adjointSolverManagers_, amI)
264 {
265 PtrList<adjointSolver>& adjointSolvers =
266 adjointSolverManagers_[amI].adjointSolvers();
267
268 forAll(adjointSolvers, asI)
269 {
270 adjointSolvers[asI].updatePrimalBasedQuantities();
271 }
272 }
273}
274
275
276// ************************************************************************* //
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:180
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
const word & system() const
Return system name.
Definition: TimePathsI.H:102
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Class for managing adjoint solvers, which may be more than one per operating point.
Base class for adjoint solvers.
Definition: adjointSolver.H:60
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:640
wordList toc() const
Return the table of contents.
Definition: dictionary.C:602
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:290
Abstract base class for optimisation methods.
virtual void solvePrimalEquations()
Solve all primal equations.
virtual void updatePrimalBasedQuantities()
Solve all primal equations.
PtrList< adjointSolverManager > adjointSolverManagers_
virtual void solveAdjointEquations()
Solve all adjoint equations.
virtual PtrList< adjointSolverManager > & adjointSolverManagers()
PtrList< primalSolver > primalSolvers_
virtual void computeSensitivities()
Compute all adjoint sensitivities.
virtual PtrList< primalSolver > & primalSolvers()
virtual bool read()
Read object.
Base class for primal solvers.
Definition: primalSolver.H:55
virtual bool read()
Read object.
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
dynamicFvMesh & mesh
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:478
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Namespace for OpenFOAM.
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
Definition: MSwindows.C:1158
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOerror FatalIOError
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define defineRunTimeSelectionTable(baseType, argNames)
Define run-time selection table.
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333