Merge branch 'fix-opt-convergence-criteria' into 'master'
BUG: optimisation convergence criteria misbehave w/o a line search (fixes #3268) Closes #3268 See merge request Development/openfoam!709
This commit is contained in:
commit
b9335f4989
@ -136,82 +136,6 @@ void Foam::designVariablesUpdate::writeToCostFile(bool zeroAdjointSolns)
|
||||
}
|
||||
|
||||
|
||||
void Foam::designVariablesUpdate::checkConvergence
|
||||
(
|
||||
const scalarField& oldCorrection
|
||||
)
|
||||
{
|
||||
bool converged(false);
|
||||
// Design variables convergence check
|
||||
if (designVarsThreshold_)
|
||||
{
|
||||
const labelList& activeVarIDs =
|
||||
designVars_->activeDesignVariables();
|
||||
const scalarField correction(oldCorrection, activeVarIDs);
|
||||
const scalarField activeVars(designVars_->getVars(), activeVarIDs);
|
||||
const scalar scaledCorrection =
|
||||
gMax(mag(correction)/(mag(activeVars) + SMALL));
|
||||
DebugInfo
|
||||
<< "Current correction " << correction << nl
|
||||
<< "Active vars " << activeVars << endl;
|
||||
Info<< "Max. scaled correction of the design variables = "
|
||||
<< scaledCorrection
|
||||
<< endl;
|
||||
if (scaledCorrection < designVarsThreshold_())
|
||||
{
|
||||
Info<< tab << "Design variables have converged " << endl;
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
// Objective convergence check
|
||||
if (objectiveThreshold_)
|
||||
{
|
||||
const scalar newObjective = computeObjectiveValue();
|
||||
const scalar oldObjective = updateMethod_->getObjectiveValueOld();
|
||||
const scalar relativeUpdate =
|
||||
mag(newObjective - oldObjective)/(mag(oldObjective) + SMALL);
|
||||
Info<< "Relative change of the objective value = "
|
||||
<< relativeUpdate
|
||||
<< endl;
|
||||
if (relativeUpdate < objectiveThreshold_())
|
||||
{
|
||||
Info<< tab << "Objective function has converged " << endl;
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
// Feasibility check
|
||||
const scalarField& constraints = updateMethod_->getConstraintValues();
|
||||
const scalar feasibility = sum(pos(constraints)*constraints);
|
||||
Info<< "Feasibility = " << feasibility << endl;
|
||||
if (converged && feasibility < feasibilityThreshold_)
|
||||
{
|
||||
Info<< "Stopping criteria met and all constraints satisfied." << nl
|
||||
<< "Optimisation has converged, stopping ..." << nl << nl
|
||||
<< "End" << nl
|
||||
<< endl;
|
||||
// Force writing of all objective and constraint functions, to get
|
||||
// the converged results to files
|
||||
for (adjointSolverManager& am : adjointSolvManagers_)
|
||||
{
|
||||
for (adjointSolver& as : am.adjointSolvers())
|
||||
{
|
||||
// Use dummy weighted objective
|
||||
as.getObjectiveManager().writeObjectives();
|
||||
}
|
||||
}
|
||||
writeToCostFile(true);
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
UPstream::exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::designVariablesUpdate::designVariablesUpdate
|
||||
@ -570,10 +494,86 @@ void Foam::designVariablesUpdate::postUpdate(const scalarField& oldCorrection)
|
||||
}
|
||||
}
|
||||
}
|
||||
checkConvergence();
|
||||
}
|
||||
if (convergenceCriteriaDefined_)
|
||||
}
|
||||
|
||||
|
||||
void Foam::designVariablesUpdate::checkConvergence()
|
||||
{
|
||||
checkConvergence(oldCorrection);
|
||||
if (!convergenceCriteriaDefined_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool converged(false);
|
||||
const scalarField& oldCorrection = updateMethod_->returnCorrection();
|
||||
// Design variables convergence check
|
||||
if (designVarsThreshold_)
|
||||
{
|
||||
const labelList& activeVarIDs =
|
||||
designVars_->activeDesignVariables();
|
||||
const scalarField correction(oldCorrection, activeVarIDs);
|
||||
const scalarField activeVars(designVars_->getVars(), activeVarIDs);
|
||||
const scalar scaledCorrection =
|
||||
gMax(mag(correction)/(mag(activeVars) + SMALL));
|
||||
DebugInfo
|
||||
<< "Current correction " << correction << nl
|
||||
<< "Active vars " << activeVars << endl;
|
||||
Info<< "Max. scaled correction of the design variables = "
|
||||
<< scaledCorrection
|
||||
<< endl;
|
||||
if (scaledCorrection < designVarsThreshold_())
|
||||
{
|
||||
Info<< tab << "Design variables have converged " << endl;
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
// Objective convergence check
|
||||
if (objectiveThreshold_ && updateMethod_->getObjectiveValueOld())
|
||||
{
|
||||
const scalar newObjective = computeObjectiveValue();
|
||||
const scalar oldObjective = updateMethod_->getObjectiveValueOld()();
|
||||
const scalar relativeUpdate =
|
||||
mag(newObjective - oldObjective)/(mag(oldObjective) + SMALL);
|
||||
Info<< "Relative change of the objective value = "
|
||||
<< relativeUpdate
|
||||
<< endl;
|
||||
if (relativeUpdate < objectiveThreshold_())
|
||||
{
|
||||
Info<< tab << "Objective function has converged " << endl;
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
// Feasibility check
|
||||
const scalarField& constraints = updateMethod_->getConstraintValues();
|
||||
const scalar feasibility = sum(pos(constraints)*constraints);
|
||||
Info<< "Feasibility = " << feasibility << endl;
|
||||
if (converged && feasibility < feasibilityThreshold_)
|
||||
{
|
||||
Info<< "Stopping criteria met and all constraints satisfied." << nl
|
||||
<< "Optimisation has converged, stopping ..." << nl << nl
|
||||
<< "End" << nl
|
||||
<< endl;
|
||||
// Force writing of all objective and constraint functions, to get
|
||||
// the converged results to files
|
||||
for (adjointSolverManager& am : adjointSolvManagers_)
|
||||
{
|
||||
for (adjointSolver& as : am.adjointSolvers())
|
||||
{
|
||||
// Use dummy weighted objective
|
||||
as.getObjectiveManager().writeObjectives();
|
||||
}
|
||||
}
|
||||
writeToCostFile(true);
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
UPstream::exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,11 +138,6 @@ protected:
|
||||
//- Write to cost file
|
||||
void writeToCostFile(bool zeroAdjointSolns = false);
|
||||
|
||||
//- Check if the optimisation loop has converged based on the provided
|
||||
//- criteria
|
||||
// May terminate the program
|
||||
void checkConvergence(const scalarField& oldCorrection);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -216,6 +211,11 @@ public:
|
||||
//- in the fixedStep approach
|
||||
void postUpdate(const scalarField& oldCorrection);
|
||||
|
||||
//- Check if the optimisation loop has converged based on the provided
|
||||
//- criteria
|
||||
// May terminate the program
|
||||
void checkConvergence();
|
||||
|
||||
//- Get access to design variables
|
||||
inline autoPtr<designVariables>& getDesignVariables()
|
||||
{
|
||||
|
@ -172,6 +172,9 @@ void Foam::optimisationManager::fixedStepUpdate()
|
||||
// Solve primal equations
|
||||
solvePrimalEquations();
|
||||
|
||||
// Check the convergence criteria of the optimisation loop
|
||||
dvUpdate_->checkConvergence();
|
||||
|
||||
// Reset adjoint sensitivities in all adjoint solver managers
|
||||
clearSensitivities();
|
||||
|
||||
|
@ -237,7 +237,7 @@ Foam::updateMethod::updateMethod
|
||||
objectiveDerivatives_(designVars().getVars().size(), Zero),
|
||||
constraintDerivatives_(0),
|
||||
objectiveValue_(0),
|
||||
objectiveValueOld_(0),
|
||||
objectiveValueOld_(nullptr),
|
||||
cValues_(0),
|
||||
correction_(readOrZeroField("correction", designVars().getVars().size())),
|
||||
cumulativeCorrection_(0),
|
||||
@ -334,7 +334,11 @@ void Foam::updateMethod::setObjectiveValue(const scalar value)
|
||||
|
||||
void Foam::updateMethod::setObjectiveValueOld(const scalar value)
|
||||
{
|
||||
objectiveValueOld_ = value;
|
||||
if (!objectiveValueOld_)
|
||||
{
|
||||
objectiveValueOld_.reset(new scalar(Zero));
|
||||
}
|
||||
objectiveValueOld_.ref() = value;
|
||||
}
|
||||
|
||||
|
||||
@ -350,7 +354,8 @@ Foam::scalar Foam::updateMethod::getObjectiveValue() const
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::updateMethod::getObjectiveValueOld() const
|
||||
const Foam::autoPtr<Foam::scalar>&
|
||||
Foam::updateMethod::getObjectiveValueOld() const
|
||||
{
|
||||
return objectiveValueOld_;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ protected:
|
||||
|
||||
//- Old objective value
|
||||
// Used for convergence checking
|
||||
scalar objectiveValueOld_;
|
||||
autoPtr<scalar> objectiveValueOld_;
|
||||
|
||||
//- Constraint values
|
||||
scalarField cValues_;
|
||||
@ -239,7 +239,7 @@ public:
|
||||
scalar getObjectiveValue() const;
|
||||
|
||||
//- Get old objective value
|
||||
scalar getObjectiveValueOld() const;
|
||||
const autoPtr<scalar>& getObjectiveValueOld() const;
|
||||
|
||||
//- Get values of constraints
|
||||
const scalarField& getConstraintValues() const;
|
||||
|
Loading…
Reference in New Issue
Block a user