optimisationTypeIncompressible.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-2020 PCOpt/NTUA
9  Copyright (C) 2013-2020 FOSS GP
10  Copyright (C) 2019-2020 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 
32 #include "runTimeSelectionTables.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 namespace incompressible
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 defineTypeNameAndDebug(optimisationType, 0);
45 defineRunTimeSelectionTable(optimisationType, dictionary);
46 
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 
49 optimisationType::optimisationType
50 (
51  fvMesh& mesh,
52  const dictionary& dict,
54 )
55 :
56  mesh_(mesh),
57  dict_(dict),
58  adjointSolvManagers_(adjointSolverManagers),
59  updateMethod_
60  (
61  updateMethod::New(mesh_, dict_.subDict("updateMethod"))
62  ),
63  sourcePtr_(nullptr),
64  lineSearch_
65  (
67  (
68  dict_.subDict("updateMethod").subOrEmptyDict("lineSearch"),
69  mesh.time()
70  )
71  )
72 {
73  // Figure out number of adjoint solvers corresponding to constraints.
74  // Looks in all operating poitns
75  label nConstraints(0);
76  for (const adjointSolverManager& adjManagerI : adjointSolvManagers_)
77  {
78  nConstraints += adjManagerI.nConstraints();
79  }
80 
81  // Sanity checks for combinations of number of constraints and
82  // optimisation methods
83  if
84  (
85  nConstraints
86  && !isA<constrainedOptimisationMethod>(updateMethod_())
87  )
88  {
89  // Has constraints but is not a constraint optimisation method
90  auto cstTablePtr
91  (
92  constrainedOptimisationMethod::dictionaryConstructorTablePtr_
93  );
95  << "Found " << nConstraints << " adjoint solvers corresponding to "
96  << "constraints but the optimisation method used "
97  << "(" << updateMethod_().type() << ") "
98  << "is not a constrainedOptimisationMethod. " << nl
99  << "Available constrainedOptimisationMethods are :" << nl
100  << cstTablePtr->sortedToc()
101  << exit(FatalError);
102  }
103  else if
104  (
105  !nConstraints
106  && isA<constrainedOptimisationMethod>(updateMethod_())
107  )
108  {
109  // Does not have constraints but is a constrained optimisation method
111  << "Did not find any adjoint solvers corresponding to "
112  << "constraints but the optimisation method used "
113  << "(" << updateMethod_().type() << ") "
114  << "is a constrainedOptimisationMethod. " << nl << nl
115  << "This can cause some constraintOptimisationMethods to misbehave."
116  << nl << nl
117  << "Either the isConstraint bool is not set in one of the adjoint "
118  << "solvers or you should consider using an updateMethod "
119  << "that is not a constrainedOptimisationMethod"
120  << nl << endl;
121  }
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
126 
128 (
129  fvMesh& mesh,
130  const dictionary& dict,
132 )
133 {
134  const word modelType(dict.subDict("optimisationType").get<word>("type"));
135 
136  Info<< "optimisationType type : " << modelType << endl;
137 
138  auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
139 
140  if (!cstrIter.found())
141  {
143  (
144  dict,
145  "optimisationType",
146  modelType,
147  *dictionaryConstructorTablePtr_
148  ) << exit(FatalIOError);
149  }
150 
152  (
153  cstrIter()(mesh, dict, adjointSolverManagers)
154  );
155 }
156 
157 
158 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
159 
161 {
162  // Compute update of the design variables
163  tmp<scalarField> tcorrection(computeDirection());
164  scalarField& correction = tcorrection.ref();
165 
166  // Update design variables given the correction
168 
169  // If direction has been scaled (say by setting the initial eta), the
170  // old correction has to be updated
172  write();
173 }
174 
175 
177 {
178  // Multiply with line search step, if necessary
180  if (lineSearch_)
181  {
182  correction *= lineSearch_->step();
183  }
184 
185  // Update the design variables
187 }
188 
189 
191 {
192  // Sum contributions for sensitivities and objective/constraint values
193  scalarField objectiveSens;
194  PtrList<scalarField> constraintSens;
195  scalar objectiveValue(Zero);
196  scalarField constraintValues;
197 
199  (
200  objectiveSens,
201  constraintSens,
202  objectiveValue,
203  constraintValues
204  );
205 
206  // Based on the sensitivities, return design variables correction
207  updateMethod_->setObjectiveDeriv(objectiveSens);
208  updateMethod_->setConstraintDeriv(constraintSens);
209  updateMethod_->setObjectiveValue(objectiveValue);
210  updateMethod_->setConstraintValues(constraintValues);
211  tmp<scalarField> tcorrection
212  (
213  new scalarField(objectiveSens.size(), Zero)
214  );
215  scalarField& correction = tcorrection.ref();
216  correction = updateMethod_->returnCorrection();
217 
218  // Compute eta if needed
220 
221  return tcorrection;
222 }
223 
224 
226 (
227  scalarField& objectiveSens,
228  PtrList<scalarField>& constraintSens,
229  scalar& objectiveValue,
230  scalarField& constraintValues
231 )
232 {
233  for (adjointSolverManager& adjSolvManager : adjointSolvManagers_)
234  {
235  const scalar opWeight = adjSolvManager.operatingPointWeight();
236 
237  // Allocate objective sens size if necessary
238  tmp<scalarField> tadjointSolverManagerSens =
239  adjSolvManager.aggregateSensitivities();
240 
241  if (objectiveSens.empty())
242  {
243  objectiveSens.setSize(tadjointSolverManagerSens().size(), Zero);
244  }
245 
246  objectiveSens += opWeight*tadjointSolverManagerSens();
247  objectiveValue += opWeight*adjSolvManager.objectiveValue();
248 
249  // Allocate constraint sens size if necessary
250  PtrList<scalarField> adjointSolverManagerConstSens =
251  adjSolvManager.constraintSensitivities();
252 
253  tmp<scalarField> cValues = adjSolvManager.constraintValues();
254 
255  if (constraintSens.empty())
256  {
257  constraintSens.setSize(adjointSolverManagerConstSens.size());
258  forAll(constraintSens, cI)
259  {
260  constraintSens.set
261  (
262  cI,
263  new scalarField
264  (
265  adjointSolverManagerConstSens[cI].size(),
266  Zero
267  )
268  );
269  constraintValues.setSize(cValues().size());
270  constraintValues = Zero;
271  }
272  }
273 
274  forAll(constraintSens, cI)
275  {
276  constraintSens[cI] += opWeight*adjointSolverManagerConstSens[cI];
277  }
278  constraintValues += opWeight*cValues();
279  }
280 }
281 
282 
284 {
285  // Compute new objective and constraint values and update the ones
286  // in updateMethod
287  scalar objectiveValue(Zero);
288  scalarField constraintValues;
289 
290  for (adjointSolverManager& adjSolvManager : adjointSolvManagers_)
291  {
292  const scalar opWeight = adjSolvManager.operatingPointWeight();
293 
294  objectiveValue += opWeight*adjSolvManager.objectiveValue();
295  tmp<scalarField> cValues = adjSolvManager.constraintValues();
296 
297  if (constraintValues.empty())
298  {
299  constraintValues.setSize(cValues().size(), Zero);
300  }
301  constraintValues += opWeight*cValues();
302  }
303  updateMethod_->setObjectiveValue(objectiveValue);
304  updateMethod_->setConstraintValues(constraintValues);
305 
306  return updateMethod_->computeMeritFunction();
307 }
308 
309 
311 {
312  return updateMethod_->meritFunctionDirectionalDerivative();
313 }
314 
315 
317 {
318  updateMethod_->updateOldCorrection(oldCorrection);
319 }
320 
321 
323 {
324  updateMethod_->write();
325 }
326 
327 
329 {
330  return sourcePtr_;
331 }
332 
333 
335 {
336  return lineSearch_;
337 }
338 
339 
340 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
341 
342 } // End namespace incompressible
343 } // End namespace Foam
344 
345 // ************************************************************************* //
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::incompressible::optimisationType::getLineSearch
autoPtr< lineSearch > & getLineSearch()
Get a reference to the line search object.
Definition: optimisationTypeIncompressible.C:334
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::incompressible::defineTypeNameAndDebug
defineTypeNameAndDebug(adjointEikonalSolver, 0)
Foam::incompressible::optimisationType::meritFunctionDirectionalDerivative
virtual scalar meritFunctionDirectionalDerivative()
Derivative of the merit function.
Definition: optimisationTypeIncompressible.C:310
Foam::incompressible::optimisationType::write
virtual void write()
Write useful quantities to files.
Definition: optimisationTypeIncompressible.C:322
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::incompressible::optimisationType::sourcePtr
const autoPtr< volScalarField > & sourcePtr()
Get source term.
Definition: optimisationTypeIncompressible.C:328
Foam::incompressible::optimisationType::sourcePtr_
autoPtr< volScalarField > sourcePtr_
Definition: optimisationTypeIncompressible.H:68
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::correction
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Foam::PtrList::set
const T * set(const label i) const
Return const pointer to element (can be nullptr),.
Definition: PtrList.H:138
Foam::incompressible::optimisationType::computeDirection
virtual tmp< scalarField > computeDirection()
Compute update direction.
Definition: optimisationTypeIncompressible.C:190
Foam::incompressible::defineRunTimeSelectionTable
defineRunTimeSelectionTable(adjointSensitivity, dictionary)
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:228
FatalIOErrorInLookup
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:406
Foam::incompressible::optimisationType::updateDesignVariables
virtual void updateDesignVariables(scalarField &correction)=0
Update the design variables given their correction.
Foam::Field< scalar >
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::lineSearch::New
static autoPtr< lineSearch > New(const dictionary &dict, const Time &time)
Return a reference to the selected turbulence model.
Definition: lineSearch.C:96
Foam::updateMethod::New
static autoPtr< updateMethod > New(const fvMesh &mesh, const dictionary &dict)
Return a reference to the selected turbulence model.
Definition: updateMethod.C:263
Foam::PtrList::setSize
void setSize(const label newLen)
Same as resize()
Definition: PtrListI.H:105
adjointSolverManagers
PtrList< adjointSolverManager > & adjointSolverManagers
Definition: createFields.H:8
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
Foam::adjointSolverManager
Class for managing adjoint solvers, which may be more than one per operating point.
Definition: adjointSolverManager.H:54
Foam::incompressible::optimisationType::adjointSolvManagers_
PtrList< adjointSolverManager > & adjointSolvManagers_
Definition: optimisationTypeIncompressible.H:66
dict
dictionary dict
Definition: searchingEngine.H:14
constrainedOptimisationMethod.H
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:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:83
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::incompressible::optimisationType::updateMethod_
autoPtr< updateMethod > updateMethod_
Definition: optimisationTypeIncompressible.H:67
Foam::nl
constexpr char nl
Definition: Ostream.H:385
runTimeSelectionTables.H
Macros to ease declaration of run-time selection tables.
Foam::incompressible::optimisationType::computeEta
virtual void computeEta(scalarField &correction)=0
Compute eta if not set in the first step.
Foam::incompressible::optimisationType::updateGradientsAndValues
virtual void updateGradientsAndValues(scalarField &objectiveSens, PtrList< scalarField > &constraintSens, scalar &objectiveValue, scalarField &constraintValues)
Compute cumulative objective and constraint gradients.
Definition: optimisationTypeIncompressible.C:226
Foam::direction
uint8_t direction
Definition: direction.H:52
optimisationTypeIncompressible.H
Foam::incompressible::optimisationType::New
static autoPtr< optimisationType > New(fvMesh &mesh, const dictionary &dict, PtrList< adjointSolverManager > &adjointSolverManagers)
Return a reference to the selected turbulence model.
Definition: optimisationTypeIncompressible.C:128
Foam::incompressible::optimisationType::update
virtual void update()
Update design variables.
Definition: optimisationTypeIncompressible.C:160
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::incompressible::optimisationType::updateOldCorrection
virtual void updateOldCorrection(const scalarField &)
Update old correction. Needed for quasi-Newton Methods.
Definition: optimisationTypeIncompressible.C:316
Foam::incompressible::optimisationType::lineSearch_
autoPtr< lineSearch > lineSearch_
Definition: optimisationTypeIncompressible.H:69
Foam::incompressible::optimisationType::computeMeritFunction
virtual scalar computeMeritFunction()
Compute the merit function of the optimisation problem.
Definition: optimisationTypeIncompressible.C:283