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 -------------------------------------------------------------------------------
12 License
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 
35 namespace Foam
36 {
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 defineTypeNameAndDebug(objectiveManager, 0);
41 defineRunTimeSelectionTable(objectiveManager, dictionary);
42 
43 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
44 
45 objectiveManager::objectiveManager
46 (
47  const fvMesh& mesh,
48  const dictionary& dict,
49  const word& adjointSolverName,
50  const word& primalSolverName
51 )
52 :
54  (
55  IOobject
56  (
57  "objectiveManager" + adjointSolverName,
58  mesh.time().system(),
59  mesh,
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,
92  adjointSolverName,
93  primalSolverName
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();
110  weigthedObjectiveFile_.reset
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;
120  weigthedObjectiveFile_()
121  << setw(4) << "#" << " "
122  << setw(width) << "weightedObjective" << " ";
123  for (objective& objI : objectives_)
124  {
125  weigthedObjectiveFile_()
126  << setw(width) << objI.objectiveName() << " ";
127  }
128  weigthedObjectiveFile_()
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  (
164  ctorPtr(mesh, dict, adjointSolverName, primalSolverName)
165  );
166 }
167 
168 
169 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
170 
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;
271  weigthedObjectiveFile_()
272  << setw(4) << mesh_.time().timeName() << " "
273  << setw(width) << weightedObjective << " ";
274 
275  for (objective& objI : objectives_)
276  {
277  weigthedObjectiveFile_()
278  << setw(width) << objI.JCycle() << " ";
279  }
280  weigthedObjectiveFile_() << endl;
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 // ************************************************************************* //
Foam::objectiveManager::updateNormalizationFactor
void updateNormalizationFactor()
Update objective function related values.
Definition: objectiveManager.C:185
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::objectiveManager::primalSolverName
const word & primalSolverName() const
Return name of the primalSolver.
Definition: objectiveManager.C:314
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::dictionary::New
static autoPtr< dictionary > New(Istream &is)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:69
Foam::objectiveManager::print
scalar print()
Print to screen.
Definition: objectiveManager.C:236
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::objectiveManager::objectives_
PtrList< objective > objectives_
Definition: objectiveManager.H:66
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::objectiveManager::readDict
virtual bool readDict(const dictionary &dict)
Definition: objectiveManager.C:171
Foam::objectiveManager::update
void update()
Update objective function related values.
Definition: objectiveManager.C:198
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
objectiveManager.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
FatalIOErrorInLookup
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:478
Foam::objectiveManager::incrementIntegrationTimes
void incrementIntegrationTimes(const scalar timeSpan)
Increment integration times by the optimisation cycle time-span.
Definition: objectiveManager.C:225
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::objectiveManager::writeObjectives
virtual bool writeObjectives(const scalar weightedObjective, const bool valid=true)
Write objective function history.
Definition: objectiveManager.C:256
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::objectiveManager::primalSolverName_
const word primalSolverName_
Definition: objectiveManager.H:65
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::objectiveManager::adjointSolverName_
const word adjointSolverName_
Definition: objectiveManager.H:64
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Foam::objectiveManager::checkIntegrationTimes
void checkIntegrationTimes() const
Check integration times for unsteady runs.
Definition: objectiveManager.C:320
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePathsI.H:102
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::objectiveManager::New
static autoPtr< objectiveManager > New(const fvMesh &mesh, const dictionary &dict, const word &adjointSolverName, const word &primalSolverName)
Return a reference to the selected turbulence model.
Definition: objectiveManager.C:138
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::List< word >
Foam::objectiveManager::updateAndWrite
void updateAndWrite()
Definition: objectiveManager.C:287
Foam::TimePaths::globalPath
fileName globalPath() const
Return global path for the case.
Definition: TimePathsI.H:80
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::objectiveManager::updateOrNullify
void updateOrNullify()
Update contributions to adjoint if true, otherwise return nulls.
Definition: objectiveManager.C:208
Foam::objectiveManager::adjointSolverName
const word & adjointSolverName() const
Return name of the adjointSolver.
Definition: objectiveManager.C:308
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::objective
Abstract base class for objective functions. No point in making this runTime selectable since its chi...
Definition: objective.H:59
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::objectRegistry::time
const Time & time() const noexcept
Return time registry.
Definition: objectRegistry.H:178
Foam::objectiveManager::getObjectiveFunctions
PtrList< objective > & getObjectiveFunctions()
Return reference to objective functions.
Definition: objectiveManager.C:296