ENH: added a normalisation mechanism in MMA

The derivatives of the objective and constraint functions can optionally
be normalised in each optimisation cycle, so that MMA does not put an
excesive stress on the constraints, which can negatively affect the
course of the optimisation
This commit is contained in:
Vaggelis Papoutsis
2023-10-04 13:15:13 +03:00
committed by Andrew Heather
parent adaac7257f
commit 6020fabcdd
4 changed files with 83 additions and 3 deletions

View File

@ -204,6 +204,9 @@ public:
//- been set
inline bool isMaxInitChangeSet() const;
//- Get maxInitChange
inline const autoPtr<scalar>& getMaxInitChange();
//- Set maxInitChange
inline void setMaxInitChange(const scalar maxInitChange);

View File

@ -41,6 +41,12 @@ bool Foam::designVariables::isMaxInitChangeSet() const
}
const Foam::autoPtr<Foam::scalar>& Foam::designVariables::getMaxInitChange()
{
return maxInitChange_;
}
void Foam::designVariables::setMaxInitChange(const scalar maxInitChange)
{
maxInitChange_.reset(new scalar(maxInitChange));

View File

@ -208,8 +208,8 @@ void Foam::MMA::updateBounds()
}
else
{
lower_ = x - 0.5*span;
upper_ = x + 0.5*span;
lower_ = x - sInit_*span;
upper_ = x + sInit_*span;
}
a_ = max(xMin, lower_ + 0.1*(x - lower_));
@ -825,6 +825,42 @@ Foam::tmp<Foam::scalarField> Foam::MMA::computeResiduals()
}
void Foam::MMA::normalise()
{
if (normalise_)
{
// Compute normalisation factors
if (!Jnorm_ || continuousNormalisation_)
{
scalarField activeSens(objectiveDerivatives_, activeDesignVars_);
Jnorm_.reset(new scalar(Foam::sqrt(globalSum(sqr(activeSens)))));
Cnorm_.reset(new scalarField(cValues_.size(), Zero));
scalarField& Cnorm = Cnorm_.ref();
forAll(constraintDerivatives_, cI)
{
scalarField activeConstrSens
(constraintDerivatives_[cI], activeDesignVars_);
Cnorm[cI] = Foam::sqrt(globalSum(sqr(activeConstrSens)));
}
Info<< "Computed normalisation factors " << nl
<< "J: " << Jnorm_() << nl
<< "C: " << Cnorm_() << endl;
}
// Normalise objective values and gradients
objectiveValue_ /= Jnorm_() + SMALL;
objectiveDerivatives_ /= Jnorm_() + SMALL;
// Normalise constraint values and gradients
cValues_ *= cw_/(Cnorm_() + SMALL);
forAll(constraintDerivatives_, cI)
{
constraintDerivatives_[cI] *= cw_/(Cnorm_()[cI] + SMALL);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::MMA::MMA
@ -882,6 +918,7 @@ Foam::MMA::MMA
(coeffsDict(type).getOrDefault<bool>("initializeEverySubproblem", false)),
asymDecr_(coeffsDict(type).getOrDefault<scalar>("asymptoteDecrease", 0.7)),
asymIncr_(coeffsDict(type).getOrDefault<scalar>("asymptoteIncrease", 1.2)),
sInit_(coeffsDict(type).getOrDefault<scalar>("sInit", 0.5)),
move_(coeffsDict(type).getOrDefault<scalar>("move", 0.5)),
raa0_(coeffsDict(type).getOrDefault<scalar>("raa0", 1.e-05)),
maxInitRhoMult_(coeffsDict(type).getOrDefault<scalar>("maxInitRhoMult", 0.1)),
@ -890,7 +927,13 @@ Foam::MMA::MMA
dynamicRhoInitialisation_
(coeffsDict(type).getOrDefault<bool>("dynamicRhoInitialisation", false)),
dynamicRhoMult_
(coeffsDict(type).getOrDefault<scalar>("dynamicRhoMult", 0.1))
(coeffsDict(type).getOrDefault<scalar>("dynamicRhoMult", 0.1)),
normalise_(coeffsDict(type).getOrDefault<bool>("normalise", false)),
continuousNormalisation_
(coeffsDict(type).getOrDefault<bool>("continuousNormalisation", false)),
Jnorm_(nullptr),
Cnorm_(nullptr),
cw_(coeffsDict(type).getOrDefault<scalar>("constraintWeight", 1))
{
// Check that the design variables bounds have been set
if (!designVars().lowerBounds() || !designVars().upperBounds())
@ -927,6 +970,9 @@ void Foam::MMA::computeCorrection()
// Update sizes of fields related to the active design variables
updateSizes();
// Perform normalisation of the objective and constraint values
normalise();
// Initialize rho values in the p,q functions
// These determine how aggressive or conservative the method will be
initializeRho();

View File

@ -200,6 +200,9 @@ protected:
//- Upper assymprote increase rate
scalar asymIncr_;
//- Used to update the assymptotes in the first optimisation cycle
scalar sInit_;
//- Movement of the unatainable upper and lower bounds
scalar move_;
@ -228,6 +231,24 @@ protected:
scalar dynamicRhoMult_;
// Normalisation based on the gradient
//- Perform the normalisation
bool normalise_;
//- Perform the normalisation in each optimisation cycle
bool continuousNormalisation_;
//- Normalisation factor for the objective
autoPtr<scalar> Jnorm_;
//- Normalisation factors for the constraints
tmp<scalarField> Cnorm_;
//- Constaint weight after the normalisation
scalar cw_;
// Protected Member Functions
//- Update sizes of fields related to the active design variables
@ -336,6 +357,10 @@ protected:
tmp<scalarField> computeResiduals();
//- Normalise the objective and constraints if necessary
void normalise();
private:
// Private Member Functions