48 const label startTimeIndex,
66 dvUpdate_->getDesignVariables()->storeDesignVariables();
69 scalar meritFunction = dvUpdate_->computeMeritFunction();
71 dvUpdate_->setOldObjectiveValue();
74 scalar dirDerivative =
75 dvUpdate_->meritFunctionDirectionalDerivative();
84 while (lineSrch->
loop())
86 Info<<
"\n- - - - - - - - - - - - - - -" <<
endl;
88 Info<<
"- - - - - - - - - - - - - - -\n" <<
endl;
95 const label startTimeIndex = mesh_.time().timeIndex();
96 const scalar primalEndTime = mesh_.time().endTime().value();
98 solvePrimalEquations();
101 meritFunction = dvUpdate_->computeMeritFunction();
107 clearSensitivities();
110 solveAdjointEquations();
113 dvUpdate_->updateGradientsAndValues();
117 dvUpdate_->meritFunctionDirectionalDerivative();
125 <<
" iterations." <<
endl;
127 dvUpdate_->postUpdate(scaledCorrection);
135 Info<<
"Line search reached max. number of iterations.\n" 136 <<
"Proceeding to the next optimisation cycle" <<
endl;
138 dvUpdate_->postUpdate(scaledCorrection);
144 this->resetTime(
startTime, startTimeIndex, primalEndTime);
145 dvUpdate_->getDesignVariables()->resetDesignVariables();
156 clearSensitivities();
159 solveAdjointEquations();
167 if (shouldUpdateDesignVariables_)
169 moveDesignVariables();
173 solvePrimalEquations();
176 clearSensitivities();
179 solveAdjointEquations();
202 dictionary& primalSolversDict = subDict(
"primalSolvers");
203 const wordList& primalSolverNames = primalSolversDict.
toc();
207 forAll(primalSolvers_, solveri)
210 primalSolversDict.
subDict(primalSolverNames[solveri]);
211 if (primalSolvers_.size() > 1)
213 solverDict.
add<
bool>(
"useSolverNameForFields",
true);
223 primalSolverNames[solveri]
229 const dictionary& adjointManagersDict = subDict(
"adjointManagers");
230 const wordList adjointManagerNames = adjointManagersDict.toc();
231 adjointSolverManagers_.
setSize(adjointManagerNames.size());
236 label nNotNullAdjointSolvers(0);
237 for (
const word& adjManager : adjointManagerNames)
240 adjointManagersDict.subDict(adjManager).subDict(
"adjointSolvers");
241 const wordList adjointSolverNames = adjSolversDict.toc();
242 for (
const word& adjSolver : adjointSolverNames)
244 if (adjSolversDict.subDict(adjSolver).get<word>(
"type") !=
"null")
246 ++nNotNullAdjointSolvers;
251 << nNotNullAdjointSolvers
252 <<
" adjoint solvers that allocate fields" 254 bool overrideUseSolverName(nNotNullAdjointSolvers > 1);
256 forAll(adjointSolverManagers_, manageri)
258 adjointSolverManagers_.set
261 new adjointSolverManager
266 adjointManagersDict.subDict(adjointManagerNames[manageri]),
267 overrideUseSolverName
273 if (primalSolvers_.size() > 1)
275 for (
const primalSolver& solveri : primalSolvers_)
277 if (!solveri.useSolverNameForFields())
280 <<
"Multiple primal solvers are present but " 281 <<
"useSolverNameForFields is set to false in " 282 <<
"primal solver " << solveri.solverName() <<
nl 283 <<
"This is considered fatal." 289 if (nNotNullAdjointSolvers > 1)
291 for (
const adjointSolverManager& amI : adjointSolverManagers_)
293 const PtrList<adjointSolver>& adjointSolvers = amI.adjointSolvers();
294 for (
const adjointSolver& asI : adjointSolvers)
296 if (!asI.useSolverNameForFields())
299 <<
"Multiple adjoint solvers are present but " 300 <<
"useSolverNameForFields is set to false in " 301 <<
"adjoint solver " << asI.solverName() <<
nl 302 <<
"This is considered fatal." 310 designVars_().addFvOptions(primalSolvers_, adjointSolverManagers_);
317 Foam::optimisationManager::optimisationManager(
fvMesh&
mesh)
332 time_(const_cast<
Time&>(
mesh.time())),
333 designVars_(nullptr),
335 adjointSolverManagers_(),
336 managerType_(
get<
word>(
"optimisationManager")),
338 shouldUpdateDesignVariables_(true)
344 if (designVarsDictPtr)
373 Info<<
"optimisationManager type : " << modelType <<
endl;
375 auto* ctorPtr = dictionaryConstructorTable(modelType);
382 "optimisationManager",
384 *dictionaryConstructorTablePtr_
399 const dictionary& primalSolversDict = subDict(
"primalSolvers");
402 sol.readDict(primalSolversDict.
subDict(sol.solverName()));
405 const dictionary& adjointManagersDict = subDict(
"adjointManagers");
408 man.readDict(adjointManagersDict.
subDict(man.managerName()));
413 designVars_->readDict
414 (subDict(
"optimisation").subDict(
"designVariables"));
428 if (dvUpdate_->getLineSearch())
442 forAll(primalSolvers_, psI)
444 primalSolvers_[psI].solve();
452 forAll(adjointSolverManagers_, amI)
454 adjointSolverManagers_[amI].solveAdjointEquations();
462 forAll(adjointSolverManagers_, amI)
464 adjointSolverManagers_[amI].computeAllSensitivities();
471 for (adjointSolverManager& adjSolvManager : adjointSolverManagers_)
473 adjSolvManager.clearSensitivities();
480 forAll(adjointSolverManagers_, amI)
482 PtrList<adjointSolver>& adjointSolvers =
483 adjointSolverManagers_[amI].adjointSolvers();
485 forAll(adjointSolvers, asI)
487 adjointSolvers[asI].updatePrimalBasedQuantities();
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
static autoPtr< optimisationManager > New(fvMesh &mesh)
Return a reference to the selected turbulence model.
void size(const label n)
Older name for setAddressableSize.
void setDirection(const scalarField &direction)
Set direction.
void fixedStepUpdate()
Update design variables using a fixed step.
static autoPtr< primalSolver > New(fvMesh &mesh, const word &managerType, const dictionary &dict, const word &solverName)
Return a reference to the selected primal solver.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual void updatePrimalBasedQuantities()
Solve all primal equations.
virtual bool read()
Read object.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
virtual void updateStep()=0
Update the line search step based on the specific line search strategy, e.g. bisection, quadratic fit, etc.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
fvMesh & mesh_
Reference to the mesh.
Base class for primal solvers.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Abstract base class for optimisation methods.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Ignore writing from objectRegistry::writeObject()
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
void setNewMeritValue(const scalar value)
Set new objective value.
const Time & time() const
Return the top-level database.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
virtual void setNewDeriv(const scalar deriv)
Set new directional derivative.
virtual void initialize()
Initialization. Construct primal and adjoint solvers.
virtual void setDeriv(const scalar deriv)
Set directional derivative.
wordList toc() const
Return the table of contents.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
#define forAll(list, i)
Loop across all elements in list.
void setSize(const label n)
Alias for resize()
label innerIter() const
Get inner line search iteration.
A class for handling words, derived from Foam::string.
void setOldMeritValue(const scalar value)
Set old objective value.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word & system() const noexcept
Return system name.
void lineSearchUpdate()
Update design variables using a line-search.
virtual void reset()
Reset step to initial value.
virtual void resetTime(const dimensionedScalar startTime, const label startTimeIndex, const scalar endTime)
Reset time.
virtual void moveDesignVariables()
Update design variables.
autoPtr< designVariables > designVars_
Design variables of the optimisation problem.
virtual void computeSensitivities()
Compute all adjoint sensitivities.
scalar step() const
Get current step.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
defineTypeNameAndDebug(combustionModel, 0)
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Find and return a sub-dictionary as a copy, otherwise return an empty dictionary. ...
virtual void solveAdjointEquations()
Solve all adjoint equations.
List< word > wordList
List of word.
Class for managing adjoint solvers, which may be more than one per operating point.
Mesh data needed to do the Finite Volume discretisation.
static autoPtr< designVariables > New(fvMesh &mesh, const dictionary &dict)
Return a reference to the selected design variables.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual void clearSensitivities()
Clear all adjoint sensitivities.
virtual bool loop()
Return true if lineSearch should continue and if so increment inner.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
A class for managing temporary objects.
Defines the attributes of an object for which implicit objectRegistry management is supported...
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
virtual bool read()
Changes in case of run-time update of optimisationDict.
label maxIters() const
Get max number of iterations.
virtual bool converged()=0
Return the correction of the design variables.
Do not request registration (bool: false)
virtual void solvePrimalEquations()
Solve all primal equations.
virtual void updateDesignVariables()
Update design variables.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
virtual bool computeGradient() const
Does line search need to update the gradient?