objectiveManager.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-2021 PCOpt/NTUA
9 Copyright (C) 2013-2021 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 "objectiveManager.H"
31#include "IOmanip.H"
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34
35namespace Foam
36{
37
38// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39
42
43// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44
46(
47 const fvMesh& mesh,
48 const dictionary& dict,
49 const word& adjointSolverName,
50 const word& primalSolverName
51)
52:
54 (
56 (
57 "objectiveManager" + adjointSolverName,
58 mesh.time().system(),
59 mesh,
60 IOobject::NO_READ,
61 IOobject::NO_WRITE,
62 true //register object
63 )
64 ),
65 mesh_(mesh),
66 dict_(dict),
67 adjointSolverName_(adjointSolverName),
68 primalSolverName_(primalSolverName),
69 objectives_(0),
70 weigthedObjectiveFile_(nullptr)
71{
72 // Construct objectives
73 //~~~~~~~~~~~~~~~~~~~~~
74 Info << "Constructing objective functions " << nl << endl;
75 const word objectiveType = dict.get<word>("type");
76 const dictionary& objectiveNamesDict(dict.subDict("objectiveNames"));
77 wordList objectiveNames(objectiveNamesDict.toc());
78 objectives_.setSize(objectiveNames.size());
79
80 forAll(objectiveNames, objectivei)
81 {
82 const word& objectiveName = objectiveNames[objectivei];
83
84 objectives_.set
85 (
86 objectivei,
88 (
89 mesh_,
90 objectiveNamesDict.subDict(objectiveName),
91 objectiveType,
94 )
95 );
96 }
97
98 if (objectives_.empty())
99 {
100 FatalIOErrorInFunction(objectiveNamesDict)
101 << "No objectives have been set - cannot perform an optimisation"
102 << exit(FatalIOError);
103 }
104
105 if (Pstream::master())
106 {
107 if (objectives_.size() > 1)
108 {
109 const Time& time = mesh_.time();
111 (
112 new OFstream
113 (
114 time.globalPath()/"optimisation"/"objective"
115 /time.timeName()/"weightedObjective"+adjointSolverName_
116 )
117 );
118
119 unsigned int width = IOstream::defaultPrecision() + 5;
121 << setw(4) << "#" << " "
122 << setw(width) << "weightedObjective" << " ";
123 for (objective& objI : objectives_)
124 {
126 << setw(width) << objI.objectiveName() << " ";
127 }
129 << endl;
130 }
131 }
132}
133
134
135// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
136
138(
139 const fvMesh& mesh,
140 const dictionary& dict,
141 const word& adjointSolverName,
142 const word& primalSolverName
143)
144{
145 // Determine type of objectiveManager from objectiveType
146 const word objectiveType(dict.get<word>("type"));
147 const word managerType("objectiveManager" & objectiveType);
148
149 auto* ctorPtr = dictionaryConstructorTable(managerType);
150
151 if (!ctorPtr)
152 {
154 (
155 dict,
156 "objectiveManagerType",
157 managerType,
158 *dictionaryConstructorTablePtr_
159 ) << exit(FatalIOError);
160 }
161
163 (
165 );
166}
167
168
169// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
170
171bool objectiveManager::readDict(const dictionary& dict)
172{
173 for (objective& obj : objectives_)
174 {
175 obj.readDict
176 (
177 dict.subDict("objectiveNames").subDict(obj.objectiveName())
178 );
179 }
180
181 return true;
182}
183
184
186{
187 // Update normalization factors for all objectives
188 for (objective& obj : objectives_)
189 {
190 if (obj.normalize())
191 {
192 obj.updateNormalizationFactor();
193 }
194 }
195}
196
197
199{
200 // Update all fields related to the objective function
201 for (objective& obj : objectives_)
202 {
203 obj.update();
204 }
205}
206
207
209{
210 // Update contributions to adjoint if true, otherwise return nulls
211 for (objective& obj : objectives_)
212 {
213 if (obj.isWithinIntegrationTime())
214 {
215 obj.update();
216 }
217 else
218 {
219 obj.nullify();
220 }
221 }
222}
223
224
226{
227 // Update start and end integration times by adding the timeSpan
228 // of the optimisation cycle
229 for (objective& obj : objectives_)
230 {
231 obj.incrementIntegrationTimes(timeSpan);
232 }
233}
234
235
237{
238 scalar objValue(Zero);
239 Info<< "Adjoint solver " << adjointSolverName_ << endl;
240 for (objective& obj : objectives_)
241 {
242 scalar cost = obj.JCycle();
243 scalar weight = obj.weight();
244 objValue += weight*cost;
245
246 Info<< obj.objectiveName() << " : " << cost << endl;
247 }
248
249 Info<< "Weighted objective : " << objValue << nl << endl;
250
251 return objValue;
252}
253
254
256(
257 const scalar weightedObjective,
258 const bool valid
259)
260{
261 for (const objective& obj : objectives_)
262 {
263 // Write objective function to file
264 obj.write();
265 obj.writeMeanValue();
266 }
267
268 if (weigthedObjectiveFile_.valid())
269 {
270 unsigned int width = IOstream::defaultPrecision() + 5;
272 << setw(4) << mesh_.time().timeName() << " "
273 << setw(width) << weightedObjective << " ";
274
275 for (objective& objI : objectives_)
276 {
278 << setw(width) << objI.JCycle() << " ";
279 }
281 }
282
283 return true;
284}
285
286
288{
290 update();
291 scalar weightedObjective = print();
292 writeObjectives(weightedObjective);
293}
294
295
297{
298 return objectives_;
299}
300
301
303{
304 return objectives_;
305}
306
307
309{
310 return adjointSolverName_;
311}
312
313
315{
316 return primalSolverName_;
317}
318
319
321{
322 for (const objective& obj : objectives_)
323 {
324 if (!obj.hasIntegrationStartTime() || !obj.hasIntegrationEndTime())
325 {
327 << "Objective function " << obj.objectiveName()
328 << " does not have a defined integration start or end time "
329 << exit(FatalError);
330 }
331 }
332}
333
334
335// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
336
337} // End namespace Foam
338
339// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:506
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Output to file stream, using an OSstream.
Definition: OFstream.H:57
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:80
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
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
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
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
class for managing incompressible objective functions.
autoPtr< OFstream > weigthedObjectiveFile_
virtual bool writeObjectives(const scalar weightedObjective, const bool valid=true)
Write objective function history.
PtrList< objective > & getObjectiveFunctions()
Return reference to objective functions.
const word & adjointSolverName() const
Return name of the adjointSolver.
scalar print()
Print to screen.
void checkIntegrationTimes() const
Check integration times for unsteady runs.
PtrList< objective > objectives_
void updateOrNullify()
Update contributions to adjoint if true, otherwise return nulls.
void incrementIntegrationTimes(const scalar timeSpan)
Increment integration times by the optimisation cycle time-span.
void update()
Update objective function related values.
void updateNormalizationFactor()
Update objective function related values.
const word & primalSolverName() const
Return name of the primalSolver.
Abstract base class for objective functions. No point in making this runTime selectable since its chi...
Definition: objective.H:62
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:76
splitCell * master() const
Definition: splitCell.H:113
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 FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#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)
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOerror FatalIOError
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
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