76 if (counter_ > nPrevSteps_)
80 newOrder[0] = nPrevSteps_ - 1;
81 for (label i = 1; i < nPrevSteps_; ++i)
85 list.reorder(newOrder);
88 list[nPrevSteps_ - 1] =
f;
106 (derivatives.size() != derivativesOld.size())
107 || (derivatives.size() != designVars_().getVars().size())
111 <<
"Sizes of input derivatives and design variables do not match"
117 scalarField yRecent(derivatives - derivativesOld, activeDesignVars_);
120 scalarField sActive(correctionOld_, activeDesignVars_);
130 const scalar sy(globalSum(
s*
y));
133 const scalarField Hy(invHessianVectorProduct(
y, counter_ - 1));
134 const scalar yHy(globalSum(
y*Hy));
139 <<
"y*s is below threshold. Using damped form" <<
nl
140 <<
"sy, yHy " << sy <<
" " << yHy <<
endl;
142 theta = 0.8*yHy/(yHy - sy);
144 s = theta*
s + (1 - theta)*Hy;
146 else if (useYDamping_)
148 const scalarField Bs(HessianVectorProduct(
s, counter_ - 1));
149 const scalar sBs(globalSum(
s*Bs));
154 <<
"y*s is below threshold. Using damped form" <<
nl
155 <<
"sy, sBs " << sy <<
" " << sBs <<
endl;
157 theta = 0.8*sBs/(sBs - sy);
159 y = theta*
y + (1 - theta)*Bs;
162 <<
"Curvature index (sy) is " << sy <<
endl;
184 label nv = designVars_().getVars().size();
185 label nav = activeDesignVars_.size();
190 else if (
vector.size() == nav)
197 <<
"Size of input vector "
198 <<
"(" <<
vector.size() <<
") "
199 <<
"is equal to neither the number of design variabes "
201 <<
" nor that of the active design variables "
210 label nSteps(
min(counter, nPrevSteps_));
211 label nLast(nSteps - 1);
214 for (label i = nLast; i > -1; --i)
216 r[i] = 1./globalSum(y_[i]*s_[i]);
217 a[i] = r[i]*globalSum(s_[i]*q);
222 globalSum(y_[nLast]*y_[nLast])/globalSum(y_[nLast]*s_[nLast]);
233 for (label i = 0; i < nSteps; ++i)
235 b = r[i]*globalSum(y_[i]*q);
236 q += s_[i]*(a[i] -
b);
268 if (
vector.size() == designVars_().getVars().size())
272 else if (
vector.size() == activeDesignVars_.size())
279 <<
"Size of input vector is equal to neither the number of "
280 <<
" design variabes nor that of the active design variables"
286 const label nSteps(
min(counter, nPrevSteps_));
287 const label nLast(nSteps - 1);
289 globalSum(y_[nLast]*y_[nLast])/globalSum(y_[nLast]*s_[nLast]);
293 for (label i = 0; i < nSteps; ++i)
295 SKsource[i] =
delta*globalSum(s_[i]*source);
296 SKsource[i + nSteps] = globalSum(y_[i]*source);
301 for (label i = 0; i < nSteps; ++i)
304 M[nSteps + i][nSteps + i] = - globalSum(s_[i]*y_[i]);
306 for (label j = 0; j < nSteps; ++j)
308 M[i][j] =
delta*globalSum(s_[i]*s_[j]);
313 for (label j = 0; j < nSteps; ++j)
315 for (label i = j + 1; i < nSteps; ++i)
317 scalar value = globalSum(s_[i]*y_[j]);
318 M[i][j + nSteps] = value;
319 M[j + nSteps][i] = value;
331 for (label j = 0; j < nSteps; ++j)
334 delta*s_[j][i]*invMSource[j]
335 + y_[j][i]*invMSource[j + nSteps];
353 const label
n(activeDesignVars_.size());
359 const label nSteps(
min(counter_, nPrevSteps_));
360 const label nLast(nSteps - 1);
362 globalSum(y_[nLast]*y_[nLast])/globalSum(y_[nLast]*s_[nLast]);
366 SquareMatrix<scalar>
M(2*nSteps, 2*nSteps,
Zero);
367 for (label i = 0; i < nSteps; ++i)
370 M[nSteps + i][nSteps + i] = - globalSum(s_[i]*y_[i]);
372 for (label j = 0; j < nSteps; ++j)
374 M[i][j] =
delta*globalSum(s_[i]*s_[j]);
379 for (label j = 0; j < nSteps; ++j)
381 for (label i = j + 1; i < nSteps; ++i)
383 scalar value = globalSum(s_[i]*y_[j]);
384 M[i][j + nSteps] = value;
385 M[j + nSteps][i] = value;
394 for (label
k = 0;
k <
n; ++
k)
396 for (label i = 0; i < 2*nSteps; ++i)
398 for (label j = 0; j < nSteps; ++j)
402 + invM[i][j + nSteps]*y_[j][
k];
410 for (label
k = 0;
k <
n; ++
k)
412 for (label j = 0; j < nSteps; ++j)
415 delta*s_[j][
k]*MR[j][
k] + y_[j][
k]*MR[j + nSteps][
k];
443 if (
vector.size() == designVars_().getVars().size())
447 else if (
vector.size() == activeDesignVars_.size())
454 <<
"Size of input vector is equal to neither the number of "
455 <<
" design variabes nor that of the active design variables"
461 const label nSteps(
min(counter, nPrevSteps_));
462 const label nLast(nSteps - 1);
464 globalSum(y_[nLast]*y_[nLast])/globalSum(y_[nLast]*s_[nLast]);
468 for (label i = 0; i < nSteps; ++i)
470 YBSsource[i] = globalSum((y_[i] -
delta*s_[i])*source);
475 for (label i = 0; i < nSteps; ++i)
478 M[i][i] += globalSum(s_[i]*y_[i]);
480 for (label j = 0; j < nSteps; ++j)
482 M[i][j] -=
delta*globalSum(s_[i]*s_[j]);
487 for (label j = 0; j < nSteps; ++j)
489 for (label i = j + 1; i < nSteps; ++i)
491 scalar value = globalSum(s_[i]*y_[j]);
499 scalarField invMSource(rightMult(invM, YBSsource));
505 for (label j = 0; j < nSteps; ++j)
507 q[i] += (y_[j][i] -
delta*s_[j][i])*invMSource[j];
525 const label
n(activeDesignVars_.size());
531 const label nSteps(
min(counter_, nPrevSteps_));
532 const label nLast(nSteps - 1);
534 globalSum(y_[nLast]*y_[nLast])/globalSum(y_[nLast]*s_[nLast]);
538 SquareMatrix<scalar>
M(nSteps, nSteps,
Zero);
539 for (label i = 0; i < nSteps; ++i)
542 M[i][i] += globalSum(s_[i]*y_[i]);
544 for (label j = 0; j < nSteps; ++j)
546 M[i][j] -=
delta*globalSum(s_[i]*s_[j]);
551 for (label j = 0; j < nSteps; ++j)
553 for (label i = j + 1; i < nSteps; ++i)
555 scalar value = globalSum(s_[i]*y_[j]);
564 for (label
k = 0;
k <
n; ++
k)
566 for (label i = 0; i < nSteps; ++i)
568 for (label j = 0; j < nSteps; ++j)
570 MR[i][
k] += invM[i][j]*(y_[j][
k] -
delta*s_[j][
k]);
578 for (label
k = 0;
k <
n; ++
k)
580 for (label j = 0; j < nSteps; ++j)
601 if (counter_ < nSteepestDescent_)
603 Info<<
"Using steepest descent to update design variables" <<
endl;
604 for (
const label varI : activeDesignVars_)
606 correction_[varI] = -eta_*objectiveDerivatives_[varI];
612 scalarField q(invHessianVectorProduct(objectiveDerivatives_));
613 forAll(activeDesignVars_, varI)
615 correction_[activeDesignVars_[varI]] = -etaHessian_*q[varI];
632 const label nConstraints,
637 nPrevSteps_(coeffsDict(
type).getOrDefault<label>(
"nPrevSteps", 10)),
640 useSDamping_(coeffsDict(
type).getOrDefault<bool>(
"useSDamping", false)),
641 useYDamping_(coeffsDict(
type).getOrDefault<bool>(
"useYDamping", false))
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
label size() const noexcept
The number of elements in list.
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
The quasi-Newton Limited-memory BFGS formula. Keeps nPrevSteps_ of the y and s vectors and approximat...
PtrList< scalarField > y_
The previous differences of derivatives. Holds nPrevSteps_ fields.
void pivotFields(PtrList< scalarField > &list, const scalarField &f)
Move pointers in PtrList to the left and replace last element with given field.
void applyDamping(scalarField &y, scalarField &s)
Use the damped version of s to ensure positive-definitiveness.
void updateVectors(const scalarField &derivatives, const scalarField &derivativesOld)
Update y and s vectors.
void allocateVectors()
Allocate matrices in the first optimisation cycle.
virtual tmp< scalarField > HessianVectorProduct(const scalarField &vector)
Compute the Hessian - vector product.
virtual tmp< scalarField > SR1HessianVectorProduct(const scalarField &vector)
Compute the Hessian - vector product.
virtual bool writeData(Ostream &os) const
Write useful quantities to files.
PtrList< scalarField > s_
The previous correction. Holds nPrevSteps_ fields.
tmp< scalarField > HessianDiag()
Return the diagonal of the Hessian.
bool useYDamping_
Use damping for s to ensure positive-definitiveness.
label nPrevSteps_
Number of old corrections and grad differences kept.
bool useSDamping_
Use damping for s to ensure positive-definitiveness.
virtual tmp< scalarField > invHessianVectorProduct(const scalarField &vector)
Compute the inverse Hessian - vector product.
virtual void update()
Update design variables.
tmp< scalarField > SR1HessianDiag()
Return the diagonal of the Hessian.
virtual void updateHessian()
Update the Hessian matrix by updating the base vectors.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
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.
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
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.
Base class for quasi-Newton methods.
scalarField correctionOld_
The previous correction.
virtual bool writeData(Ostream &os) const
Write useful quantities to files.
label nSteepestDescent_
Number of first steepest descent steps.
scalar etaHessian_
Step for the Newton method.
scalarField derivativesOld_
The previous derivatives.
A class for managing references or pointers (no reference counting).
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
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 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.
autoPtr< designVariables > & designVars_
Design variables.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
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.
List< label > labelList
A List of labels.
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.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
#define forAll(list, i)
Loop across all elements in list.