45 constrainedOptimisationMethod,
96 + iTildaEps_[1].size()
97 + iTildaEps_[2].size()
99 if (nConstraints && solveDualProblem_)
101 scalar resMax(
gMax(
mag(computeResiduals())));
106 <<
"Dual problem Newton iter " << iter <<
nl <<
endl;
109 if (resMax < 0.9*eps_)
115 computeNewtonDirection();
122 <<
"max residual = " << resMax <<
", " 123 <<
"eps = " << eps_ <<
nl <<
endl;
125 mesh_.time().printExecutionTime(
Info);
128 iter++ < maxNewtonIters_
129 && (eps_ > dualTolerance_ || resMax > 0.9*eps_)
132 Info<<
"Solved the dual Newton problem in " << iter <<
" iterations " 134 Info<<
"fluid related Lagrange mults " << mu_ <<
endl;
144 const label m = iFlow.
size();
145 const label
nl = iLower.size();
146 const label
nu = iUpper.
size();
153 scalarField dLdx(objectiveDerivatives_, activeDesignVars_);
158 *
scalarField(constraintDerivatives_[iFlow[i]], activeDesignVars_);
162 dLdx[iLower[i]] -= l_[i];
166 dLdx[iUpper[i]] += u_[i];
176 dLdx*
scalarField(constraintDerivatives_[ic], activeDesignVars_)
179 res[iRes++] = gradPart - dualMu_[i];
185 res[iRes++] = mu_[i]*dualMu_[i] - eps_;
191 res[iRes++] = - dualL_[i] - 2*dLdx[iLower[i]];
197 res[iRes++] = - dualU_[i] + 2*dLdx[iUpper[i]];
203 res[iRes++] = l_[i]*dualL_[i] - eps_;
209 res[iRes++] = u_[i]*dualU_[i] - eps_;
226 const label m = iFlow.
size();
227 const label
nl = iLower.size();
228 const label
nu = iUpper.
size();
238 diagKsi = scalar(1)/(2 + dualL_/l_);
241 SubField<scalar>(res,
nl, 2*m)
242 + SubField<scalar>(res,
nl, 2*m +
nl +
nu)/l_
247 diagEta = scalar(1)/(2 + dualU_/u_);
250 SubField<scalar>(res,
nu, 2*m +
nl)
251 + SubField<scalar>(res,
nu, 2*m + 2*
nl +
nu)/u_
257 for (label i = 0; i < m; ++i)
259 const label ic = iFlow[i];
260 scalarField dci(constraintDerivatives_[ic], activeDesignVars_);
261 lhs[i][i] += 2*globalSum(dci*dci) + dualMu_[i]/mu_[i];
262 rhs[i] -= res[i] + res[m + i]/mu_[i];
267 4*globalSum(dciKsi*dciKsi*diagKsi)
268 + 4*globalSum(dciEta*dciEta*diagEta);
269 rhs[i] += 2*globalSum(dciKsi*rhsKsi) - 2*globalSum(dciEta*rhsEta);
270 for (label j = i + 1; j < m; ++j)
272 const label jc = iFlow[j];
273 scalarField dcj(constraintDerivatives_[jc], activeDesignVars_);
274 scalar ij = 2*globalSum(dci*dcj);
282 scalar ksiContr = 4*globalSum(dciKsi*dcjKsi*diagKsi);
283 scalar etaContr = 4*globalSum(dciEta*dcjEta*diagEta);
284 lhs[i][j] -= ksiContr + etaContr;
285 lhs[j][i] -= ksiContr + etaContr;
292 solve(deltaMu_, lhs, rhs);
293 deltaDualMu_ = -(deltaMu_*dualMu_ + SubField<scalar>(res, m, m))/mu_;
301 const label ic = iFlow[i];
302 scalarField dci(constraintDerivatives_[ic], activeDesignVars_);
306 deltaL_ *= 2*diagKsi;
309 deltaU_ *= 2*diagEta;
315 - (dualL_*deltaL_ + SubField<scalar>(res,
nl, 2*m +
nl +
nu))
335 adjustStep(step, mu_[i], deltaMu_[i]);
336 adjustStep(step, dualMu_[i], deltaDualMu_[i]);
341 adjustStep(step, l_[i], deltaL_[i]);
342 adjustStep(step, dualL_[i], deltaDualL_[i]);
347 adjustStep(step, u_[i], deltaU_[i]);
348 adjustStep(step, dualU_[i], deltaDualU_[i]);
355 reduce(step, minOp<scalar>());
360 Info<<
"Step before line search is " << step <<
endl;
364 scalar normResOld =
sqrt(globalSum(
magSqr(computeResiduals())));
365 scalar maxRes(GREAT);
367 for (label i = 0; i < maxLineSearchIters_ ; ++i)
370 updateSolution(step);
374 scalar normResNew =
sqrt(globalSum(
magSqr(resNew)));
377 if (normResNew < normResOld)
380 <<
"Initial residual = " << normResOld <<
", " 381 <<
"Final residual = " << normResNew <<
", " 382 <<
"No of LineSearch Iterations = " << i + 1
389 updateSolution(-step);
393 if (i == maxLineSearchIters_ - 1)
396 Info<<
"Line search could not find a step that reduced" 397 <<
" residuals while satisfying the constraints" <<
nl 398 <<
"Increasing eps to " << eps_ <<
endl;
405 Info<<
"Step after line search is " << step <<
nl <<
endl;
419 if (0.99*value + step*
update < scalar(0))
421 step = -0.99*value/
update;
428 mu_ += step*deltaMu_;
429 dualMu_ += step*deltaDualMu_;
432 dualL_ += step*deltaDualL_;
435 dualU_ += step*deltaDualU_;
441 updateViolatedIndices(0, cValues_);
443 if (includeBoundConstraints_)
446 (designVars_->lowerBoundsRef() - designVars_(), activeDesignVars_);
447 updateViolatedIndices(1, lowerBounds);
450 (designVars_() - designVars_->upperBoundsRef(), activeDesignVars_);
451 updateViolatedIndices(2, upperBounds);
454 statistics(iTilda_,
"violated");
455 statistics(iTildaEps_,
"violated-up-to-eps");
461 if (solveDualProblem_)
463 updateCorrectionIndices(0, mu_, dualMu_);
464 updateCorrectionIndices(1, l_, dualL_);
465 updateCorrectionIndices(2, u_, dualU_);
467 statistics(iHat_,
"non-tangent,violated");
468 statistics(iRangeSpace_,
"to-be-reduced");
473 iRangeSpace_ = iTildaEps_;
486 subset.setSize(constraints.size(), -1);
487 label iViolated =
Zero;
490 if (constraints[i] >= 0)
495 subset.setSize(iViolated);
498 DynamicList<label> iTildaEps(
subset);
501 if (constraints[i] >= -epsConstr_ && constraints[i] < 0)
503 iTildaEps.push_back(i);
506 iTildaEps_[i].transfer(iTildaEps);
518 const labelList& firstAddr = iTildaEps_[i];
520 subset.setSize(LagrangeMults.size(), -1);
521 label iViolated(
Zero);
530 if (LagrangeMults[j] > dual[j])
532 subset[iViolated++] = firstAddr[j];
537 DynamicList<label> iRangeSpace(iTilda_[i]);
538 for (label j = iTilda_[i].size(); j < iTildaEps_[i].size(); ++j)
540 if (LagrangeMults[j] > dual[j])
542 subset[iViolated++] = firstAddr[j];
543 iRangeSpace.push_back(firstAddr[j]);
546 subset.setSize(iViolated);
547 iRangeSpace_[i].transfer(iRangeSpace);
554 const scalarField activeDerivs(objectiveDerivatives_, activeDesignVars_);
556 scalarField lamdaJ(constraintRelatedUpdate(rJ, iHat_));
557 scalarField ksiJ(activeDerivs - ATv(lamdaJ, iHat_));
561 scalarField lamdaC(constraintRelatedUpdate(
g, iRangeSpace_));
566 scalar magKsiJ =
sqrt(globalSum(
sqr(ksiJ))) ;
568 for (
const label i : iHat_[0])
571 (constraintDerivatives_[i], activeDesignVars_);
572 cDerivs /=
sqrt(globalSum(
sqr(cDerivs))) + SMALL;
573 Info<<
"\tNull space update projected to the " << i
574 <<
"-th flow constraint gradient " 575 << globalSum(ksiJUnit*cDerivs)
579 scalar sumLowConsts(
Zero);
580 scalar sumUppConsts(
Zero);
581 for (
const label il : iHat_[1])
583 sumLowConsts += ksiJUnit[il];
585 for (
const label iu : iHat_[2])
587 sumUppConsts += ksiJUnit[iu];
591 reduce(sumLowConsts, sumOp<scalar>());
592 reduce(sumUppConsts, sumOp<scalar>());
594 Info<<
"\tSum of projections to the lower bound constraints " 595 << sumLowConsts <<
endl;
596 Info<<
"\tSum of projections to the upper bound constraints " 597 << sumUppConsts <<
endl;
600 scalar maxKsiJ =
gMax(
mag(ksiJ));
601 if (adaptiveStep_ && maxKsiJ > VSMALL)
603 if (counter_ < lastAcceleratedCycle_)
605 aJ_ = maxDVChange_()/eta_/maxKsiJ;
607 else if (strictMaxDVChange_)
609 aJ_ =
min(aJ_, maxDVChange_()/eta_/maxKsiJ);
619 <<
"aJ set to " << aJ_ <<
endl;
622 scalar maxKsiC =
gMax(
mag(ksiC));
623 if (adaptiveStep_ && maxKsiC > VSMALL)
628 targetConstraintReduction_/eta_,
629 maxDVChange_()/eta_/maxKsiC
635 Info<<
"Mag of ksiJ and ksiC " 640 Info<<
"Inner product of ksiJ and ksiC " << globalSum(ksiC*ksiJ)
646 correction_.rmap(-eta_*(aJ_*ksiJ + aC_*ksiC), activeDesignVars_);
659 label m = iFlow.
size();
660 label
nl = iLower.size();
662 if (v.size() != activeDesignVars_.size())
665 <<
"Input vector size not equal to the active design variables" 674 scalarField di(constraintDerivatives_[iFlow[ic]], activeDesignVars_);
675 mvp[ic] += globalSum(di*v);
681 mvp[m + il] = -v[iLower[il]];
687 mvp[m +
nl + iu] = v[iUpper[iu]];
703 label m = iFlow.
size();
704 label
nl = iLower.size();
706 if (v.size() != m +
nl +
nu)
709 <<
"Input vector size not equal to the active constraints" 718 scalarField di(constraintDerivatives_[iFlow[ic]], activeDesignVars_);
725 mvp[iLower[il]] -= v[m + il];
731 mvp[iUpper[iu]] += v[m +
nl + iu];
746 label m = iFlow.
size();
747 label
nl = iLower.size();
753 for (
const label i : iFlow)
755 cons[ic++] = cValues_[i];
758 const autoPtr<scalarField>& lowerBounds = designVars_->lowerBounds();
759 for (
const label i : iLower)
761 const label iActive = activeDesignVars_[i];
762 cons[ic++] = bcMult_*(lowerBounds()[iActive] - designVars_()[iActive]);
765 const autoPtr<scalarField>& upperBounds = designVars_->upperBounds();
766 for (
const label i : iUpper)
768 const label iActive = activeDesignVars_[i];
769 cons[ic++] = bcMult_*(designVars_()[iActive] - upperBounds()[iActive]);
785 label m = iFlow.
size();
786 label
nl = iLower.size();
788 if (rhs.size() != m +
nl +
nu)
791 <<
"rhs should have the dimensions of the active constraints" 802 const label ic = iFlow[i];
803 scalarField dci(constraintDerivatives_[ic], activeDesignVars_);
806 lhs[i][i] += globalSum(dci*dci) ;
807 scalar lowerContr(
Zero);
808 scalar upperContr(
Zero);
809 for (
const label il : iLower)
811 lowerContr -= dci[il]*dci[il];
813 for (
const label iu : iUpper)
815 upperContr -= dci[iu]*dci[iu];
819 reduce(lowerContr, sumOp<scalar>());
820 reduce(upperContr, sumOp<scalar>());
822 lhs[i][i] += lowerContr + upperContr;
825 for (label j = i + 1; j < m; ++j)
827 const label jc = iFlow[j];
828 scalarField dcj(constraintDerivatives_[jc], activeDesignVars_);
829 scalar ij = globalSum(dci*dcj);
834 for (
const label il : iLower)
836 lowerContr -= dci[il]*dcj[il];
839 for (
const label iu : iUpper)
841 upperContr -= dci[iu]*dcj[iu];
846 reduce(lowerContr, sumOp<scalar>());
847 reduce(upperContr, sumOp<scalar>());
849 lhs[i][j] += lowerContr + upperContr;
850 lhs[j][i] += lowerContr + upperContr;
858 lowerContr += dci[iLower[il]]*rhs[m + il];
863 upperContr -= dci[iUpper[iu]]*rhs[m +
nl + iu];
868 reduce(lowerContr, sumOp<scalar>());
869 reduce(upperContr, sumOp<scalar>());
871 r[i] += lowerContr + upperContr;
875 SubField<scalar>(res,
nl, m) = SubField<scalar>(rhs,
nl, m);
876 SubField<scalar>(res,
nu,
nl + m) = SubField<scalar>(rhs,
nu,
nl + m);
881 SubField<scalar>(res, m, 0) = solF;
885 scalarField dci(constraintDerivatives_[iFlow[i]], activeDesignVars_);
888 res[m + il] += dci[iLower[il]]*solF[i];
892 res[m +
nl + iu] -= dci[iUpper[iu]]*solF[i];
903 const word& description
907 <<
"Number of flow constraints (" << description <<
") " 909 if (includeBoundConstraints_)
912 <<
"Number of lower bounds constraints (" << description <<
") " 913 << globalSum(
subset[1].size())
916 <<
"Number of upper bounds constraints (" << description <<
") " 917 << globalSum(
subset[2].size())
926 Foam::nullSpace::nullSpace
931 const label nConstraints,
937 includeBoundConstraints_
939 designVars->upperBounds() && designVars->lowerBounds()
941 mu_(nConstraints_,
Zero),
945 (coeffsDict(
type).getOrDefault<bool>(
"solveDualProblem", true)),
946 dualMu_(nConstraints_,
Zero),
953 deltaMu_(nConstraints_,
Zero),
956 deltaDualMu_(nConstraints_,
Zero),
960 maxNewtonIters_(coeffsDict(
type).getOrDefault<label>(
"maxIters", 6000)),
963 coeffsDict(
type).getOrDefault<label>(
"maxLineSearchIters", 10)
966 (coeffsDict(
type).getOrDefault<label>(
"maxCGIters", maxNewtonIters_)),
968 (coeffsDict(
type).getOrDefault<scalar>(
"dualTolerance", 1.
e-12)),
972 getOrDefault<scalar>(
"violatedConstraintsThreshold", 1.
e-3)
974 epsPerturb_(coeffsDict(
type). getOrDefault<scalar>(
"perturbation", 1.
e-2)),
975 aJ_(coeffsDict(
type).getOrDefault<scalar>(
"aJ", 1)),
976 aC_(coeffsDict(
type).getOrDefault<scalar>(
"aC", 1)),
977 adaptiveStep_(coeffsDict(
type).getOrDefault<bool>(
"adaptiveStep", true)),
978 lastAcceleratedCycle_
979 (coeffsDict(
type).getOrDefault<label>(
"lastAcceleratedCycle", 20)),
980 maxDVChange_(nullptr),
982 (coeffsDict(
type).getOrDefault<bool>(
"strictMaxDVChange", false)),
983 targetConstraintReduction_
986 getOrDefault<scalar>(
"targetConstraintReduction", 0.5)
988 bcMult_(coeffsDict(
type).getOrDefault<scalar>(
"boundConstraintsMult", 0.5))
1002 <<
"Either maxInitChange or maxDVChange has to be setup when using " 1003 <<
"an adaptive step" 1018 boolList isOnLowerBound(designVars.size(),
false);
1019 boolList isOnUpperBound(designVars.size(),
false);
1020 bool existsNonBoundVar =
false;
1021 for (
const label activeVarI :
designVars_->activeDesignVariables())
1023 isOnLowerBound[activeVarI] =
1024 mag(designVars[activeVarI] - lowerBounds[activeVarI]) < SMALL;
1025 isOnUpperBound[activeVarI] =
1026 mag(designVars[activeVarI] - upperBounds[activeVarI]) < SMALL;
1029 || (!isOnLowerBound[activeVarI] && !isOnUpperBound[activeVarI]);
1033 reduce(existsNonBoundVar, orOp<bool>());
1035 if (!existsNonBoundVar)
1038 <<
"All design variables lay on their bound values." <<
nl 1039 <<
tab <<
"This will lead to singular matrices in nullSpace" 1041 <<
tab <<
"Perturbing the design variables by " 1046 for (
const label activeVarI :
designVars_->activeDesignVariables())
1048 if (isOnLowerBound[activeVarI])
1052 *(upperBounds[activeVarI] - lowerBounds[activeVarI]);
1054 if (isOnUpperBound[activeVarI])
1058 *(upperBounds[activeVarI] - lowerBounds[activeVarI]);
1082 updateNullAndRangeSpaceSubsets();
1094 scalar LagrangePart = objectiveValue_;
1099 LagrangePart += mu_[i]*cValues_[iTildaEps_[0][i]];
1101 scalar lowerPart =
Zero;
1104 const label iActive = activeDesignVars_[iTildaEps_[1][i]];
1105 lowerPart += l_[i]*(lBounds()[iActive] - designVars_()[iActive]);
1107 scalar upperPart =
Zero;
1110 const label iActive = activeDesignVars_[iTildaEps_[2][i]];
1111 upperPart += u_[i]*(designVars_()[iActive] - uBounds()[iActive]);
1115 reduce(lowerPart, sumOp<scalar>());
1116 reduce(upperPart, sumOp<scalar>());
1118 LagrangePart += lowerPart + upperPart;
1119 LagrangePart *= aJ_;
1122 scalarField invAAT_g(constraintRelatedUpdate(
g, iTildaEps_));
1124 scalar constraintPart =
Zero;
1125 const label gSize =
g.size();
1126 const label flowSize = iTildaEps_[0].size();
1129 constraintPart +=
g[i]*invAAT_g[i];
1132 scalarField a = SubField<scalar>(
g, gSize - flowSize, flowSize);
1133 scalarField b = SubField<scalar>(invAAT_g, gSize - flowSize, flowSize);
1134 constraintPart += globalSum(a*
b);
1135 constraintPart *= 0.5*aC_;
1137 return LagrangePart + constraintPart;
1147 scalarField deriv(objectiveDerivatives_, activeDesignVars_);
1148 deriv += ATv(LagrangeMults, iTildaEps_);
1152 scalarField lamdaC(constraintRelatedUpdate(
g, iTildaEps_));
1158 derivAll.rmap(deriv, activeDesignVars_);
1160 return globalSum(
sqr(derivAll*correction_));
void updateViolatedConstraintsSubsets()
Update the constraint subsets.
autoPtr< designVariables > & designVars_
Design variables.
scalar lineSearch()
Perform line search and return max residual corresponding to the updated solution.
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix by subtracting the matrix multiplied by the current fi...
tmp< scalarField > activeConstraints(const labelListList &subsets)
Collect all constraint values corresponding to the provided indices.
void size(const label n)
Older name for setAddressableSize.
tmp< scalarField > constraintRelatedUpdate(const scalarField &rhs, const labelListList &subsets)
Computes the parts of ksiJ and ksiC that require a system solution.
void correction()
Compute the update of the design variables as a combination of null space and range space parts...
void initialise()
Update sizes of fields related to the constraints.
Abstract base class for optimisation methods supporting constraints. Does not add functionality to up...
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
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...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void computeNewtonDirection()
Compute direction for the Newton problem.
autoPtr< scalar > maxDVChange_
Max change of the design variables, pertaining to the objective reduction.
scalar eps_
Infinitesimal quantity.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline '\n' character (0x0a)
Abstract base class for optimisation methods.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
constexpr char tab
The tab '\t' character(0x09)
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
void updateNullAndRangeSpaceSubsets()
Update the constraint subsets.
scalarField mu_
Lagrange multipliers for flow-reated constraints.
List< labelList > labelListList
List of labelList.
Macros for easy insertion into run-time selection tables.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
tmp< scalarField > Av(const scalarField &v, const labelListList &subsets)
A & v.
#define forAll(list, i)
Loop across all elements in list.
scalarField l_
Lagrange multipliers for the lower bound constraints.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
scalarField u_
Lagrange multipliers for the upper bound constraints.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
const dimensionedScalar e
Elementary charge.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
virtual void computeCorrection()
Compute design variables correction.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void zeroUpdates()
Zero the updates computed in the previous optimisation cycle.
void updateSolution(const scalar step)
Update the current solution using the known direction and the given step length.
scalar epsPerturb_
Value to perturb the design variables by, if all of them lay on their bounds at the beginning of the ...
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
void updateCorrectionIndices(const label i, const scalarField &LagrangeMults, const scalarField &dual)
Update constraint indices related to the null and range space part of the correction.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
SolverPerformance< Type > solve(faMatrix< Type > &, const dictionary &solverControls)
Solve returning the solution statistics given convergence tolerance.
#define DebugInfo
Report an information message using Foam::Info.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
const uniformDimensionedVectorField & g
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
Type gMax(const FieldField< Field, Type > &f)
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
dictionary coeffsDict(const word &type) const
Return optional dictionary with parameters specific to each method.
virtual scalar meritFunctionDirectionalDerivative()
Directional derivative of the merit function, in the direction of the correction. ...
scalar aJ_
Multiplier of the null space update.
Abstract base class for line search methods.
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
tmp< scalarField > ATv(const scalarField &v, const labelListList &subsets)
A.T & v.
bool globalSum_
Whether to use gSum or sum in the inner products.
#define WarningInFunction
Report a warning using Foam::Warning.
scalarField dualU_
Lagrange multipliers of the dual problem for the upper bound constraints.
tmp< scalarField > computeResiduals()
Compute and return residuals based on the current solution.
void solveDualProblem()
Solve the dual problem for computing the Lagrange multiplier using a Newton solver.
Mesh data needed to do the Finite Volume discretisation.
bool adaptiveStep_
Change aJ and aC adaptively.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool writeData(Ostream &os) const
Write useful quantities to files.
scalarField dualMu_
Lagrange multipliers of the dual problem for flow-related constraints.
void updateViolatedIndices(const label i, const scalarField &constraints)
Update violated constraints indices (iTilda and iTildaEps)
void adjustStep(scalar &step, const scalar value, const scalar update)
Adjust step to satisfy cireteria.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
List< label > labelList
A List of labels.
A class for managing temporary objects.
virtual scalar computeMeritFunction()
Compute the merit function for line search.
SquareMatrix< scalar > scalarSquareMatrix
List< bool > boolList
A List of bools.
virtual bool writeData(Ostream &os) const
Write continuation data under uniform.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
scalarField dualL_
Lagrange multipliers of the dual problem for the lower bound constraints.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
static constexpr const zero Zero
Global zero (0)
void statistics(const labelListList &subset, const word &description)
Print statistics on the number of flow- and bound-related constraints included in the subset...
labelListList iTildaEps_
List of saturated or violated constraints (up to epsConstr_)