Loading...
Searching...
No Matches
DBFGS.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-2023 PCOpt/NTUA
9 Copyright (C) 2013-2023 FOSS GP
10 Copyright (C) 2019-2020 OpenCFD Ltd.
11-------------------------------------------------------------------------------
12License
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
30#include "DBFGS.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
39 (
41 DBFGS,
43 );
44}
45
46
47// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
48
50{
51 // Vectors needed to construct the inverse Hessian matrix
56
57 scalar ys = globalSum(s*y);
58 if (counter_ == 1 && scaleFirstHessian_)
59 {
60 if (ys > scalar(0))
61 {
62 scalar scaleFactor = ys/globalSum(y*y);
63 Info<< "Scaling Hessian with factor " << scaleFactor << endl;
65 {
66 Hessian_()[varI][varI] /= scaleFactor;
67 }
68 }
69 else
70 {
72 << "y*s is negative. Skipping the scaling of the first Hessian"
73 << endl;
74 }
75 }
76
77 scalar sBs = globalSum(leftMult(s, Hessian_())*s);
78
79 // Check curvature condition and apply dampening is necessary
80 scalar theta(1);
81 if (ys < gamma_*sBs)
82 {
84 << " y*s is below threshold. Using damped form" << endl;
85 theta = (scalar(1)-gamma_)*sBs/(sBs - ys);
86 }
87
89 << "Hessian curvature index " << ys << endl;
90
91 scalarField r(theta*y + (scalar(1)-theta)*rightMult(Hessian_(), s));
92
93 // Construct the inverse Hessian
94 Hessian_() +=
96 + outerProd(r, r/globalSum(s*r));
97}
98
99
101{
102 SquareMatrix<scalar> HessianInv = inv(Hessian_());
103
104 // In the first few iterations, use steepest descent but update the Hessian
105 // matrix
106 if (counter_ < nSteepestDescent_)
107 {
108 Info<< "Using steepest descent to update design variables" << endl;
109 for (const label varI : activeDesignVars_)
110 {
111 correction_[varI] = -eta_*objectiveDerivatives_[varI];
112 }
113 }
114 // Else use DBFGS formula to update design variables
115 else
116 {
117 // Compute correction for active design variables
118 scalarField activeDerivs(activeDesignVars_.size(), Zero);
119 activeDerivs.map(objectiveDerivatives_, activeDesignVars_);
120 scalarField activeCorrection
121 (
122 -etaHessian_*rightMult(HessianInv, activeDerivs)
123 );
124
125 // Transfer correction to the global list
126 correction_ = Zero;
127 forAll(activeDesignVars_, varI)
128 {
129 correction_[activeDesignVars_[varI]] = activeCorrection[varI];
130 }
131 }
132
133 // Store fields for the next iteration
136}
137
138
139// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
140
141Foam::DBFGS::DBFGS
142(
143 const fvMesh& mesh,
144 const dictionary& dict,
145 autoPtr<designVariables>& designVars,
146 const label nConstraints,
147 const word& type
148)
149:
150 quasiNewton(mesh, dict, designVars, nConstraints, type),
151 curvatureThreshold_
152 (
153 coeffsDict(type).getOrDefault<scalar>("curvatureThreshold", 1e-10)
154 ),
155 gamma_(coeffsDict(type).getOrDefault<scalar>("gamma", 0.2))
156{
158}
159
160
161// ************************************************************************* //
scalar y
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
The quasi-Newton BFGS formula with the dampening proposed by Powell.
Definition DBFGS.H:52
scalar curvatureThreshold_
Curvature threshold.
Definition DBFGS.H:60
scalar gamma_
Threshold for damping.
Definition DBFGS.H:65
void update()
Update design variables.
Definition DBFGS.C:93
void updateHessian()
Update approximation of the inverse Hessian.
Definition DBFGS.C:42
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition Field.C:302
A templated (N x N) square matrix of objects of <Type>, containing N*N elements, derived from Matrix.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
Base class for quasi-Newton methods.
Definition quasiNewton.H:52
scalarField correctionOld_
The previous correction.
Definition quasiNewton.H:88
autoPtr< SquareMatrix< scalar > > Hessian_
The Hessian or its inverse, depending on the deriving class.
Definition quasiNewton.H:78
label nSteepestDescent_
Number of first steepest descent steps.
Definition quasiNewton.H:65
scalar etaHessian_
Step for the Newton method.
Definition quasiNewton.H:60
bool scaleFirstHessian_
Scale the initial unitary Hessian approximation.
Definition quasiNewton.H:70
scalarField derivativesOld_
The previous derivatives.
Definition quasiNewton.H:83
void allocateHessian()
Allocate the Hessian matrix.
Definition quasiNewton.C:35
Abstract base class for optimisation methods.
scalarField objectiveDerivatives_
Derivatives of the objective functions.
scalarField correction_
Design variables correction.
dictionary coeffsDict(const word &type) const
Return optional dictionary with parameters specific to each method.
scalar globalSum(const scalarField &field)
Compute either global or local sum, based on globalSum flag.
const scalarField leftMult(const scalarField &, const SquareMatrix< scalar > &)
const labelList & activeDesignVars_
Map to active design variables.
const scalarField rightMult(const SquareMatrix< scalar > &, const scalarField &)
label counter_
Optimisation cycle count.
label nConstraints() const
Get the number of constraints.
scalar eta_
Step multiplying the correction.
SquareMatrix< scalar > outerProd(const scalarField &, const scalarField &)
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
dynamicFvMesh & mesh
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
dictionary dict
volScalarField & e
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299