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 dvUpdate_->checkConvergence();
179 clearSensitivities();
182 solveAdjointEquations();
205 dictionary& primalSolversDict = subDict(
"primalSolvers");
206 const wordList& primalSolverNames = primalSolversDict.
toc();
210 forAll(primalSolvers_, solveri)
213 primalSolversDict.
subDict(primalSolverNames[solveri]);
214 if (primalSolvers_.size() > 1)
216 solverDict.
add<
bool>(
"useSolverNameForFields",
true);
226 primalSolverNames[solveri]
232 const dictionary& adjointManagersDict = subDict(
"adjointManagers");
233 const wordList adjointManagerNames = adjointManagersDict.toc();
234 adjointSolverManagers_.
setSize(adjointManagerNames.size());
239 label nNotNullAdjointSolvers(0);
240 for (
const word& adjManager : adjointManagerNames)
243 adjointManagersDict.subDict(adjManager).subDict(
"adjointSolvers");
244 const wordList adjointSolverNames = adjSolversDict.toc();
245 for (
const word& adjSolver : adjointSolverNames)
247 if (adjSolversDict.subDict(adjSolver).get<word>(
"type") !=
"null")
249 ++nNotNullAdjointSolvers;
254 << nNotNullAdjointSolvers
255 <<
" adjoint solvers that allocate fields" 257 bool overrideUseSolverName(nNotNullAdjointSolvers > 1);
259 forAll(adjointSolverManagers_, manageri)
261 adjointSolverManagers_.set
264 new adjointSolverManager
269 adjointManagersDict.subDict(adjointManagerNames[manageri]),
270 overrideUseSolverName
276 if (primalSolvers_.size() > 1)
278 for (
const primalSolver& solveri : primalSolvers_)
280 if (!solveri.useSolverNameForFields())
283 <<
"Multiple primal solvers are present but " 284 <<
"useSolverNameForFields is set to false in " 285 <<
"primal solver " << solveri.solverName() <<
nl 286 <<
"This is considered fatal." 292 if (nNotNullAdjointSolvers > 1)
294 for (
const adjointSolverManager& amI : adjointSolverManagers_)
296 const PtrList<adjointSolver>& adjointSolvers = amI.adjointSolvers();
297 for (
const adjointSolver& asI : adjointSolvers)
299 if (!asI.useSolverNameForFields())
302 <<
"Multiple adjoint solvers are present but " 303 <<
"useSolverNameForFields is set to false in " 304 <<
"adjoint solver " << asI.solverName() <<
nl 305 <<
"This is considered fatal." 313 designVars_().addFvOptions(primalSolvers_, adjointSolverManagers_);
320 Foam::optimisationManager::optimisationManager(
fvMesh&
mesh)
335 time_(const_cast<
Time&>(
mesh.time())),
336 designVars_(nullptr),
338 adjointSolverManagers_(),
339 managerType_(
get<
word>(
"optimisationManager")),
341 shouldUpdateDesignVariables_(true)
347 if (designVarsDictPtr)
376 Info<<
"optimisationManager type : " << modelType <<
endl;
378 auto* ctorPtr = dictionaryConstructorTable(modelType);
385 "optimisationManager",
387 *dictionaryConstructorTablePtr_
402 const dictionary& primalSolversDict = subDict(
"primalSolvers");
405 sol.readDict(primalSolversDict.
subDict(sol.solverName()));
408 const dictionary& adjointManagersDict = subDict(
"adjointManagers");
411 man.readDict(adjointManagersDict.
subDict(man.managerName()));
416 designVars_->readDict
417 (subDict(
"optimisation").subDict(
"designVariables"));
431 if (dvUpdate_->getLineSearch())
445 forAll(primalSolvers_, psI)
447 primalSolvers_[psI].solve();
455 forAll(adjointSolverManagers_, amI)
457 adjointSolverManagers_[amI].solveAdjointEquations();
465 forAll(adjointSolverManagers_, amI)
467 adjointSolverManagers_[amI].computeAllSensitivities();
474 for (adjointSolverManager& adjSolvManager : adjointSolverManagers_)
476 adjSolvManager.clearSensitivities();
483 forAll(adjointSolverManagers_, amI)
485 PtrList<adjointSolver>& adjointSolvers =
486 adjointSolverManagers_[amI].adjointSolvers();
488 forAll(adjointSolvers, asI)
490 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?