Compare commits
4 Commits
multiNodeD
...
feature-un
| Author | SHA1 | Date | |
|---|---|---|---|
| 07664c0de8 | |||
| 32c8fb57b7 | |||
| 4ee7dd50ee | |||
| 162f5f29ec |
@ -967,6 +967,34 @@ bool Foam::Time::end() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::Time::reverseRun() const
|
||||||
|
{
|
||||||
|
// Must not solve for the 0 time step
|
||||||
|
bool isRunning = value() > (endTime_ + 0.5*deltaT_);
|
||||||
|
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::Time::reverseLoop()
|
||||||
|
{
|
||||||
|
const bool isRunning = reverseRun();
|
||||||
|
|
||||||
|
if (isRunning)
|
||||||
|
{
|
||||||
|
operator--();
|
||||||
|
}
|
||||||
|
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::Time::reverseEnd() const
|
||||||
|
{
|
||||||
|
return value() < (endTime_ - 0.5*deltaT_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
|
bool Foam::Time::stopAt(const stopAtControls stopCtrl) const
|
||||||
{
|
{
|
||||||
if (stopCtrl == stopAtControls::saUnknown)
|
if (stopCtrl == stopAtControls::saUnknown)
|
||||||
@ -1365,4 +1393,242 @@ Foam::Time& Foam::Time::operator++(int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Time&
|
||||||
|
Foam::Time::operator-=(const dimensionedScalar& deltaT)
|
||||||
|
{
|
||||||
|
return operator-=(deltaT.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Time& Foam::Time::operator-=(const scalar deltaT)
|
||||||
|
{
|
||||||
|
setDeltaT(deltaT);
|
||||||
|
return operator--();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Time& Foam::Time::operator--()
|
||||||
|
{
|
||||||
|
deltaT0_ = deltaTSave_;
|
||||||
|
deltaTSave_ = deltaT_;
|
||||||
|
|
||||||
|
// Save old time value and name
|
||||||
|
const scalar oldTimeValue = timeToUserTime(value());
|
||||||
|
const word oldTimeName = dimensionedScalar::name();
|
||||||
|
|
||||||
|
// Decrease time
|
||||||
|
setTime(value() - deltaT_, timeIndex_ - 1);
|
||||||
|
|
||||||
|
if (!subCycling_)
|
||||||
|
{
|
||||||
|
// If the time is very close to zero reset to zero
|
||||||
|
if (mag(value()) < 10*SMALL*deltaT_)
|
||||||
|
{
|
||||||
|
setTime(0.0, timeIndex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
|
||||||
|
{
|
||||||
|
// A signal might have been sent on one processor only
|
||||||
|
// Reduce so all decide the same.
|
||||||
|
|
||||||
|
label flag = 0;
|
||||||
|
if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
|
||||||
|
{
|
||||||
|
flag += 1;
|
||||||
|
}
|
||||||
|
if (sigWriteNow_.active() && writeOnce_)
|
||||||
|
{
|
||||||
|
flag += 2;
|
||||||
|
}
|
||||||
|
reduce(flag, maxOp<label>());
|
||||||
|
|
||||||
|
if (flag & 1)
|
||||||
|
{
|
||||||
|
stopAt_ = saWriteNow;
|
||||||
|
}
|
||||||
|
if (flag & 2)
|
||||||
|
{
|
||||||
|
writeOnce_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeTime_ = false;
|
||||||
|
|
||||||
|
switch (writeControl_)
|
||||||
|
{
|
||||||
|
case wcNone:
|
||||||
|
case wcUnknown:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wcTimeStep:
|
||||||
|
// Avoid writing just because timIndex_ is zero
|
||||||
|
writeTime_ =
|
||||||
|
!(timeIndex_ % label(writeInterval_)) && timeIndex_;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wcRunTime:
|
||||||
|
case wcAdjustableRunTime:
|
||||||
|
{
|
||||||
|
const label writeIndex = label
|
||||||
|
(
|
||||||
|
((value() - startTime_) - 0.5*deltaT_)
|
||||||
|
/ writeInterval_
|
||||||
|
);
|
||||||
|
|
||||||
|
if (writeIndex < writeTimeIndex_)
|
||||||
|
{
|
||||||
|
writeTime_ = true;
|
||||||
|
writeTimeIndex_ = writeIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wcCpuTime:
|
||||||
|
{
|
||||||
|
const label writeIndex = label
|
||||||
|
(
|
||||||
|
returnReduce(elapsedCpuTime(), maxOp<double>())
|
||||||
|
/ writeInterval_
|
||||||
|
);
|
||||||
|
if (writeIndex > writeTimeIndex_)
|
||||||
|
{
|
||||||
|
writeTime_ = true;
|
||||||
|
writeTimeIndex_ = writeIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wcClockTime:
|
||||||
|
{
|
||||||
|
const label writeIndex = label
|
||||||
|
(
|
||||||
|
returnReduce(elapsedClockTime(), maxOp<double>())
|
||||||
|
/ writeInterval_
|
||||||
|
);
|
||||||
|
if (writeIndex > writeTimeIndex_)
|
||||||
|
{
|
||||||
|
writeTime_ = true;
|
||||||
|
writeTimeIndex_ = writeIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if endTime needs adjustment to stop at the next
|
||||||
|
// reverseRun()/reverseEnd()
|
||||||
|
if (!reverseEnd())
|
||||||
|
{
|
||||||
|
if (stopAt_ == saNoWriteNow)
|
||||||
|
{
|
||||||
|
endTime_ = value();
|
||||||
|
}
|
||||||
|
else if (stopAt_ == saWriteNow)
|
||||||
|
{
|
||||||
|
endTime_ = value();
|
||||||
|
writeTime_ = true;
|
||||||
|
}
|
||||||
|
else if (stopAt_ == saNextWrite && writeTime_ == true)
|
||||||
|
{
|
||||||
|
endTime_ = value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override writeTime if one-shot writing
|
||||||
|
if (writeOnce_)
|
||||||
|
{
|
||||||
|
writeTime_ = true;
|
||||||
|
writeOnce_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust the precision of the time directory name if necessary
|
||||||
|
if (writeTime_)
|
||||||
|
{
|
||||||
|
// Tolerance used when testing time equivalence
|
||||||
|
const scalar timeTol =
|
||||||
|
max(min(pow(10.0, -precision_), 0.1*deltaT_), SMALL);
|
||||||
|
|
||||||
|
// User-time equivalent of deltaT
|
||||||
|
const scalar userDeltaT = timeToUserTime(deltaT_);
|
||||||
|
|
||||||
|
// Time value obtained by reading timeName
|
||||||
|
scalar timeNameValue = -VGREAT;
|
||||||
|
|
||||||
|
// Check that new time representation differs from old one
|
||||||
|
// reinterpretation of the word
|
||||||
|
if
|
||||||
|
(
|
||||||
|
readScalar(dimensionedScalar::name(), timeNameValue)
|
||||||
|
&& (mag(-timeNameValue + oldTimeValue - userDeltaT) > timeTol)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int oldPrecision = precision_;
|
||||||
|
while
|
||||||
|
(
|
||||||
|
precision_ < maxPrecision_
|
||||||
|
&& readScalar(dimensionedScalar::name(), timeNameValue)
|
||||||
|
&& (mag(-timeNameValue + oldTimeValue - userDeltaT) > timeTol)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
precision_++;
|
||||||
|
setTime(value(), timeIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (precision_ != oldPrecision)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Increased the timePrecision from " << oldPrecision
|
||||||
|
<< " to " << precision_
|
||||||
|
<< " to distinguish between timeNames at time "
|
||||||
|
<< dimensionedScalar::name()
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (precision_ == maxPrecision_)
|
||||||
|
{
|
||||||
|
// Reached maxPrecision limit
|
||||||
|
WarningInFunction
|
||||||
|
<< "Current time name " << dimensionedScalar::name()
|
||||||
|
<< nl
|
||||||
|
<< " The maximum time precision has been reached"
|
||||||
|
" which might result in overwriting previous"
|
||||||
|
" results."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if round-off error caused time-reversal
|
||||||
|
scalar oldTimeNameValue = -VGREAT;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
readScalar(oldTimeName, oldTimeNameValue)
|
||||||
|
&& (
|
||||||
|
sign(timeNameValue - oldTimeNameValue)
|
||||||
|
!= sign(deltaT_)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Current time name " << dimensionedScalar::name()
|
||||||
|
<< " is set to an instance prior to the "
|
||||||
|
"previous one "
|
||||||
|
<< oldTimeName << nl
|
||||||
|
<< " This might result in temporal "
|
||||||
|
"discontinuities."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Time& Foam::Time::operator--(int)
|
||||||
|
{
|
||||||
|
return operator--();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||||
|
Copyright (C) 2022 PCOpt/NTUA
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -571,6 +572,43 @@ public:
|
|||||||
// not yield the same result
|
// not yield the same result
|
||||||
virtual bool end() const;
|
virtual bool end() const;
|
||||||
|
|
||||||
|
//- Return true if run should continue.
|
||||||
|
// Does not invoke any functionObject methods
|
||||||
|
// \note
|
||||||
|
// For correct behaviour, the following style of time-loop
|
||||||
|
// is recommended:
|
||||||
|
// \code
|
||||||
|
// while (runTime.reverseRun())
|
||||||
|
// {
|
||||||
|
// --runTime;
|
||||||
|
// solve;
|
||||||
|
// runTime.write();
|
||||||
|
// }
|
||||||
|
// \endcode
|
||||||
|
virtual bool reverseRun() const;
|
||||||
|
|
||||||
|
//- Return true if run should continue and if so decrease time
|
||||||
|
// Does not invoke any functionObject methods
|
||||||
|
// \note
|
||||||
|
// For correct behaviour, the following style of time-loop
|
||||||
|
// is recommended:
|
||||||
|
// \code
|
||||||
|
// while (runTime.reverseLoop())
|
||||||
|
// {
|
||||||
|
// solve;
|
||||||
|
// runTime.write();
|
||||||
|
// }
|
||||||
|
// \endcode
|
||||||
|
virtual bool reverseLoop();
|
||||||
|
|
||||||
|
//- Return true if end of run,
|
||||||
|
// does not invoke any functionObject methods
|
||||||
|
// \note
|
||||||
|
// The rounding heuristics near endTime mean that
|
||||||
|
// \code reverseRun() \endcode and \code !reverseEnd() \endcode
|
||||||
|
// may not yield the same result
|
||||||
|
virtual bool reverseEnd() const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
@ -653,6 +691,20 @@ public:
|
|||||||
|
|
||||||
//- Postfix increment, this is identical to the prefix increment
|
//- Postfix increment, this is identical to the prefix increment
|
||||||
virtual Time& operator++(int);
|
virtual Time& operator++(int);
|
||||||
|
|
||||||
|
//- Set deltaT to that specified and decrease time via operator--()
|
||||||
|
virtual Time& operator-=(const dimensionedScalar& deltaT);
|
||||||
|
|
||||||
|
//- Set deltaT to that specified and decrease time via operator--()
|
||||||
|
virtual Time& operator-=(const scalar deltaT);
|
||||||
|
|
||||||
|
//- prefix decrease,
|
||||||
|
// also invokes the functionobjectlist::start() or
|
||||||
|
// functionobjectlist::execute() method, depending on the time-index
|
||||||
|
virtual Time& operator--();
|
||||||
|
|
||||||
|
//- Postfix decrease, this is identical to the decrease increment
|
||||||
|
virtual Time& operator--(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -545,7 +545,8 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
|||||||
(
|
(
|
||||||
const IOobject& io,
|
const IOobject& io,
|
||||||
const Mesh& mesh,
|
const Mesh& mesh,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
const bool readOldTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Internal(io, mesh, dimless, false),
|
Internal(io, mesh, dimless, false),
|
||||||
@ -566,6 +567,11 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
|||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (readOldTime)
|
||||||
|
{
|
||||||
|
readOldTimeIfPresent();
|
||||||
|
}
|
||||||
|
|
||||||
DebugInFunction
|
DebugInFunction
|
||||||
<< "Finishing dictionary-construct" << nl << this->info() << endl;
|
<< "Finishing dictionary-construct" << nl << this->info() << endl;
|
||||||
}
|
}
|
||||||
@ -623,7 +629,8 @@ template<class Type, template<class> class PatchField, class GeoMesh>
|
|||||||
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||||
(
|
(
|
||||||
const IOobject& io,
|
const IOobject& io,
|
||||||
const GeometricField<Type, PatchField, GeoMesh>& gf
|
const GeometricField<Type, PatchField, GeoMesh>& gf,
|
||||||
|
const bool readOldTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Internal(io, gf),
|
Internal(io, gf),
|
||||||
@ -636,7 +643,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
|||||||
<< "Copy construct, resetting IO params" << nl
|
<< "Copy construct, resetting IO params" << nl
|
||||||
<< this->info() << endl;
|
<< this->info() << endl;
|
||||||
|
|
||||||
if (!readIfPresent() && gf.field0Ptr_)
|
if (!readIfPresent() && gf.field0Ptr_ && readOldTime)
|
||||||
{
|
{
|
||||||
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
|
field0Ptr_ = new GeometricField<Type, PatchField, GeoMesh>
|
||||||
(
|
(
|
||||||
|
|||||||
@ -296,7 +296,8 @@ public:
|
|||||||
(
|
(
|
||||||
const IOobject& io,
|
const IOobject& io,
|
||||||
const Mesh& mesh,
|
const Mesh& mesh,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
const bool readOldTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Copy construct
|
//- Copy construct
|
||||||
@ -315,7 +316,8 @@ public:
|
|||||||
GeometricField
|
GeometricField
|
||||||
(
|
(
|
||||||
const IOobject& io,
|
const IOobject& io,
|
||||||
const GeometricField<Type, PatchField, GeoMesh>& gf
|
const GeometricField<Type, PatchField, GeoMesh>& gf,
|
||||||
|
const bool readOldTime = true
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from tmp\<GeometricField\> resetting IO parameters
|
//- Construct from tmp\<GeometricField\> resetting IO parameters
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
|
/* COMPRESSION PARAMETERS */
|
||||||
|
storage/primalStorage/storageParameters/storageParameters/storageParameters.C
|
||||||
|
storage/primalStorage/storageParameters/shortParameters/shortParameters.C
|
||||||
|
|
||||||
|
/* COMPRESSED GEOMETRIC FIELD */
|
||||||
|
compressedGeometricField = OpenFOAM/fields/compressedGeometricField
|
||||||
|
$(compressedGeometricField)/compressedGeometricField/compressedGeometricFields.C
|
||||||
|
$(compressedGeometricField)/shortGeometricField/shortGeometricFields.C
|
||||||
|
|
||||||
/* TURBULENCE MODEL VARIABLE REFS */
|
/* TURBULENCE MODEL VARIABLE REFS */
|
||||||
turbulenceModels/turbulenceModelVariables/RAS/RASModelVariables/RASModelVariables.C
|
turbulenceModels/turbulenceModelVariables/RAS/RASModelVariables/RASModelVariables.C
|
||||||
turbulenceModels/turbulenceModelVariables/RAS/laminar/laminar.C
|
turbulenceModels/turbulenceModelVariables/RAS/laminar/laminar.C
|
||||||
@ -11,12 +20,29 @@ solvers/variablesSet/variablesSet/variablesSet.C
|
|||||||
solvers/variablesSet/incompressible/incompressibleVars.C
|
solvers/variablesSet/incompressible/incompressibleVars.C
|
||||||
solvers/variablesSet/incompressibleAdjointMeanFlow/incompressibleAdjointMeanFlowVars.C
|
solvers/variablesSet/incompressibleAdjointMeanFlow/incompressibleAdjointMeanFlowVars.C
|
||||||
solvers/variablesSet/incompressibleAdjoint/incompressibleAdjointVars.C
|
solvers/variablesSet/incompressibleAdjoint/incompressibleAdjointVars.C
|
||||||
|
solvers/variablesSet/compressedIncompressible/compressedIncompressibleVars/compressedIncompressibleVars.C
|
||||||
|
solvers/variablesSet/compressedIncompressible/shortIncompressibleVars/shortIncompressibleVars.C
|
||||||
|
solvers/variablesSet/compressedIncompressible/fullIncompressibleVars/fullIncompressibleVars.C
|
||||||
|
solvers/variablesSet/checkPoint/checkPoint.C
|
||||||
|
|
||||||
/* SOLVER CONTROL */
|
/* SOLVER CONTROL */
|
||||||
solvers/solverControl/solverControl/solverControl.C
|
solvers/solverControl/solverControl/solverControl.C
|
||||||
solvers/solverControl/SIMPLEControl/SIMPLEControl/SIMPLEControl.C
|
solvers/solverControl/SIMPLEControl/SIMPLEControl/SIMPLEControl.C
|
||||||
solvers/solverControl/SIMPLEControl/singleRun/SIMPLEControlSingleRun.C
|
solvers/solverControl/SIMPLEControl/singleRun/SIMPLEControlSingleRun.C
|
||||||
solvers/solverControl/SIMPLEControl/optimisation/SIMPLEControlOpt.C
|
solvers/solverControl/SIMPLEControl/optimisation/SIMPLEControlOpt.C
|
||||||
|
solvers/solverControl/PISOControl/PISOControl/PISOControl.C
|
||||||
|
solvers/solverControl/PISOControl/optimisation/PISOControlOpt.C
|
||||||
|
solvers/solverControl/PIMPLEControl/PIMPLEControl/PIMPLEControl.C
|
||||||
|
solvers/solverControl/PIMPLEControl/optimisation/PIMPLEControlOpt.C
|
||||||
|
|
||||||
|
/* STORAGE MANAGMENT */
|
||||||
|
storage/primalStorage/primalStorage/primalStorage.C
|
||||||
|
storage/primalStorage/fullStorage/fullStorage.C
|
||||||
|
storage/primalStorage/none/noneStorage.C
|
||||||
|
storage/primalStorage/binomialCheckPointing/binomialCheckPointing.C
|
||||||
|
compressedFullStorage = storage/primalStorage/compressedFullStorage
|
||||||
|
$(compressedFullStorage)/compressedFullStorage/compressedFullStorage.C
|
||||||
|
$(compressedFullStorage)/shortFullStorage/shortFullStorage.C
|
||||||
|
|
||||||
/* SOLVERS */
|
/* SOLVERS */
|
||||||
solvers/solver/solver.C
|
solvers/solver/solver.C
|
||||||
@ -24,9 +50,13 @@ solvers/primalSolvers/primalSolver/primalSolver.C
|
|||||||
solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
|
solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
|
||||||
solvers/primalSolvers/incompressible/simple/simple.C
|
solvers/primalSolvers/incompressible/simple/simple.C
|
||||||
solvers/primalSolvers/incompressible/RASTurbulenceModel/RASTurbulenceModel.C
|
solvers/primalSolvers/incompressible/RASTurbulenceModel/RASTurbulenceModel.C
|
||||||
|
solvers/primalSolvers/incompressible/piso/piso.C
|
||||||
|
solvers/primalSolvers/incompressible/pimple/pimple.C
|
||||||
solvers/adjointSolvers/adjointSolver/adjointSolver.C
|
solvers/adjointSolvers/adjointSolver/adjointSolver.C
|
||||||
solvers/adjointSolvers/incompressible/incompressibleAdjointSolver/incompressibleAdjointSolver.C
|
solvers/adjointSolvers/incompressible/incompressibleAdjointSolver/incompressibleAdjointSolver.C
|
||||||
solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
|
solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
|
||||||
|
solvers/adjointSolvers/incompressible/adjointPiso/adjointPiso.C
|
||||||
|
solvers/adjointSolvers/incompressible/adjointPimple/adjointPimple.C
|
||||||
|
|
||||||
/* ADJOINT SOLVER MANAGER */
|
/* ADJOINT SOLVER MANAGER */
|
||||||
solvers/adjointSolverManager/adjointSolverManager.C
|
solvers/adjointSolverManager/adjointSolverManager.C
|
||||||
@ -183,5 +213,7 @@ $(incoOptType)/shapeOptimisation/shapeOptimisationIncompressible.C
|
|||||||
optimisation/optimisationManager/optimisationManager/optimisationManager.C
|
optimisation/optimisationManager/optimisationManager/optimisationManager.C
|
||||||
optimisation/optimisationManager/singleRun/singleRun.C
|
optimisation/optimisationManager/singleRun/singleRun.C
|
||||||
optimisation/optimisationManager/steadyOptimisation/steadyOptimisation.C
|
optimisation/optimisationManager/steadyOptimisation/steadyOptimisation.C
|
||||||
|
optimisation/optimisationManager/unsteadyOptimisation/unsteadyTimeManipulation/unsteadyTimeManipulation.C
|
||||||
|
optimisation/optimisationManager/unsteadyOptimisation/unsteadyOptimisation.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libadjointOptimisation
|
LIB = $(FOAM_LIBBIN)/libadjointOptimisation
|
||||||
|
|||||||
@ -0,0 +1,612 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wallFvPatch.H"
|
||||||
|
#include "symmetryPlaneFvPatch.H"
|
||||||
|
#include "emptyFvsPatchField.H"
|
||||||
|
#include "processorFvsPatchField.H"
|
||||||
|
#include "coupledFvPatchField.H"
|
||||||
|
#include "emptyFvPatchField.H"
|
||||||
|
#include "zeroGradientFvPatchField.H"
|
||||||
|
#include "inletOutletFvPatchField.H"
|
||||||
|
#include "outletInletFvPatchField.H"
|
||||||
|
#include "freestreamFvPatchField.H"
|
||||||
|
#include "slipFvPatchField.H"
|
||||||
|
#include "symmetryFvPatchField.H"
|
||||||
|
#include "symmetryPlaneFvPatchField.H"
|
||||||
|
#include "cyclicACMIFvPatchField.H"
|
||||||
|
#include "bound.H"
|
||||||
|
#include "compressedGeometricField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
label compressedGeometricField<Type, PatchField, GeoMesh>::counter = 0;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<scalar, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
Field<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::getValue
|
||||||
|
(
|
||||||
|
Field<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<vector, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
Field<vector>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos][componI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const scalar&
|
||||||
|
compressedGeometricField<scalar, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
const Field<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const scalar&
|
||||||
|
compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::getValue
|
||||||
|
(
|
||||||
|
const Field<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const scalar&
|
||||||
|
compressedGeometricField<vector, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
const Field<vector>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos][componI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<scalar, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
List<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::getValue
|
||||||
|
(
|
||||||
|
List<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline scalar&
|
||||||
|
compressedGeometricField<vector, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
List<vector>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos][componI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const
|
||||||
|
scalar& compressedGeometricField<scalar, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
const List<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const
|
||||||
|
scalar& compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::getValue
|
||||||
|
(
|
||||||
|
const List<scalar>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline const
|
||||||
|
scalar& compressedGeometricField<vector, fvPatchField, volMesh>::getValue
|
||||||
|
(
|
||||||
|
const List<vector>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return field[pos][componI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::toBeStored()
|
||||||
|
{
|
||||||
|
setValidComponent();
|
||||||
|
toBeStored_.setSize(mesh_.boundary().size(), false);
|
||||||
|
toBeStoredUniformOrNot_.setSize(mesh_.boundary().size(), false);
|
||||||
|
surfacePatchesToBeZeroed_.setSize(mesh_.boundary().size(), false);
|
||||||
|
typedef typename GeometricField<Type, PatchField, GeoMesh>::Boundary
|
||||||
|
Boundary;
|
||||||
|
const Boundary& boundaryField = field_.boundaryField();
|
||||||
|
forAll(mesh_.boundary(), pI)
|
||||||
|
{
|
||||||
|
const PatchField<Type>& pf = boundaryField[pI];
|
||||||
|
if (storageParams_.storeAllBoundaries())
|
||||||
|
{
|
||||||
|
if (pf.size() != 0)
|
||||||
|
{
|
||||||
|
// Warning: Possible error upon compression of boundaries
|
||||||
|
// with very small values when single precision is used.
|
||||||
|
// E.g. flux phi on boundaries with rotatingWallVelocity
|
||||||
|
// for the velocity
|
||||||
|
toBeStoredUniformOrNot_[pI] = true;
|
||||||
|
toBeStored_[pI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkFvsPatchFieldStorage(pf, pI);
|
||||||
|
checkFvPatchFieldStorage(pf, pI);
|
||||||
|
}
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
Info<< "Field '" << field_.name() << "': "
|
||||||
|
<< "Storing boundary patch " << pI
|
||||||
|
<< " '" << mesh_.boundary()[pI].name() << "' "
|
||||||
|
<< "of type '" << boundaryField.types()[pI] << "'? "
|
||||||
|
<< Switch(toBeStored_[pI]);
|
||||||
|
if (toBeStoredUniformOrNot_[pI] && !toBeStored_[pI])
|
||||||
|
{
|
||||||
|
Info << " --> Uniform boundary. A single value is stored.";
|
||||||
|
}
|
||||||
|
Info << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::checkFvsPatchFieldStorage
|
||||||
|
(
|
||||||
|
const PatchField<Type>& patchField,
|
||||||
|
const label pI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<fvsPatchField<Type>>(patchField)
|
||||||
|
&& !isA<emptyFvsPatchField<Type>>(patchField)
|
||||||
|
&& patchField.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
toBeStoredUniformOrNot_[pI] = true;
|
||||||
|
// Store processor boundaries even if they are not uniform.
|
||||||
|
// Not sure what will happen at a latter time-step for
|
||||||
|
// compression techniques using time-windows, such as iPGD
|
||||||
|
// Processor check only valid for surfaceFields since volFields
|
||||||
|
// wont enter here due to !isA<coupledFvPatch>
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!patchField.uniform()
|
||||||
|
|| storageParams_.storeUniformBoundaries()
|
||||||
|
|| isA<processorFvsPatchField<Type>>(patchField)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
toBeStored_[pI] = true;
|
||||||
|
}
|
||||||
|
// At boundaries with a near-zero value of flux, store a
|
||||||
|
// (single) zero value for phi. This was added after ZFP
|
||||||
|
// crashed trying to compress single-precision values of the
|
||||||
|
// iPGD modes with magnitude below 5.e-30. That problem does
|
||||||
|
// not arise if these values are represented in
|
||||||
|
// double-precision. In case that the maximum flux magnitude
|
||||||
|
// is lower than 1.e-15, it is assumed that the field should
|
||||||
|
// be zero and the non-zero values arise due to arithmetic
|
||||||
|
// error. This threshold has been arbitrarily chosen.
|
||||||
|
// Target patch types (although not checked in the code):
|
||||||
|
// wall, symmetryPlane
|
||||||
|
|
||||||
|
// surfacePatchesToBeZeroed becomes true only in case that phi at the
|
||||||
|
// corresponding patch must be stored (toBeStoredUniformOrNot = true)
|
||||||
|
// and is not uniform (patchField.uniform() = false)
|
||||||
|
if (toBeStored_[pI])
|
||||||
|
{
|
||||||
|
// Do the magnitude check here, to avoid unnecessary max
|
||||||
|
// mag calculations
|
||||||
|
if (max(mag(patchField)) < 1.e-15)
|
||||||
|
{
|
||||||
|
toBeStored_[pI] = false;
|
||||||
|
surfacePatchesToBeZeroed_[pI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::checkFvPatchFieldStorage
|
||||||
|
(
|
||||||
|
const PatchField<Type>& patchField,
|
||||||
|
const label pI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvPatch& patch = mesh_.boundary()[pI];
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<fvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<emptyFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<coupledFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<wallFvPatch>(patch)
|
||||||
|
&& !isA<cyclicAMIFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<zeroGradientFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<inletOutletFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<outletInletFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<freestreamFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<slipFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<symmetryFvPatchField<Type>>(patchField)
|
||||||
|
&& !isA<symmetryPlaneFvPatchField<Type>>(patchField)
|
||||||
|
&& patchField.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
toBeStoredUniformOrNot_[pI] = true;
|
||||||
|
if (!patchField.uniform() || storageParams_.storeUniformBoundaries())
|
||||||
|
{
|
||||||
|
toBeStored_[pI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::setValidComponent()
|
||||||
|
{
|
||||||
|
validCompon_ = 0;
|
||||||
|
if (!solDirs_[0])
|
||||||
|
{
|
||||||
|
validCompon_ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::computeSize()
|
||||||
|
{
|
||||||
|
initialSize_ = Zero;
|
||||||
|
uncompressedRoughSize_ = Zero;
|
||||||
|
totalSize_ = Zero;
|
||||||
|
const Field<Type>& internalField = field_.primitiveField();
|
||||||
|
for (label cmptI = 0; cmptI < pTraits<Type>::nComponents; ++cmptI)
|
||||||
|
{
|
||||||
|
initialSize_ += internalField.size()*sizeof(scalar);
|
||||||
|
if (solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
uncompressedRoughSize_ += internalField.size()*sizeof(scalar);
|
||||||
|
totalSize_ += internalField.size();
|
||||||
|
}
|
||||||
|
forAll(mesh_.boundary(), pI)
|
||||||
|
{
|
||||||
|
const Field<Type>& boundaryField = field_.boundaryField()[pI];
|
||||||
|
initialSize_ += boundaryField.size()*sizeof(scalar);
|
||||||
|
if (toBeStored_[pI] && solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
uncompressedRoughSize_ += boundaryField.size()*sizeof(scalar);
|
||||||
|
totalSize_ += boundaryField.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::gatherStorageMetrics()
|
||||||
|
{
|
||||||
|
if (!timing_)
|
||||||
|
{
|
||||||
|
for (scalar& sm : storageMetrics_)
|
||||||
|
{
|
||||||
|
reduce(sm, sumOp<scalar>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void
|
||||||
|
compressedGeometricField<scalar, fvPatchField, volMesh>::handleParticularities
|
||||||
|
(
|
||||||
|
volScalarField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Due to compression error, turbulence variables might take on
|
||||||
|
// negative values. Correct here
|
||||||
|
// TODO: A little dangerous way to identify turbuelence fields
|
||||||
|
if (iPtr_ == 3 || iPtr_ == 4)
|
||||||
|
{
|
||||||
|
bound(field, dimensionedScalar(field.dimensions(), Zero));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void
|
||||||
|
compressedGeometricField<vector, fvPatchField, volMesh>::handleParticularities
|
||||||
|
(
|
||||||
|
volVectorField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vectorField& internalField = field_.primitiveFieldRef();
|
||||||
|
const labelList& cellIDs = storageParams_.wallList();
|
||||||
|
label cellCounter(0);
|
||||||
|
forAll(cellIDs, i)
|
||||||
|
{
|
||||||
|
vector& vec = internalField[cellIDs[i]];
|
||||||
|
if (mag(vec) < SMALL)
|
||||||
|
{
|
||||||
|
cellCounter++;
|
||||||
|
forAll(vec, j)
|
||||||
|
{
|
||||||
|
if (solDirs_[j])
|
||||||
|
{
|
||||||
|
vec[j] = SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebugInfo
|
||||||
|
<< "Modified " << field.name() << " in " << cellCounter
|
||||||
|
<< " cell(s) next to wall boundaries" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void
|
||||||
|
compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::handleParticularities
|
||||||
|
(
|
||||||
|
surfaceScalarField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void compressedGeometricField<scalar, fvPatchField, volMesh>::correctBCs
|
||||||
|
(
|
||||||
|
volScalarField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
handleParticularities(field);
|
||||||
|
if (!storageParams_.storeAllBoundaries())
|
||||||
|
{
|
||||||
|
field.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void compressedGeometricField<vector, fvPatchField, volMesh>::correctBCs
|
||||||
|
(
|
||||||
|
volVectorField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
handleParticularities(field);
|
||||||
|
if (!storageParams_.storeAllBoundaries())
|
||||||
|
{
|
||||||
|
field.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void
|
||||||
|
compressedGeometricField<scalar, fvsPatchField, surfaceMesh>::correctBCs
|
||||||
|
(
|
||||||
|
surfaceScalarField& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::compressedGeometricField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
):
|
||||||
|
field_(field),
|
||||||
|
iPtr_(iPtr),
|
||||||
|
|
||||||
|
dict_(storageParams.dict()),
|
||||||
|
mesh_(field.mesh()),
|
||||||
|
validCompon_(0),
|
||||||
|
k_(k),
|
||||||
|
|
||||||
|
storageParams_(storageParams),
|
||||||
|
timing_(storageParams.timing()),
|
||||||
|
solDirs_(storageParams.solDirs()),
|
||||||
|
eps_(1.e-12),
|
||||||
|
|
||||||
|
storageMetrics_(4, Zero),
|
||||||
|
initialSize_(storageMetrics_[0]),
|
||||||
|
uncompressedRoughSize_(storageMetrics_[1]),
|
||||||
|
uncompressedSize_(storageMetrics_[2]),
|
||||||
|
compressedSize_(storageMetrics_[3]),
|
||||||
|
totalSize_(Zero)
|
||||||
|
{
|
||||||
|
if (Pstream::master()) counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
autoPtr<compressedGeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::New
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& type = storageParams.compressionMethod()[iPtr];
|
||||||
|
auto cstrIter = dictionaryConstructorTablePtr_->cfind(type);
|
||||||
|
|
||||||
|
if (!cstrIter.found())
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(storageParams.dict())
|
||||||
|
<< "Unknown compressedGeometricField type " << type << nl << nl
|
||||||
|
<< "Valid compressedGeometricField types are :" << nl
|
||||||
|
<< dictionaryConstructorTablePtr_->sortedToc()
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<compressedGeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
(cstrIter()( field, storageParams, iPtr, k ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::compress()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::decompress
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void compressedGeometricField<Type, PatchField, GeoMesh>::decompress()
|
||||||
|
{
|
||||||
|
this->decompress(field_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
const word& compressedGeometricField<Type, PatchField, GeoMesh>::name() const
|
||||||
|
{
|
||||||
|
return field_.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
const scalarList&
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::storageMetrics() const
|
||||||
|
{
|
||||||
|
return storageMetrics_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,354 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
compressedGeometricField
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for compression and decompression of the primal fields
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
compressedGeometricField.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef compressedGeometricField_H
|
||||||
|
#define compressedGeometricField_H
|
||||||
|
|
||||||
|
#include "GeometricField.H"
|
||||||
|
#include "fieldTypes.H"
|
||||||
|
#include "storageParameters.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class compressedGeometricField Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
class compressedGeometricField
|
||||||
|
{
|
||||||
|
static label counter;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
compressedGeometricField(const compressedGeometricField&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const compressedGeometricField&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Reference to the field to be compressed,
|
||||||
|
//- i.e. the field used from primalSolver
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field_;
|
||||||
|
|
||||||
|
//- Name of the field to be compressed
|
||||||
|
const label iPtr_;
|
||||||
|
|
||||||
|
const dictionary dict_;
|
||||||
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
//- Is the first non-empty direction
|
||||||
|
label validCompon_;
|
||||||
|
|
||||||
|
//- Current S/N of the time-step that is compressed in the present
|
||||||
|
//- object
|
||||||
|
const label& k_;
|
||||||
|
|
||||||
|
//- Reference to the compression parameters
|
||||||
|
storageParameters& storageParams_;
|
||||||
|
|
||||||
|
//- Are all unnecessary actions are avoided to benchmark the code?
|
||||||
|
const bool timing_;
|
||||||
|
|
||||||
|
//- The vector of solved-for directions in mesh.
|
||||||
|
// 1 indicates valid direction and -1 an invalid direction.
|
||||||
|
const Vector<label>& solDirs_;
|
||||||
|
|
||||||
|
//- Per patch, whether to store/compress fields using the
|
||||||
|
//- appropriate algorithm.
|
||||||
|
// Patches with uniform BCs, if a single value is chosen to be
|
||||||
|
// stored for them, have a false value
|
||||||
|
boolList toBeStored_;
|
||||||
|
|
||||||
|
//- Per patch of a surfaceScalarField, whether they must be zeroed
|
||||||
|
//- upon retrieval.
|
||||||
|
// To do so a zero value is stored for each of them.
|
||||||
|
boolList surfacePatchesToBeZeroed_;
|
||||||
|
|
||||||
|
//- Per patch, whether to store/compress fields using the
|
||||||
|
//- appropriate algorithm, irrespective of storing a uniform or
|
||||||
|
//- non-uniform value
|
||||||
|
boolList toBeStoredUniformOrNot_;
|
||||||
|
|
||||||
|
//- Threshold to avoid division with Zero
|
||||||
|
scalar eps_;
|
||||||
|
|
||||||
|
//- List holding all of the storageMetrics information
|
||||||
|
scalarList storageMetrics_;
|
||||||
|
|
||||||
|
//- Initial memory size of the field
|
||||||
|
scalar& initialSize_;
|
||||||
|
|
||||||
|
//- Initial memory size of the part of the field, which will be stored
|
||||||
|
// (e.g. excluding the coupled patches)
|
||||||
|
scalar& uncompressedRoughSize_;
|
||||||
|
|
||||||
|
//- Initial memory size of the part of the field that is sent to Zfp
|
||||||
|
//- compressor.
|
||||||
|
// It may be larger than uncompressedRoughSize_, if
|
||||||
|
// rearrangementType=2 and meshMode_=1. Needed to compute the pure
|
||||||
|
// compression ratio of zfp.
|
||||||
|
scalar& uncompressedSize_;
|
||||||
|
|
||||||
|
//- Compressed memory size of the field
|
||||||
|
scalar& compressedSize_;
|
||||||
|
|
||||||
|
//- Total size of elements at all lists to be compressed
|
||||||
|
label totalSize_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Fill in uniformBoundaryValuePtr_ with the uniform boundary field
|
||||||
|
//- values
|
||||||
|
virtual void storeUniformBoundaryValues() = 0;
|
||||||
|
|
||||||
|
//- Restore the uniform boundary field values based on what is stored
|
||||||
|
//- in uniformBoundaryValuePtr_
|
||||||
|
virtual void restoreUniformBoundaryValues
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
//- Const and non-const function to return a reference to
|
||||||
|
//- field[pos][componI] for a vectorField and to field[pos] for a
|
||||||
|
//- scalarField
|
||||||
|
inline scalar& getValue
|
||||||
|
(
|
||||||
|
Field<Type>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const;
|
||||||
|
|
||||||
|
inline const scalar& getValue
|
||||||
|
(
|
||||||
|
const Field<Type>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Const and non-const function to return a reference to
|
||||||
|
//- field[pos][componI] for a List<vector> and to field[pos] for a
|
||||||
|
//- List<scalar>
|
||||||
|
inline scalar& getValue
|
||||||
|
(
|
||||||
|
List<Type>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const;
|
||||||
|
|
||||||
|
inline const scalar& getValue
|
||||||
|
(
|
||||||
|
const List<Type>& field,
|
||||||
|
const label& pos,
|
||||||
|
const label& componI
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Fill in toBeSorted_ which defines if the scalarField component of
|
||||||
|
//- a boundary condition must be stored or not, per patch
|
||||||
|
// (empty, coupled and zero sized patches do not get stored)
|
||||||
|
virtual void toBeStored();
|
||||||
|
|
||||||
|
//- Since partial template specialization is not allowed,
|
||||||
|
//- define two different functions with the same arguments
|
||||||
|
//- and specialize checks there
|
||||||
|
void checkFvsPatchFieldStorage
|
||||||
|
(
|
||||||
|
const PatchField<Type>& patchField,
|
||||||
|
const label pI
|
||||||
|
);
|
||||||
|
|
||||||
|
void checkFvPatchFieldStorage
|
||||||
|
(
|
||||||
|
const PatchField<Type>& patchField,
|
||||||
|
const label patchI
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Compute initial size of the field to be compressed
|
||||||
|
void computeSize();
|
||||||
|
|
||||||
|
//- Construct a list containing all of the compression metrics
|
||||||
|
void gatherStorageMetrics();
|
||||||
|
|
||||||
|
//- Set a valid solution direction
|
||||||
|
void setValidComponent();
|
||||||
|
|
||||||
|
//- Called before correcting the BCs
|
||||||
|
// The function is specialized for the different geometric fields.
|
||||||
|
inline void handleParticularities
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Correct boundary conditions of coupled patches.
|
||||||
|
// The function is specialized for the different geometric fields.
|
||||||
|
inline void correctBCs
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("compressedGeometricField");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection tables
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
compressedGeometricField,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
),
|
||||||
|
(field, storageParams, iPtr, k)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
compressedGeometricField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
virtual ~compressedGeometricField() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a pointer to a new compressedGeometricField
|
||||||
|
static autoPtr<compressedGeometricField<Type, PatchField, GeoMesh>> New
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Compress the field
|
||||||
|
virtual void compress();
|
||||||
|
|
||||||
|
//- Decompress the field
|
||||||
|
virtual void decompress
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
void decompress();
|
||||||
|
|
||||||
|
const word& name() const;
|
||||||
|
|
||||||
|
//- Get a const reference to the compression metrics
|
||||||
|
virtual const scalarList& storageMetrics() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "compressedGeometricField.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Add the patch constructor functions to the hash tables
|
||||||
|
|
||||||
|
#define makeCompressedGeometricTypeField(SS, Type, PatchField, GeoMesh) \
|
||||||
|
typedef SS<Type, PatchField, GeoMesh> \
|
||||||
|
SS##Type##PatchField##GeoMesh##_; \
|
||||||
|
\
|
||||||
|
defineNamedTemplateTypeNameAndDebug \
|
||||||
|
(SS##Type##PatchField##GeoMesh##_, 0); \
|
||||||
|
\
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh> \
|
||||||
|
::adddictionaryConstructorToTable<SS<Type, PatchField, GeoMesh>> \
|
||||||
|
add##SS##Type##PatchField##GeoMesh##dictionaryConstructorToTable_; \
|
||||||
|
|
||||||
|
#define makeCompressedGeometricTypeFieldNoAdd(SS, Type, PatchField, GeoMesh) \
|
||||||
|
typedef SS<Type, PatchField, GeoMesh> \
|
||||||
|
SS##Type##PatchField##GeoMesh##_; \
|
||||||
|
\
|
||||||
|
defineNamedTemplateTypeNameAndDebug \
|
||||||
|
(SS##Type##PatchField##GeoMesh##_, 0);
|
||||||
|
|
||||||
|
#define makeCompressedGeometricField(SS) \
|
||||||
|
\
|
||||||
|
makeCompressedGeometricTypeField(SS, scalar, fvPatchField, volMesh) \
|
||||||
|
makeCompressedGeometricTypeField(SS, scalar, fvsPatchField, surfaceMesh) \
|
||||||
|
makeCompressedGeometricTypeField(SS, vector, fvPatchField, volMesh)
|
||||||
|
|
||||||
|
#define makeCompressedGeometricFieldNoAdd(SS) \
|
||||||
|
\
|
||||||
|
makeCompressedGeometricTypeFieldNoAdd(SS, scalar, fvPatchField, volMesh) \
|
||||||
|
makeCompressedGeometricTypeFieldNoAdd(SS, scalar, fvsPatchField, surfaceMesh) \
|
||||||
|
makeCompressedGeometricTypeFieldNoAdd(SS, vector, fvPatchField, volMesh)
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Released 2004-2011 OpenCFD Ltd.
|
||||||
|
Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "compressedGeometricFields.H"
|
||||||
|
#include "HashTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
// Define the constructor function hash tables
|
||||||
|
|
||||||
|
defineNamedTemplateTypeNameAndDebug(compressedVolScalarField, 0);
|
||||||
|
defineTemplateRunTimeSelectionTable(compressedVolScalarField, dictionary);
|
||||||
|
|
||||||
|
defineNamedTemplateTypeNameAndDebug(compressedSurfaceScalarField, 0);
|
||||||
|
defineTemplateRunTimeSelectionTable(compressedSurfaceScalarField, dictionary);
|
||||||
|
|
||||||
|
defineNamedTemplateTypeNameAndDebug(compressedVolVectorField, 0);
|
||||||
|
defineTemplateRunTimeSelectionTable(compressedVolVectorField, dictionary);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Released 2004-2011 OpenCFD Ltd.
|
||||||
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef compressedGeometricFields_H
|
||||||
|
#define compressedGeometricFields_H
|
||||||
|
|
||||||
|
#include "compressedGeometricField.H"
|
||||||
|
#include "compressedGeometricFieldsFwd.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
compressedGeometricField
|
||||||
|
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef compressedGeometricFieldsFwd_H
|
||||||
|
#define compressedGeometricFieldsFwd_H
|
||||||
|
|
||||||
|
#include "fieldTypes.H"
|
||||||
|
#include "fvPatchField.H"
|
||||||
|
#include "wordList.H"
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
class compressedGeometricField;
|
||||||
|
|
||||||
|
typedef compressedGeometricField<scalar, fvPatchField, volMesh> compressedVolScalarField;
|
||||||
|
typedef compressedGeometricField<scalar, fvsPatchField, surfaceMesh> compressedSurfaceScalarField;
|
||||||
|
typedef compressedGeometricField<vector, fvPatchField, volMesh> compressedVolVectorField;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,254 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "shortGeometricField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void
|
||||||
|
shortGeometricField<Type, PatchField, GeoMesh>::storeUniformBoundaryValues()
|
||||||
|
{
|
||||||
|
forAll(uniformBoundaryValuePtr_, pI)
|
||||||
|
{
|
||||||
|
const Field<Type>& boundaryField = this->field_.boundaryField()[pI];
|
||||||
|
if (this->toBeStoredUniformOrNot_[pI] && !this->toBeStored_[pI])
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
std::is_same<PatchField<Type>, fvsPatchField<Type>>::value
|
||||||
|
&& this->surfacePatchesToBeZeroed_[pI]
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// At this point, the maximum magnitude of the boundaryField is
|
||||||
|
// for sure below the prescribed threshold
|
||||||
|
uniformBoundaryValuePtr_.set(pI, new Type(Zero));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uniformBoundaryValuePtr_.set
|
||||||
|
(
|
||||||
|
pI, new Type(boundaryField.first())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void
|
||||||
|
shortGeometricField<Type, PatchField, GeoMesh>::restoreUniformBoundaryValues
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll(uniformBoundaryValuePtr_, pI)
|
||||||
|
{
|
||||||
|
Field<Type>& boundaryField = field.boundaryFieldRef()[pI];
|
||||||
|
if (uniformBoundaryValuePtr_(pI))
|
||||||
|
{
|
||||||
|
boundaryField = uniformBoundaryValuePtr_[pI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void shortGeometricField<Type, PatchField, GeoMesh>::initialize()
|
||||||
|
{
|
||||||
|
this->toBeStored();
|
||||||
|
this->computeSize();
|
||||||
|
this->uncompressedSize_ = this->uncompressedRoughSize_;
|
||||||
|
this->compressedSize_ = this->uncompressedRoughSize_;
|
||||||
|
setBuffers();
|
||||||
|
storeUniformBoundaryValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void shortGeometricField<Type, PatchField, GeoMesh>::setBuffers()
|
||||||
|
{
|
||||||
|
const Field<Type>& internalField = this->field_.primitiveField();
|
||||||
|
forAll(internalBufferPtr_, cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
internalBufferPtr_[cmptI].setSize(internalField.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAll (boundaryBufferPtr_, pI)
|
||||||
|
{
|
||||||
|
if (this->toBeStored_[pI])
|
||||||
|
{
|
||||||
|
boundaryBufferPtr_[pI].setSize(pTraits<Type>::nComponents);
|
||||||
|
const Field<Type>& boundaryField = this->field_.boundaryField()[pI];
|
||||||
|
forAll(boundaryBufferPtr_[pI], cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
boundaryBufferPtr_[pI][cmptI].setSize(boundaryField.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
shortGeometricField<Type, PatchField, GeoMesh>::shortGeometricField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
):
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>
|
||||||
|
(
|
||||||
|
field,
|
||||||
|
storageParams,
|
||||||
|
iPtr,
|
||||||
|
k
|
||||||
|
),
|
||||||
|
internalBufferPtr_(pTraits<Type>::nComponents),
|
||||||
|
boundaryBufferPtr_(field.mesh().boundary().size()),
|
||||||
|
uniformBoundaryValuePtr_(field.mesh().boundary().size())
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void shortGeometricField<Type, PatchField, GeoMesh>::compress()
|
||||||
|
{
|
||||||
|
const Field<Type>& internalField = this->field_.primitiveField();
|
||||||
|
forAll(internalBufferPtr_, cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
forAll(internalBufferPtr_[cmptI], iPtr)
|
||||||
|
{
|
||||||
|
internalBufferPtr_[cmptI][iPtr] =
|
||||||
|
this->getValue(internalField, iPtr, cmptI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAll(boundaryBufferPtr_, pI)
|
||||||
|
{
|
||||||
|
if (this->toBeStored_[pI])
|
||||||
|
{
|
||||||
|
const Field<Type>& boundaryField = this->field_.boundaryField()[pI];
|
||||||
|
for (label cmptI = 0; cmptI < pTraits<Type>::nComponents; ++cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
forAll(boundaryBufferPtr_[pI][cmptI], iPtr)
|
||||||
|
{
|
||||||
|
boundaryBufferPtr_[pI][cmptI][iPtr] =
|
||||||
|
this->getValue(boundaryField, iPtr, cmptI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->gatherStorageMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void shortGeometricField<Type, PatchField, GeoMesh>::decompress
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Field<Type>& internalField = field.primitiveFieldRef();
|
||||||
|
forAll(internalBufferPtr_, cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
forAll(internalBufferPtr_[cmptI], iPtr)
|
||||||
|
{
|
||||||
|
scalar& val = this->getValue(internalField, iPtr, cmptI);
|
||||||
|
val = internalBufferPtr_[cmptI][iPtr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*else
|
||||||
|
{
|
||||||
|
forAll(internalBufferPtr_[cmptI], iPtr)
|
||||||
|
{
|
||||||
|
scalar& val = this->getValue(internalField, iPtr, cmptI);
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
forAll(boundaryBufferPtr_, pI)
|
||||||
|
{
|
||||||
|
if (this->toBeStored_[pI])
|
||||||
|
{
|
||||||
|
Field<Type>& boundaryField = field.boundaryFieldRef()[pI];
|
||||||
|
for (label cmptI = 0; cmptI < pTraits<Type>::nComponents; ++cmptI)
|
||||||
|
{
|
||||||
|
if (this->solDirs_[cmptI])
|
||||||
|
{
|
||||||
|
forAll(boundaryBufferPtr_[pI][cmptI], iPtr)
|
||||||
|
{
|
||||||
|
scalar& val =
|
||||||
|
this->getValue(boundaryField, iPtr, cmptI);
|
||||||
|
val = boundaryBufferPtr_[pI][cmptI][iPtr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*else
|
||||||
|
{
|
||||||
|
forAll (boundaryBufferPtr_[pI], iPtr)
|
||||||
|
{
|
||||||
|
scalar& val = this->getValue(boundaryField, iPtr, cmptI);
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->restoreUniformBoundaryValues(field);
|
||||||
|
this->correctBCs(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
shortGeometricField
|
||||||
|
|
||||||
|
Description
|
||||||
|
Stores only the current state of a GeometricField (i.e. not oldTimes).
|
||||||
|
Additionally, avoids storing patchFields that can be retrieved through
|
||||||
|
correctBoundaryConditions (e.g. uniform fields, coupled, symmetry, etc)
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
shortGeometricField.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef shortGeometricField_H
|
||||||
|
#define shortGeometricField_H
|
||||||
|
|
||||||
|
#include "compressedGeometricField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class shortGeometricField Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
class shortGeometricField
|
||||||
|
:
|
||||||
|
public compressedGeometricField<Type, PatchField, GeoMesh>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Storage of the internalField deceomposed into multiple
|
||||||
|
//- scalarFields
|
||||||
|
List<scalarField> internalBufferPtr_;
|
||||||
|
|
||||||
|
//- Storage of the boundaryField deceomposed into multiple
|
||||||
|
//- scalarFields per patch
|
||||||
|
List<List<scalarField>> boundaryBufferPtr_;
|
||||||
|
|
||||||
|
//- Holds the uniform value for patches with such boundary conditions.
|
||||||
|
// Allocated only on these patches
|
||||||
|
PtrList<Type> uniformBoundaryValuePtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Fill in uniformBoundaryValuePtr_ with the uniform boundary field
|
||||||
|
//- values
|
||||||
|
void storeUniformBoundaryValues() override;
|
||||||
|
|
||||||
|
//- Restore the uniform boundary field values based on what is stored
|
||||||
|
//- in uniformBoundaryValuePtr_
|
||||||
|
void restoreUniformBoundaryValues
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
) override;
|
||||||
|
|
||||||
|
//- Initialize necessary parameters
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
//- Set sizes for internalBufferPtr_ and boundaryBufferPtr_
|
||||||
|
void setBuffers();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("shortGeometricField");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
shortGeometricField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
const label iPtr,
|
||||||
|
const label& k
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructors
|
||||||
|
virtual ~shortGeometricField() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Store field
|
||||||
|
void compress() override;
|
||||||
|
|
||||||
|
//- Retrieve field
|
||||||
|
void decompress
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "shortGeometricField.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "shortGeometricField.H"
|
||||||
|
#include "HashTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
makeCompressedGeometricField(shortGeometricField)
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -67,7 +67,8 @@ objectiveManager::objectiveManager
|
|||||||
adjointSolverName_(adjointSolverName),
|
adjointSolverName_(adjointSolverName),
|
||||||
primalSolverName_(primalSolverName),
|
primalSolverName_(primalSolverName),
|
||||||
objectives_(0),
|
objectives_(0),
|
||||||
weigthedObjectiveFile_(nullptr)
|
weigthedObjectiveFile_(nullptr),
|
||||||
|
hasIntegrationTimes_(true)
|
||||||
{
|
{
|
||||||
// Construct objectives
|
// Construct objectives
|
||||||
//~~~~~~~~~~~~~~~~~~~~~
|
//~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -182,6 +183,12 @@ bool objectiveManager::readDict(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool objectiveManager::hasIntegrationTimes() const
|
||||||
|
{
|
||||||
|
return hasIntegrationTimes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void objectiveManager::updateNormalizationFactor()
|
void objectiveManager::updateNormalizationFactor()
|
||||||
{
|
{
|
||||||
// Update normalization factors for all objectives
|
// Update normalization factors for all objectives
|
||||||
@ -252,6 +259,24 @@ scalar objectiveManager::print()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void objectiveManager::setWrite(const bool shouldWrite)
|
||||||
|
{
|
||||||
|
for (objective& obj : objectives_)
|
||||||
|
{
|
||||||
|
obj.setWrite(shouldWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void objectiveManager::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
for (objective& obj : objectives_)
|
||||||
|
{
|
||||||
|
obj.setWriteOption(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool objectiveManager::writeObjectives
|
bool objectiveManager::writeObjectives
|
||||||
(
|
(
|
||||||
const scalar weightedObjective,
|
const scalar weightedObjective,
|
||||||
@ -261,8 +286,8 @@ bool objectiveManager::writeObjectives
|
|||||||
for (const objective& obj : objectives_)
|
for (const objective& obj : objectives_)
|
||||||
{
|
{
|
||||||
// Write objective function to file
|
// Write objective function to file
|
||||||
obj.write();
|
obj.write();
|
||||||
obj.writeMeanValue();
|
obj.writeMeanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weigthedObjectiveFile_.valid())
|
if (weigthedObjectiveFile_.valid())
|
||||||
@ -317,16 +342,13 @@ const word& objectiveManager::primalSolverName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void objectiveManager::checkIntegrationTimes() const
|
void objectiveManager::checkIntegrationTimes()
|
||||||
{
|
{
|
||||||
for (const objective& obj : objectives_)
|
for (const objective& obj : objectives_)
|
||||||
{
|
{
|
||||||
if (!obj.hasIntegrationStartTime() || !obj.hasIntegrationEndTime())
|
if (!obj.hasIntegrationStartTime() || !obj.hasIntegrationEndTime())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction()
|
hasIntegrationTimes_ = false;
|
||||||
<< "Objective function " << obj.objectiveName()
|
|
||||||
<< " does not have a defined integration start or end time "
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -66,6 +66,7 @@ protected:
|
|||||||
const word primalSolverName_;
|
const word primalSolverName_;
|
||||||
PtrList<objective> objectives_;
|
PtrList<objective> objectives_;
|
||||||
autoPtr<OFstream> weigthedObjectiveFile_;
|
autoPtr<OFstream> weigthedObjectiveFile_;
|
||||||
|
bool hasIntegrationTimes_;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -130,6 +131,12 @@ public:
|
|||||||
|
|
||||||
virtual bool readDict(const dictionary& dict);
|
virtual bool readDict(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Boolean defining if all objectives have defined their integration
|
||||||
|
// window.
|
||||||
|
// false if at least one of the objectives has an undefined
|
||||||
|
// integration window
|
||||||
|
bool hasIntegrationTimes() const;
|
||||||
|
|
||||||
//- Update objective function related values
|
//- Update objective function related values
|
||||||
void updateNormalizationFactor();
|
void updateNormalizationFactor();
|
||||||
|
|
||||||
@ -145,6 +152,12 @@ public:
|
|||||||
//- Print to screen
|
//- Print to screen
|
||||||
scalar print();
|
scalar print();
|
||||||
|
|
||||||
|
//- Set write option for objectives (files in the optimisation folder)
|
||||||
|
void setWrite(const bool shouldWrite);
|
||||||
|
|
||||||
|
//- Set write option for the localIOdictionary base of the objectives
|
||||||
|
void setWriteOption(IOobject::writeOption w);
|
||||||
|
|
||||||
//- Write objective function history
|
//- Write objective function history
|
||||||
virtual bool writeObjectives
|
virtual bool writeObjectives
|
||||||
(
|
(
|
||||||
@ -172,7 +185,7 @@ public:
|
|||||||
const word& primalSolverName() const;
|
const word& primalSolverName() const;
|
||||||
|
|
||||||
//- Check integration times for unsteady runs
|
//- Check integration times for unsteady runs
|
||||||
void checkIntegrationTimes() const;
|
void checkIntegrationTimes();
|
||||||
|
|
||||||
//- Add contribution to adjoint momentum PDEs
|
//- Add contribution to adjoint momentum PDEs
|
||||||
virtual void addUaEqnSource(fvVectorMatrix& UaEqn) = 0;
|
virtual void addUaEqnSource(fvVectorMatrix& UaEqn) = 0;
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2020 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2020 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -131,6 +131,7 @@ objective::objective
|
|||||||
computeMeanFields_(false), // is reset in derived classes
|
computeMeanFields_(false), // is reset in derived classes
|
||||||
nullified_(false),
|
nullified_(false),
|
||||||
normalize_(dict.getOrDefault<bool>("normalize", false)),
|
normalize_(dict.getOrDefault<bool>("normalize", false)),
|
||||||
|
shouldWrite_(true),
|
||||||
|
|
||||||
J_(Zero),
|
J_(Zero),
|
||||||
JMean_(this->getOrDefault<scalar>("JMean", Zero)),
|
JMean_(this->getOrDefault<scalar>("JMean", Zero)),
|
||||||
@ -172,14 +173,22 @@ objective::objective
|
|||||||
{
|
{
|
||||||
integrationStartTimePtr_.reset
|
integrationStartTimePtr_.reset
|
||||||
(
|
(
|
||||||
new scalar(dict.get<scalar>("integrationStartTime"))
|
new scalar
|
||||||
|
(
|
||||||
|
dict.get<scalar>("integrationStartTime") +
|
||||||
|
mesh_.time().value()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (dict.found("integrationEndTime"))
|
if (dict.found("integrationEndTime"))
|
||||||
{
|
{
|
||||||
integrationEndTimePtr_.reset
|
integrationEndTimePtr_.reset
|
||||||
(
|
(
|
||||||
new scalar(dict.get<scalar>("integrationEndTime"))
|
new scalar
|
||||||
|
(
|
||||||
|
dict.get<scalar>("integrationEndTime") +
|
||||||
|
mesh_.time().value()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,17 +308,22 @@ void objective::accumulateJMean(solverControl& solverControl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void objective::resetJMean()
|
||||||
|
{
|
||||||
|
JMean_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void objective::accumulateJMean()
|
void objective::accumulateJMean()
|
||||||
{
|
{
|
||||||
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||||
{
|
{
|
||||||
const scalar time = mesh_.time().value();
|
|
||||||
if (isWithinIntegrationTime())
|
if (isWithinIntegrationTime())
|
||||||
{
|
{
|
||||||
const scalar dt = mesh_.time().deltaT().value();
|
const scalar dt = mesh_.time().deltaTValue();
|
||||||
const scalar elapsedTime = time - integrationStartTimePtr_();
|
const scalar elapsedTime
|
||||||
const scalar denom = elapsedTime + dt;
|
= mesh_.time().value() - integrationStartTimePtr_();
|
||||||
JMean_ = (JMean_*elapsedTime + J_*dt)/denom;
|
JMean_ = (JMean_*elapsedTime + J_*dt)/(elapsedTime + dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -384,10 +398,11 @@ bool objective::isWithinIntegrationTime() const
|
|||||||
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||||
{
|
{
|
||||||
const scalar time = mesh_.time().value();
|
const scalar time = mesh_.time().value();
|
||||||
|
const scalar dt = mesh_.time().deltaTValue();
|
||||||
return
|
return
|
||||||
(
|
(
|
||||||
time >= integrationStartTimePtr_()
|
time >= (integrationStartTimePtr_() - 0.1*dt)
|
||||||
&& time <= integrationEndTimePtr_()
|
&& time <= (integrationEndTimePtr_() + 1.1*dt)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -413,6 +428,8 @@ void objective::incrementIntegrationTimes(const scalar timeSpan)
|
|||||||
<< "Unallocated integration start or end time"
|
<< "Unallocated integration start or end time"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
// Set nullified_ to false for the next optimization cycle
|
||||||
|
nullified_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -659,7 +676,7 @@ void objective::nullify()
|
|||||||
|
|
||||||
bool objective::write(const bool valid) const
|
bool objective::write(const bool valid) const
|
||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master() && shouldWrite_)
|
||||||
{
|
{
|
||||||
// File is opened only upon invocation of the write function
|
// File is opened only upon invocation of the write function
|
||||||
// in order to avoid various instantiations of the same objective
|
// in order to avoid various instantiations of the same objective
|
||||||
@ -732,7 +749,7 @@ void objective::writeInstantaneousSeparator() const
|
|||||||
|
|
||||||
void objective::writeMeanValue() const
|
void objective::writeMeanValue() const
|
||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master() && shouldWrite_)
|
||||||
{
|
{
|
||||||
// Write mean value if necessary
|
// Write mean value if necessary
|
||||||
// Covers both steady and unsteady runs
|
// Covers both steady and unsteady runs
|
||||||
@ -742,8 +759,8 @@ void objective::writeMeanValue() const
|
|||||||
|| (hasIntegrationStartTime() && hasIntegrationEndTime())
|
|| (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// File is opened only upon invocation of the write function
|
// File is opened only upon invocation of the write function in
|
||||||
// in order to avoid various instantiations of the same objective
|
// order to avoid various instantiations of the same objective
|
||||||
// opening the same file
|
// opening the same file
|
||||||
if (!meanValueFilePtr_)
|
if (!meanValueFilePtr_)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2020 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2020 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -73,6 +73,7 @@ protected:
|
|||||||
bool computeMeanFields_;
|
bool computeMeanFields_;
|
||||||
bool nullified_;
|
bool nullified_;
|
||||||
bool normalize_;
|
bool normalize_;
|
||||||
|
bool shouldWrite_;
|
||||||
|
|
||||||
//- Objective function value and weight
|
//- Objective function value and weight
|
||||||
scalar J_;
|
scalar J_;
|
||||||
@ -253,6 +254,9 @@ public:
|
|||||||
// For unsteady runs
|
// For unsteady runs
|
||||||
void accumulateJMean();
|
void accumulateJMean();
|
||||||
|
|
||||||
|
//- Nullify JMean. To be used in unsteady optimization.
|
||||||
|
void resetJMean();
|
||||||
|
|
||||||
//- Return the objective function weight
|
//- Return the objective function weight
|
||||||
scalar weight() const;
|
scalar weight() const;
|
||||||
|
|
||||||
@ -392,6 +396,15 @@ public:
|
|||||||
//- Return the objective name
|
//- Return the objective name
|
||||||
inline const word& objectiveName() const;
|
inline const word& objectiveName() const;
|
||||||
|
|
||||||
|
//- Should the objective be written to file upon calling write()?
|
||||||
|
inline bool shouldWrite() const;
|
||||||
|
|
||||||
|
//- Set the shouldWrite_ flag (files in the optimisation folder)
|
||||||
|
inline void setWrite(const bool shouldWrite);
|
||||||
|
|
||||||
|
//- Set the write option of the base localIOdictionary
|
||||||
|
inline void setWriteOption(IOobject::writeOption w);
|
||||||
|
|
||||||
// Inline functions for checking whether pointers are set or not
|
// Inline functions for checking whether pointers are set or not
|
||||||
inline bool hasdJdb() const;
|
inline bool hasdJdb() const;
|
||||||
inline bool hasBoundarydJdb() const;
|
inline bool hasBoundarydJdb() const;
|
||||||
|
|||||||
@ -36,6 +36,24 @@ inline const Foam::word& Foam::objective::objectiveName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::objective::shouldWrite() const
|
||||||
|
{
|
||||||
|
return shouldWrite_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::objective::setWrite(const bool shouldWrite)
|
||||||
|
{
|
||||||
|
shouldWrite_ = shouldWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::objective::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
IOobject::writeOpt() = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::objective::hasdJdb() const
|
inline bool Foam::objective::hasdJdb() const
|
||||||
{
|
{
|
||||||
return bool(dJdbPtr_);
|
return bool(dJdbPtr_);
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -38,28 +38,137 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::optimisationManager::optimisationManager(fvMesh& mesh)
|
void Foam::optimisationManager::resetTime()
|
||||||
:
|
{
|
||||||
IOdictionary
|
// Does nothing in base
|
||||||
(
|
}
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"optimisationDict",
|
void Foam::optimisationManager::lineSearchUpdate()
|
||||||
mesh.time().system(),
|
{
|
||||||
mesh,
|
// Compute direction of update
|
||||||
IOobject::MUST_READ_IF_MODIFIED,
|
tmp<scalarField> tdirection = optType_->computeDirection();
|
||||||
IOobject::NO_WRITE,
|
scalarField& direction = tdirection.ref();
|
||||||
true
|
|
||||||
)
|
// Grab reference to line search
|
||||||
),
|
autoPtr<lineSearch>& lineSrch = optType_->getLineSearch();
|
||||||
mesh_(mesh),
|
|
||||||
time_(const_cast<Time&>(mesh.time())),
|
// Store starting point
|
||||||
primalSolvers_(),
|
optType_->storeDesignVariables();
|
||||||
adjointSolverManagers_(),
|
|
||||||
managerType_(get<word>("optimisationManager")),
|
// Compute merit function before update
|
||||||
optType_(nullptr)
|
scalar meritFunction = optType_->computeMeritFunction();
|
||||||
|
lineSrch->setOldMeritValue(meritFunction);
|
||||||
|
|
||||||
|
// Get merit function derivative
|
||||||
|
const scalar dirDerivative =
|
||||||
|
optType_->meritFunctionDirectionalDerivative();
|
||||||
|
lineSrch->setDeriv(dirDerivative);
|
||||||
|
lineSrch->setDirection(direction);
|
||||||
|
|
||||||
|
// Reset initial step.
|
||||||
|
// Might be interpolated from previous optimisation cycles
|
||||||
|
lineSrch->reset();
|
||||||
|
|
||||||
|
// Perform line search
|
||||||
|
for (label iter = 0; iter < lineSrch->maxIters(); ++iter)
|
||||||
|
{
|
||||||
|
Info<< "\n- - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Line search iteration " << iter << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - -\n" << endl;
|
||||||
|
|
||||||
|
// Update design variables. Multiplication with line search step
|
||||||
|
// happens inside the update(direction) function
|
||||||
|
moveDesignVariables(direction);
|
||||||
|
|
||||||
|
// Solve all primal equations
|
||||||
|
solvePrimalEquations();
|
||||||
|
|
||||||
|
// Compute and set new merit function
|
||||||
|
meritFunction = optType_->computeMeritFunction();
|
||||||
|
lineSrch->setNewMeritValue(meritFunction);
|
||||||
|
|
||||||
|
if (lineSrch->converged())
|
||||||
|
{
|
||||||
|
// If line search criteria have been met, proceed
|
||||||
|
Info<< "Line search converged in " << iter + 1
|
||||||
|
<< " iterations." << endl;
|
||||||
|
scalarField scaledCorrection(lineSrch->step()*direction);
|
||||||
|
optType_->updateOldCorrection(scaledCorrection);
|
||||||
|
optType_->write();
|
||||||
|
lineSrch()++;
|
||||||
|
postUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If maximum number of iteration has been reached, continue
|
||||||
|
if (iter == lineSrch->maxIters() - 1)
|
||||||
|
{
|
||||||
|
Info<< "Line search reached max. number of iterations.\n"
|
||||||
|
<< "Proceeding to the next optimisation cycle" << endl;
|
||||||
|
scalarField scaledCorrection(lineSrch->step()*direction);
|
||||||
|
optType_->updateOldCorrection(scaledCorrection);
|
||||||
|
optType_->write();
|
||||||
|
lineSrch()++;
|
||||||
|
postUpdate();
|
||||||
|
}
|
||||||
|
// Reset to initial design variables and update step
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resetTime();
|
||||||
|
optType_->resetDesignVariables();
|
||||||
|
lineSrch->updateStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::fixedStepUpdate()
|
||||||
|
{
|
||||||
|
moveDesignVariables();
|
||||||
|
|
||||||
|
// Solve primal equations
|
||||||
|
solvePrimalEquations();
|
||||||
|
postUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::postUpdate()
|
||||||
|
{
|
||||||
|
for (primalSolver& solver : primalSolvers_)
|
||||||
|
{
|
||||||
|
solver.postLineSearch();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (adjointSolverManager& manager : adjointSolverManagers_)
|
||||||
|
{
|
||||||
|
manager.postLineSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::moveDesignVariables()
|
||||||
|
{
|
||||||
|
// Update design variables
|
||||||
|
optType_->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::moveDesignVariables
|
||||||
|
(
|
||||||
|
scalarField& direction
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Update design variables
|
||||||
|
optType_->update(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::initialize()
|
||||||
{
|
{
|
||||||
dictionary& primalSolversDict = subDict("primalSolvers");
|
dictionary& primalSolversDict = subDict("primalSolvers");
|
||||||
const wordList& primalSolverNames = primalSolversDict.toc();
|
const wordList& primalSolverNames = primalSolversDict.toc();
|
||||||
@ -79,7 +188,7 @@ Foam::optimisationManager::optimisationManager(fvMesh& mesh)
|
|||||||
solveri,
|
solveri,
|
||||||
primalSolver::New
|
primalSolver::New
|
||||||
(
|
(
|
||||||
mesh,
|
mesh_,
|
||||||
managerType_,
|
managerType_,
|
||||||
solverDict
|
solverDict
|
||||||
)
|
)
|
||||||
@ -100,7 +209,7 @@ Foam::optimisationManager::optimisationManager(fvMesh& mesh)
|
|||||||
manageri,
|
manageri,
|
||||||
new adjointSolverManager
|
new adjointSolverManager
|
||||||
(
|
(
|
||||||
mesh,
|
mesh_,
|
||||||
managerType_,
|
managerType_,
|
||||||
adjointManagersDict.subDict(adjointManagerNames[manageri]),
|
adjointManagersDict.subDict(adjointManagerNames[manageri]),
|
||||||
overrideUseSolverName
|
overrideUseSolverName
|
||||||
@ -148,6 +257,33 @@ Foam::optimisationManager::optimisationManager(fvMesh& mesh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::optimisationManager::optimisationManager(fvMesh& mesh)
|
||||||
|
:
|
||||||
|
IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"optimisationDict",
|
||||||
|
mesh.time().system(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ_IF_MODIFIED,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
),
|
||||||
|
mesh_(mesh),
|
||||||
|
time_(const_cast<Time&>(mesh.time())),
|
||||||
|
primalSolvers_(),
|
||||||
|
adjointSolverManagers_(),
|
||||||
|
managerType_(get<word>("optimisationManager")),
|
||||||
|
optType_(nullptr),
|
||||||
|
shouldUpdateDesignVariables_(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::autoPtr<Foam::optimisationManager> Foam::optimisationManager::New
|
Foam::autoPtr<Foam::optimisationManager> Foam::optimisationManager::New
|
||||||
@ -215,6 +351,24 @@ bool Foam::optimisationManager::read()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::updateDesignVariables()
|
||||||
|
{
|
||||||
|
// Update design variables using either a line-search scheme or
|
||||||
|
// a fixed-step update
|
||||||
|
if (optType_->getLineSearch())
|
||||||
|
{
|
||||||
|
lineSearchUpdate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixedStepUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset adjoint sensitivities in all adjoint solver managers
|
||||||
|
clearSensitivities();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::PtrList<Foam::primalSolver>& Foam::optimisationManager::primalSolvers()
|
Foam::PtrList<Foam::primalSolver>& Foam::optimisationManager::primalSolvers()
|
||||||
{
|
{
|
||||||
return primalSolvers_;
|
return primalSolvers_;
|
||||||
@ -230,10 +384,9 @@ Foam::optimisationManager::adjointSolverManagers()
|
|||||||
|
|
||||||
void Foam::optimisationManager::solvePrimalEquations()
|
void Foam::optimisationManager::solvePrimalEquations()
|
||||||
{
|
{
|
||||||
// Solve all primal equations
|
for (primalSolver& solver : primalSolvers_)
|
||||||
forAll(primalSolvers_, psI)
|
|
||||||
{
|
{
|
||||||
primalSolvers_[psI].solve();
|
solver.solve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,9 +394,9 @@ void Foam::optimisationManager::solvePrimalEquations()
|
|||||||
void Foam::optimisationManager::solveAdjointEquations()
|
void Foam::optimisationManager::solveAdjointEquations()
|
||||||
{
|
{
|
||||||
// Solve all adjoint solver equations
|
// Solve all adjoint solver equations
|
||||||
forAll(adjointSolverManagers_, amI)
|
for (adjointSolverManager& manager : adjointSolverManagers_)
|
||||||
{
|
{
|
||||||
adjointSolverManagers_[amI].solveAdjointEquations();
|
manager.solveAdjointEquations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +411,15 @@ void Foam::optimisationManager::computeSensitivities()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::optimisationManager::clearSensitivities()
|
||||||
|
{
|
||||||
|
for (adjointSolverManager& adjSolvManager : adjointSolverManagers_)
|
||||||
|
{
|
||||||
|
adjSolvManager.clearSensitivities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::optimisationManager::updatePrimalBasedQuantities()
|
void Foam::optimisationManager::updatePrimalBasedQuantities()
|
||||||
{
|
{
|
||||||
forAll(adjointSolverManagers_, amI)
|
forAll(adjointSolverManagers_, amI)
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2e22 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -68,8 +68,37 @@ protected:
|
|||||||
PtrList<primalSolver> primalSolvers_;
|
PtrList<primalSolver> primalSolvers_;
|
||||||
PtrList<adjointSolverManager> adjointSolverManagers_;
|
PtrList<adjointSolverManager> adjointSolverManagers_;
|
||||||
const word managerType_;
|
const word managerType_;
|
||||||
|
|
||||||
autoPtr<incompressible::optimisationType> optType_;
|
autoPtr<incompressible::optimisationType> optType_;
|
||||||
|
|
||||||
|
Switch shouldUpdateDesignVariables_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
virtual void resetTime();
|
||||||
|
|
||||||
|
//- Update design variables
|
||||||
|
virtual void moveDesignVariables();
|
||||||
|
|
||||||
|
//- Update design variables. Multiplication with line search step
|
||||||
|
//- happens inside the update(direction) function
|
||||||
|
virtual void moveDesignVariables
|
||||||
|
(
|
||||||
|
scalarField& direction
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Update design variables using a line-search
|
||||||
|
void lineSearchUpdate();
|
||||||
|
|
||||||
|
//- Update design variables using a fixed step
|
||||||
|
void fixedStepUpdate();
|
||||||
|
|
||||||
|
//- Actions performed after lineSearch has converged
|
||||||
|
void postUpdate();
|
||||||
|
|
||||||
|
//- Initialization. Construct primal and adjoint solvers
|
||||||
|
virtual void initialize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -145,7 +174,7 @@ public:
|
|||||||
//- Update design variables.
|
//- Update design variables.
|
||||||
// Might employ a line search to find a correction satisfying the step
|
// Might employ a line search to find a correction satisfying the step
|
||||||
// convergence criteria
|
// convergence criteria
|
||||||
virtual void updateDesignVariables() = 0;
|
virtual void updateDesignVariables();
|
||||||
|
|
||||||
//- Solve all primal equations
|
//- Solve all primal equations
|
||||||
virtual void solvePrimalEquations();
|
virtual void solvePrimalEquations();
|
||||||
@ -156,6 +185,9 @@ public:
|
|||||||
//- Compute all adjoint sensitivities
|
//- Compute all adjoint sensitivities
|
||||||
virtual void computeSensitivities();
|
virtual void computeSensitivities();
|
||||||
|
|
||||||
|
//- Clear all adjoint sensitivities
|
||||||
|
virtual void clearSensitivities();
|
||||||
|
|
||||||
//- Solve all primal equations
|
//- Solve all primal equations
|
||||||
virtual void updatePrimalBasedQuantities();
|
virtual void updatePrimalBasedQuantities();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -45,7 +45,9 @@ Foam::singleRun::singleRun(fvMesh& mesh)
|
|||||||
:
|
:
|
||||||
optimisationManager(mesh),
|
optimisationManager(mesh),
|
||||||
cycles_(Zero)
|
cycles_(Zero)
|
||||||
{}
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -66,102 +66,13 @@ void Foam::steadyOptimisation::updateOptTypeSource()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::steadyOptimisation::lineSearchUpdate()
|
|
||||||
{
|
|
||||||
// Compute direction of update
|
|
||||||
tmp<scalarField> tdirection = optType_->computeDirection();
|
|
||||||
scalarField& direction = tdirection.ref();
|
|
||||||
|
|
||||||
// Grab reference to line search
|
|
||||||
autoPtr<lineSearch>& lineSrch = optType_->getLineSearch();
|
|
||||||
|
|
||||||
// Store starting point
|
|
||||||
optType_->storeDesignVariables();
|
|
||||||
|
|
||||||
// Compute merit function before update
|
|
||||||
scalar meritFunction = optType_->computeMeritFunction();
|
|
||||||
lineSrch->setOldMeritValue(meritFunction);
|
|
||||||
|
|
||||||
// Get merit function derivative
|
|
||||||
const scalar dirDerivative =
|
|
||||||
optType_->meritFunctionDirectionalDerivative();
|
|
||||||
lineSrch->setDeriv(dirDerivative);
|
|
||||||
lineSrch->setDirection(direction);
|
|
||||||
|
|
||||||
// Reset initial step.
|
|
||||||
// Might be interpolated from previous optimisation cycles
|
|
||||||
lineSrch->reset();
|
|
||||||
|
|
||||||
// Perform line search
|
|
||||||
for (label iter = 0; iter < lineSrch->maxIters(); ++iter)
|
|
||||||
{
|
|
||||||
Info<< "\n- - - - - - - - - - - - - - -" << endl;
|
|
||||||
Info<< "Line search iteration " << iter << endl;
|
|
||||||
Info<< "- - - - - - - - - - - - - - -\n" << endl;
|
|
||||||
|
|
||||||
// Update design variables. Multiplication with line search step
|
|
||||||
// happens inside the update(direction) function
|
|
||||||
optType_->update(direction);
|
|
||||||
|
|
||||||
// Solve all primal equations
|
|
||||||
solvePrimalEquations();
|
|
||||||
|
|
||||||
// Compute and set new merit function
|
|
||||||
meritFunction = optType_->computeMeritFunction();
|
|
||||||
lineSrch->setNewMeritValue(meritFunction);
|
|
||||||
|
|
||||||
if (lineSrch->converged())
|
|
||||||
{
|
|
||||||
// If line search criteria have been met, proceed
|
|
||||||
Info<< "Line search converged in " << iter + 1
|
|
||||||
<< " iterations." << endl;
|
|
||||||
scalarField scaledCorrection(lineSrch->step()*direction);
|
|
||||||
optType_->updateOldCorrection(scaledCorrection);
|
|
||||||
optType_->write();
|
|
||||||
lineSrch()++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If maximum number of iteration has been reached, continue
|
|
||||||
if (iter == lineSrch->maxIters() - 1)
|
|
||||||
{
|
|
||||||
Info<< "Line search reached max. number of iterations.\n"
|
|
||||||
<< "Proceeding to the next optimisation cycle" << endl;
|
|
||||||
scalarField scaledCorrection(lineSrch->step()*direction);
|
|
||||||
optType_->updateOldCorrection(scaledCorrection);
|
|
||||||
optType_->write();
|
|
||||||
lineSrch()++;
|
|
||||||
}
|
|
||||||
// Reset to initial design variables and update step
|
|
||||||
else
|
|
||||||
{
|
|
||||||
optType_->resetDesignVariables();
|
|
||||||
lineSrch->updateStep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::steadyOptimisation::fixedStepUpdate()
|
|
||||||
{
|
|
||||||
// Update design variables
|
|
||||||
optType_->update();
|
|
||||||
|
|
||||||
// Solve primal equations
|
|
||||||
solvePrimalEquations();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::steadyOptimisation::steadyOptimisation(fvMesh& mesh)
|
Foam::steadyOptimisation::steadyOptimisation(fvMesh& mesh)
|
||||||
:
|
:
|
||||||
optimisationManager(mesh)
|
optimisationManager(mesh)
|
||||||
{
|
{
|
||||||
|
initialize();
|
||||||
optType_.reset
|
optType_.reset
|
||||||
(
|
(
|
||||||
incompressible::optimisationType::New
|
incompressible::optimisationType::New
|
||||||
@ -221,25 +132,4 @@ bool Foam::steadyOptimisation::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::steadyOptimisation::updateDesignVariables()
|
|
||||||
{
|
|
||||||
// Update design variables using either a line-search scheme or
|
|
||||||
// a fixed-step update
|
|
||||||
if (optType_->getLineSearch())
|
|
||||||
{
|
|
||||||
lineSearchUpdate();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fixedStepUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset adjoint sensitivities in all adjoint solver managers
|
|
||||||
for (adjointSolverManager& adjSolverManager : adjointSolverManagers_)
|
|
||||||
{
|
|
||||||
adjSolverManager.clearSensitivities();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -114,10 +114,6 @@ public:
|
|||||||
|
|
||||||
//- Whether to update the design variables
|
//- Whether to update the design variables
|
||||||
virtual bool update();
|
virtual bool update();
|
||||||
|
|
||||||
//- Do a line search to find a correction satisfying the step
|
|
||||||
//- convergence criteria
|
|
||||||
virtual void updateDesignVariables();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,525 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "unsteadyOptimisation.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(unsteadyOptimisation, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
optimisationManager,
|
||||||
|
unsteadyOptimisation,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::updateOptTypeSource()
|
||||||
|
{
|
||||||
|
forAll(primalSolvers_, pI)
|
||||||
|
{
|
||||||
|
primalSolvers_[pI].updateOptTypeSource(optType_->sourcePtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(adjointSolverManagers_, asmI)
|
||||||
|
{
|
||||||
|
PtrList<adjointSolver>& adjointSolvers =
|
||||||
|
adjointSolverManagers_[asmI].adjointSolvers();
|
||||||
|
|
||||||
|
forAll(adjointSolvers, aI)
|
||||||
|
{
|
||||||
|
adjointSolvers[aI].updateOptTypeSource(optType_->sourcePtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::resetTime()
|
||||||
|
{
|
||||||
|
timeManip_.moveToPrimalStartTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::moveDesignVariables()
|
||||||
|
{
|
||||||
|
if (shouldUpdateDesignVariables_)
|
||||||
|
{
|
||||||
|
// Updated grid should be written at the primal end time, to coinside
|
||||||
|
// with the primal and adjoint solutions to be stored then. The
|
||||||
|
// (unknown) time index is not important at this point, so it remains
|
||||||
|
// unchanged.
|
||||||
|
timeManip_.storeTime();
|
||||||
|
timeManip_.moveToAdjointStartTime(false, false);
|
||||||
|
|
||||||
|
// Update design variables
|
||||||
|
optType_->update();
|
||||||
|
|
||||||
|
// Restore time
|
||||||
|
timeManip_.restoreTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::moveDesignVariables
|
||||||
|
(
|
||||||
|
scalarField& direction
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (shouldUpdateDesignVariables_)
|
||||||
|
{
|
||||||
|
// Updated grid should be written at the primal end time, to coinside
|
||||||
|
// with the primal and adjoint solutions to be stored then. The
|
||||||
|
// (unknown) time index is not important at this point, so it remains
|
||||||
|
// unchanged.
|
||||||
|
timeManip_.storeTime();
|
||||||
|
timeManip_.moveToAdjointStartTime(false, false);
|
||||||
|
|
||||||
|
// Update design variables
|
||||||
|
optType_->update(direction);
|
||||||
|
|
||||||
|
// Restore time
|
||||||
|
timeManip_.restoreTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::unsteadyOptimisation::nActivePrimalSolvers()
|
||||||
|
{
|
||||||
|
const dictionary& primalSolversDict =
|
||||||
|
IOdictionary::subDict("primalSolvers");
|
||||||
|
const wordList& primalSolverNames = primalSolversDict.toc();
|
||||||
|
label n(0);
|
||||||
|
for (const word& name : primalSolverNames)
|
||||||
|
{
|
||||||
|
if (primalSolversDict.subDict(name).getOrDefault<bool>("active", true))
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::unsteadyOptimisation::nActiveAdjointSolvers()
|
||||||
|
{
|
||||||
|
const dictionary& adjointManagersDict =
|
||||||
|
IOdictionary::subDict("adjointManagers");
|
||||||
|
const wordList& adjointManagerNames = adjointManagersDict.toc();
|
||||||
|
label n(0);
|
||||||
|
for (const word& name : adjointManagerNames)
|
||||||
|
{
|
||||||
|
const dictionary& dict = adjointManagersDict.subDict(name);
|
||||||
|
n += adjointSolverManager::nActiveAdjointSolvers(dict);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::initialize()
|
||||||
|
{
|
||||||
|
mesh_.moving(false); // Note: not sure if needed
|
||||||
|
// Boolean defining if primal fields will be read from a custom time
|
||||||
|
// provided by the user.
|
||||||
|
Switch useCustomReadTime(true);
|
||||||
|
Switch shouldWriteObjective(true);
|
||||||
|
if (!localIOdictionary::empty())
|
||||||
|
{
|
||||||
|
// Possible scenarios for the solution of the primal/adjoint equations:
|
||||||
|
// (a) one wishes to continue with the next optimization cycle, or
|
||||||
|
// (b) has run the primal solver, has stored the flow fields
|
||||||
|
// time-series and now wants to run adjoint,
|
||||||
|
// (c) has already solved the adjoint equations and wants to integrate
|
||||||
|
// them again based on the same primal fields and without proceeding to
|
||||||
|
// the next optimization cycle, or
|
||||||
|
// (d) wants to continue with the primal solver only.
|
||||||
|
// For (a), nothing needs to be done here.
|
||||||
|
// For (b), in the previous execution of the code only the flow
|
||||||
|
// equations were integrated and, now, the adjoint equations are
|
||||||
|
// about to be solved. Hence, isAdjointActive under uniform is false
|
||||||
|
// and nActiveAdjointSolvers() > 0 and nActivePrimalSolvers() >= 0.
|
||||||
|
// nActivePrimalSolvers() is allowed to take positive values since the
|
||||||
|
// user may have stored the primal problem and now wants to run adjoint
|
||||||
|
// only (nActivePrimalSolvers() = 0) or wants to run adjoint and, then,
|
||||||
|
// continue with the optimization (nActivePrimalSolvers() > 0)
|
||||||
|
// For (c), isAdjointActive under uniform is true,
|
||||||
|
// nActiveAdjointSolvers() > 0 and nActivePrimalSolvers() = 0.
|
||||||
|
// For (d), isAdjointActive under uniform is false,
|
||||||
|
// nActiveAdjointSolvers() = 0 and nActivePrimalSolvers() > 0.
|
||||||
|
// iOptCycles_ does not need to be checked for the following reason.
|
||||||
|
// Even if iOptCycles_ > 0 and the user wants to run the primal solver
|
||||||
|
// only, then if
|
||||||
|
// (i) the previous optimization cycle has just been completed case4 is
|
||||||
|
// not activated and the manager proceeds as if a new optimization
|
||||||
|
// cycle begins (a), whereas if
|
||||||
|
// (ii) the primal solver has already been used, primal fields must be
|
||||||
|
// initialized using the last available time-step
|
||||||
|
|
||||||
|
label nPrimalSolvers = nActivePrimalSolvers();
|
||||||
|
label nAdjointSolvers = nActiveAdjointSolvers();
|
||||||
|
// Check if adjoint solvers were active in the previous execution
|
||||||
|
Switch isAdjointActive =
|
||||||
|
localIOdictionary::get<Switch>("isAdjointActive");
|
||||||
|
|
||||||
|
Switch case2(!isAdjointActive && nAdjointSolvers > 0);
|
||||||
|
Switch case3
|
||||||
|
(
|
||||||
|
isAdjointActive && nAdjointSolvers > 0 && nPrimalSolvers == 0
|
||||||
|
);
|
||||||
|
Switch case4
|
||||||
|
(
|
||||||
|
!isAdjointActive && nAdjointSolvers == 0 && nPrimalSolvers > 0
|
||||||
|
);
|
||||||
|
DebugInfo
|
||||||
|
<< "case2 " << case2 << nl
|
||||||
|
<< "case3 " << case3 << nl
|
||||||
|
<< "case4 " << case4 << endl;
|
||||||
|
if (case2 || case3)
|
||||||
|
{
|
||||||
|
// Start time of the primal is this time - the old span
|
||||||
|
timeManip_.setStartTime
|
||||||
|
(
|
||||||
|
mesh_.time().value() - localIOdictionary::get<scalar>("span")
|
||||||
|
);
|
||||||
|
// Read startTimeIndex from dict
|
||||||
|
timeManip_.setStartTimeIndex
|
||||||
|
(localIOdictionary::get<label>("primalStartTimeIndex"));
|
||||||
|
// Don't update design variables and avoid writing objectives
|
||||||
|
// since we are running adjoint only
|
||||||
|
shouldUpdateDesignVariables_ = false;
|
||||||
|
shouldWriteObjective = false;
|
||||||
|
// Don't solve the primal equations in the first go, even if they
|
||||||
|
// are enabled
|
||||||
|
solveFirstPrimalEqns_ = false;
|
||||||
|
}
|
||||||
|
else if (case4)
|
||||||
|
{
|
||||||
|
// Don't update design variables since we are running primal only
|
||||||
|
shouldUpdateDesignVariables_ = false;
|
||||||
|
// Disable editing readTime of the primal fields
|
||||||
|
useCustomReadTime = false;
|
||||||
|
}
|
||||||
|
if (case3)
|
||||||
|
{
|
||||||
|
if (--iOptCycle_ < 0)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "iOptCycle = " << iOptCycle_ << ". Code should enter "
|
||||||
|
<< "here only if both the primal and adjoint" << nl
|
||||||
|
<< "equations have already been integrated for the" << nl
|
||||||
|
<< "current optimization cycle and the user wants to" << nl
|
||||||
|
<< "run the adjoint solver again" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setSolvers(useCustomReadTime);
|
||||||
|
// Deactivate writting objective functions in case that the primal
|
||||||
|
// solution of the current optimization cycle has been stored and
|
||||||
|
// the adjoint problem is about to be solved
|
||||||
|
if (!shouldWriteObjective)
|
||||||
|
{
|
||||||
|
forAll(adjointSolverManagers_, amI)
|
||||||
|
{
|
||||||
|
adjointSolverManagers_[amI].setWrite(false);
|
||||||
|
adjointSolverManagers_[amI].setWriteOption(IOobject::NO_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set averaging start time (if activated)
|
||||||
|
forAll(primalSolvers_, psI)
|
||||||
|
{
|
||||||
|
primalSolvers_[psI].getVariablesSet().
|
||||||
|
adjustAverageStartTime(timeManip_.startTime().value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (debug)
|
||||||
|
// {
|
||||||
|
Info<< "startTime " << timeManip_.startTime() << nl
|
||||||
|
<< "startTimeIndex " << timeManip_.startTimeIndex() << nl
|
||||||
|
<< "primalEndTime " << timeManip_.primalEndTime() << nl
|
||||||
|
<< "span " << timeManip_.span() << endl;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::setSolvers(Switch useCustomReadTime)
|
||||||
|
{
|
||||||
|
// Read primal fields from the time prescribed in the optimisationDict,
|
||||||
|
// Time index is not updated, but this should not be a problem
|
||||||
|
dictionary& primalSolversDict =
|
||||||
|
IOdictionary::subDict("primalSolvers");
|
||||||
|
const wordList& primalSolverNames = primalSolversDict.toc();
|
||||||
|
|
||||||
|
// Construct primal solvers
|
||||||
|
primalSolvers_.setSize(primalSolverNames.size());
|
||||||
|
forAll(primalSolvers_, solveri)
|
||||||
|
{
|
||||||
|
dictionary& solverDict =
|
||||||
|
primalSolversDict.subDict(primalSolverNames[solveri]);
|
||||||
|
if (primalSolvers_.size() > 1)
|
||||||
|
{
|
||||||
|
solverDict.add<bool>("useSolverNameForFields", true);
|
||||||
|
}
|
||||||
|
primalSolvers_.set
|
||||||
|
(
|
||||||
|
solveri,
|
||||||
|
primalSolver::New
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
managerType_,
|
||||||
|
solverDict,
|
||||||
|
useCustomReadTime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct adjointSolverManagers
|
||||||
|
const dictionary& adjointManagersDict =
|
||||||
|
IOdictionary::subDict("adjointManagers");
|
||||||
|
const wordList& adjointManagerNames = adjointManagersDict.toc();
|
||||||
|
adjointSolverManagers_.setSize(adjointManagerNames.size());
|
||||||
|
|
||||||
|
label nAdjointSolvers(0);
|
||||||
|
label nActiveAdjointSolvers(0);
|
||||||
|
bool overrideUseSolverName(adjointSolverManagers_.size() > 1);
|
||||||
|
forAll(adjointSolverManagers_, manageri)
|
||||||
|
{
|
||||||
|
adjointSolverManagers_.set
|
||||||
|
(
|
||||||
|
manageri,
|
||||||
|
new adjointSolverManager
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
managerType_,
|
||||||
|
adjointManagersDict.subDict(adjointManagerNames[manageri]),
|
||||||
|
overrideUseSolverName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
nAdjointSolvers +=
|
||||||
|
adjointSolverManagers_[manageri].nAdjointSolvers();
|
||||||
|
nActiveAdjointSolvers +=
|
||||||
|
adjointSolverManagers_[manageri].nActiveAdjointSolvers();
|
||||||
|
}
|
||||||
|
isAdjointActive_ = (nActiveAdjointSolvers > 0);
|
||||||
|
|
||||||
|
// Sanity checks on the naming convention
|
||||||
|
if (primalSolvers_.size() > 1)
|
||||||
|
{
|
||||||
|
for (const primalSolver& solveri : primalSolvers_)
|
||||||
|
{
|
||||||
|
if (!solveri.useSolverNameForFields())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Multiple primal solvers are present but "
|
||||||
|
<< "useSolverNameForFields is set to false in "
|
||||||
|
<< "primal solver " << solveri.solverName() << nl
|
||||||
|
<< "This is considered fatal."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nAdjointSolvers > 1)
|
||||||
|
{
|
||||||
|
for (const adjointSolverManager& amI : adjointSolverManagers_)
|
||||||
|
{
|
||||||
|
const PtrList<adjointSolver>& adjointSolvers = amI.adjointSolvers();
|
||||||
|
for (const adjointSolver& asI : adjointSolvers)
|
||||||
|
{
|
||||||
|
if (!asI.useSolverNameForFields())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Multiple adjoint solvers are present but "
|
||||||
|
<< "useSolverNameForFields is set to false in "
|
||||||
|
<< "adjoint solver " << asI.solverName() << nl
|
||||||
|
<< "This is considered fatal."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::unsteadyOptimisation::unsteadyOptimisation(fvMesh& mesh)
|
||||||
|
:
|
||||||
|
optimisationManager(mesh),
|
||||||
|
localIOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"optimisation",
|
||||||
|
mesh_.time().timeName(),
|
||||||
|
"uniform",
|
||||||
|
mesh_,
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
word::null
|
||||||
|
),
|
||||||
|
iOptCycle_(localIOdictionary::getOrDefault<label>("optimisationCycle", 0)),
|
||||||
|
nOptCycles_(mesh_.time().controlDict().get<label>("nOptimisationCycles")),
|
||||||
|
isAdjointActive_(true),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
solveFirstPrimalEqns_(true)
|
||||||
|
{
|
||||||
|
// Set primal and adjoint solvers
|
||||||
|
initialize();
|
||||||
|
optType_.reset
|
||||||
|
(
|
||||||
|
incompressible::optimisationType::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
IOdictionary::subDict("optimisation"),
|
||||||
|
adjointSolverManagers_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// Update source ptrs in all solvers to look at the source held in optType
|
||||||
|
// Possible problem if mesh is adapted
|
||||||
|
updateOptTypeSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::optimisationManager& Foam::unsteadyOptimisation::operator++()
|
||||||
|
{
|
||||||
|
iOptCycle_++;
|
||||||
|
|
||||||
|
if (!end())
|
||||||
|
{
|
||||||
|
Info<< "\n* * * * * * * * * * * * * * * * *" << endl;
|
||||||
|
Info<< "Optimisation cycle " << iOptCycle_ << endl;
|
||||||
|
Info<< "Time span ["
|
||||||
|
<< time_.value() << ","
|
||||||
|
<< time_.value() + timeManip_.span()
|
||||||
|
<< "]" << endl;
|
||||||
|
Info<< "* * * * * * * * * * * * * * * * *\n" << endl;
|
||||||
|
}
|
||||||
|
timeManip_.newOptimisationCycle();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::optimisationManager& Foam::unsteadyOptimisation::operator++(int)
|
||||||
|
{
|
||||||
|
return operator++();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::unsteadyOptimisation::checkEndOfLoopAndUpdate()
|
||||||
|
{
|
||||||
|
if (update())
|
||||||
|
{
|
||||||
|
optType_->update();
|
||||||
|
}
|
||||||
|
return end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::unsteadyOptimisation::end()
|
||||||
|
{
|
||||||
|
return iOptCycle_ > nOptCycles_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::unsteadyOptimisation::update()
|
||||||
|
{
|
||||||
|
return (iOptCycle_ != 1 && !end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::solvePrimalEquations()
|
||||||
|
{
|
||||||
|
// Solve all primal equations
|
||||||
|
if (solveFirstPrimalEqns_)
|
||||||
|
{
|
||||||
|
optimisationManager::solvePrimalEquations();
|
||||||
|
}
|
||||||
|
solveFirstPrimalEqns_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyOptimisation::solveAdjointEquations()
|
||||||
|
{
|
||||||
|
optimisationManager::solveAdjointEquations();
|
||||||
|
// Re-activate Switch to update the design variables at the
|
||||||
|
// beggining of the next optimization cycle, if it has been
|
||||||
|
// deactivated
|
||||||
|
shouldUpdateDesignVariables_ = true;
|
||||||
|
// Allow writing objectives at the next optimization cycle,
|
||||||
|
// if deactivated
|
||||||
|
forAll(adjointSolverManagers_, amI)
|
||||||
|
{
|
||||||
|
adjointSolverManagers_[amI].setWrite(true);
|
||||||
|
adjointSolverManagers_[amI].setWriteOption(IOobject::AUTO_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::unsteadyOptimisation::writeData(Ostream& os) const
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Calling unsteadyOptimisation::writeData" << endl;
|
||||||
|
|
||||||
|
// If adjoint hasn't been solved, don't treat this cycle as complete
|
||||||
|
label cycle(isAdjointActive_ ? iOptCycle_ : iOptCycle_ - 1);
|
||||||
|
|
||||||
|
const label startTimeIndex = timeManip_.startTimeIndex();
|
||||||
|
os.writeEntry("optimisationCycle", cycle);
|
||||||
|
os.writeEntry("isAdjointActive", isAdjointActive_);
|
||||||
|
os.writeEntry("primalStartTimeIndex", startTimeIndex);
|
||||||
|
|
||||||
|
DebugInfo
|
||||||
|
<< "Writing data to localIOdictionary for continuation" << nl
|
||||||
|
<< tab << "optimisationCycle " << cycle << nl
|
||||||
|
<< tab << "isAdjointActive " << isAdjointActive_ << nl
|
||||||
|
<< tab << "primalStartTimeIndex " << startTimeIndex << endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::unsteadyOptimisation
|
||||||
|
|
||||||
|
Description
|
||||||
|
Iterate the optimisation cycles. For steady state opt, this coinsides
|
||||||
|
with evolving Time
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
unsteadyOptimisation.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef unsteadyOptimisation_H
|
||||||
|
#define unsteadyOptimisation_H
|
||||||
|
|
||||||
|
#include "optimisationManager.H"
|
||||||
|
#include "localIOdictionary.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class unsteadyOptimisation Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class unsteadyOptimisation
|
||||||
|
:
|
||||||
|
public optimisationManager,
|
||||||
|
public localIOdictionary
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Data
|
||||||
|
|
||||||
|
//- Current optimisation cycle
|
||||||
|
label iOptCycle_;
|
||||||
|
|
||||||
|
//- Number of optimisation cycles
|
||||||
|
label nOptCycles_;
|
||||||
|
|
||||||
|
//- Switch defining if at least one adjoint solver is active
|
||||||
|
Switch isAdjointActive_;
|
||||||
|
|
||||||
|
//- Time manipulation, common for all primal and adjoint solvers
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
//- Boolean to treat a special case
|
||||||
|
// If adjoint was not solved in the previous code execution, but it is
|
||||||
|
// solved now, together with the primal equations, avoid solving the
|
||||||
|
// primal equations the first time
|
||||||
|
bool solveFirstPrimalEqns_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Update optimisationType source for all primal and adjoint solvers
|
||||||
|
void updateOptTypeSource();
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
unsteadyOptimisation(const unsteadyOptimisation&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const unsteadyOptimisation&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Reset time to primal time after a failed line search
|
||||||
|
virtual void resetTime() override;
|
||||||
|
|
||||||
|
virtual void moveDesignVariables() override;
|
||||||
|
|
||||||
|
virtual void moveDesignVariables
|
||||||
|
(
|
||||||
|
scalarField& direction
|
||||||
|
) override;
|
||||||
|
|
||||||
|
//- Return number of active primal and adjoint solvers without
|
||||||
|
//- constructing any of the solvers.
|
||||||
|
// It is calculated through reading dictionary entries. Warning: It is
|
||||||
|
// designed to be used by initialize() function only. In this case no
|
||||||
|
// mismatch can occur if the optimisationDict is changed during
|
||||||
|
// runTime, since the primal or adjoint solvers are built directly
|
||||||
|
// after calling this function. If the number of active adjoint
|
||||||
|
// solvers is required elsewhere, use the nActiveAdjointSolvers()
|
||||||
|
// function of each adjointSolverManager.
|
||||||
|
label nActivePrimalSolvers();
|
||||||
|
|
||||||
|
label nActiveAdjointSolvers();
|
||||||
|
|
||||||
|
virtual void initialize() override;
|
||||||
|
|
||||||
|
void setSolvers(Switch editPrimalReadTime);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("unsteadyOptimisation");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
unsteadyOptimisation(fvMesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~unsteadyOptimisation() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Prefix increment
|
||||||
|
virtual optimisationManager& operator++();
|
||||||
|
|
||||||
|
//- Postfix increment, this is identical to the prefix increment
|
||||||
|
virtual optimisationManager& operator++(int);
|
||||||
|
|
||||||
|
//- Return true if end of optimisation run
|
||||||
|
// Also, updates the design variables if needed
|
||||||
|
virtual bool checkEndOfLoopAndUpdate();
|
||||||
|
|
||||||
|
//- Return true if end of optimisation run
|
||||||
|
virtual bool end();
|
||||||
|
|
||||||
|
//- Whether to update the design variables
|
||||||
|
virtual bool update();
|
||||||
|
|
||||||
|
//- Solve all primal equations
|
||||||
|
virtual void solvePrimalEquations() override;
|
||||||
|
|
||||||
|
//- Solve all adjoint equations
|
||||||
|
virtual void solveAdjointEquations() override;
|
||||||
|
|
||||||
|
//- write necessary data for continuation
|
||||||
|
virtual bool writeData(Ostream&) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "error.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(unsteadyTimeManipulation, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::printOut(const char* functionName)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< "After call to " << functionName << endl;
|
||||||
|
OSstream& os = Info.stream();
|
||||||
|
os.beginBlock();
|
||||||
|
os<< *this;
|
||||||
|
os.endBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::unsteadyTimeManipulation::unsteadyTimeManipulation
|
||||||
|
(
|
||||||
|
const fvMesh& mesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
MeshObject<fvMesh, UpdateableMeshObject, unsteadyTimeManipulation>(mesh),
|
||||||
|
time_(const_cast<Time&>(mesh.time())),
|
||||||
|
startTime_(time_.startTime()),
|
||||||
|
startTimeIndex_(time_.startTimeIndex()),
|
||||||
|
endTimeIndex_(-1),
|
||||||
|
span_(time_.endTime().value() - time_.startTime().value()),
|
||||||
|
storedTime_(nullptr),
|
||||||
|
storedTimeIndex_(nullptr),
|
||||||
|
storedEndTime_(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::moveToPrimalStartTime(bool setEndTime)
|
||||||
|
{
|
||||||
|
time_.setTime(startTime_, startTimeIndex_);
|
||||||
|
if (setEndTime)
|
||||||
|
{
|
||||||
|
time_.setEndTime(startTime_.value() + span_);
|
||||||
|
}
|
||||||
|
printOut(FUNCTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::moveToAdjointStartTime
|
||||||
|
(
|
||||||
|
bool setEndTime,
|
||||||
|
bool setTimeIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
label index(setTimeIndex ? endTimeIndex_ : time_.timeIndex());
|
||||||
|
time_.setTime(startTime_.value() + span_, index);
|
||||||
|
if (setEndTime)
|
||||||
|
{
|
||||||
|
// Set endTime of the adjoint solver as the start of the primal one,
|
||||||
|
// plus a deltaT
|
||||||
|
time_.setEndTime(startTime_.value() + time_.deltaT().value());
|
||||||
|
}
|
||||||
|
printOut(FUNCTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::newOptimisationCycle()
|
||||||
|
{
|
||||||
|
// Increment endTime by a time span
|
||||||
|
time_.setEndTime(time_.value() + span_);
|
||||||
|
|
||||||
|
// Adjust startTime of each optimisation loop
|
||||||
|
startTime_ = time_;
|
||||||
|
startTimeIndex_ = time_.timeIndex();
|
||||||
|
printOut(FUNCTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::storeTime()
|
||||||
|
{
|
||||||
|
storedTime_.reset(new dimensionedScalar(time_));
|
||||||
|
storedTimeIndex_.reset(new label(time_.timeIndex()));
|
||||||
|
storedEndTime_.reset(new dimensionedScalar(time_.endTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::restoreTime()
|
||||||
|
{
|
||||||
|
if (storedTime_ && storedTimeIndex_)
|
||||||
|
{
|
||||||
|
time_.setTime(storedTime_(), storedTimeIndex_());
|
||||||
|
storedTime_.clear();
|
||||||
|
storedTimeIndex_.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to restore unset stored time and timeIndex"
|
||||||
|
<< exit(FatalError)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storedEndTime_)
|
||||||
|
{
|
||||||
|
time_.setEndTime(storedEndTime_());
|
||||||
|
storedEndTime_.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to restore unset stored endTime"
|
||||||
|
<< exit(FatalError)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
printOut(FUNCTION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::writeEntries(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.beginBlock("localEntries");
|
||||||
|
os.writeEntry("startTime", startTime());
|
||||||
|
os.writeEntry("startTimeIndex", startTimeIndex());
|
||||||
|
os.writeEntry("primalEndTime", primalEndTime());
|
||||||
|
os.writeEntry("endTimeIndex", endTimeIndex());
|
||||||
|
os.writeEntry("span", span_);
|
||||||
|
os.endBlock();
|
||||||
|
|
||||||
|
os.beginBlock("TimeEntries");
|
||||||
|
os.writeEntry("time", time_.value());
|
||||||
|
os.writeEntry("timeIndex", time_.timeIndex());
|
||||||
|
os.writeEntry("deltaT", time_.deltaT());
|
||||||
|
os.writeEntry("endTime", time_.endTime());
|
||||||
|
os.endBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::unsteadyTimeManipulation::movePoints()
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::unsteadyTimeManipulation::updateMesh(const mapPolyMesh&)
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const unsteadyTimeManipulation& timeManip
|
||||||
|
)
|
||||||
|
{
|
||||||
|
timeManip.writeEntries(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,247 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::unsteadyTimeManipulation
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class with helper functions to manipulate time during unsteady optimisation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
unsteadyTimeManipulation.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef unsteadyTimeManipulation_H
|
||||||
|
#define unsteadyTimeManipulation_H
|
||||||
|
|
||||||
|
#include "MeshObject.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class unsteadyTimeManipulation;
|
||||||
|
Ostream& operator<< (Ostream&, const unsteadyTimeManipulation&);
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class unsteadyTimeManipulation Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class unsteadyTimeManipulation
|
||||||
|
:
|
||||||
|
public MeshObject<fvMesh, UpdateableMeshObject, unsteadyTimeManipulation>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Not constant reference to Time
|
||||||
|
Time& time_;
|
||||||
|
|
||||||
|
//- Start time of the optimisation loop
|
||||||
|
// Will be updated at the beginning of each new loop
|
||||||
|
dimensionedScalar startTime_;
|
||||||
|
|
||||||
|
//- Start time index of the optimisation loop
|
||||||
|
label startTimeIndex_;
|
||||||
|
|
||||||
|
//- Start time index of the optimisation loop
|
||||||
|
label endTimeIndex_;
|
||||||
|
|
||||||
|
//- Span of the optimisation loop
|
||||||
|
scalar span_;
|
||||||
|
|
||||||
|
|
||||||
|
// Temporarily stored time features
|
||||||
|
|
||||||
|
autoPtr<dimensionedScalar> storedTime_;
|
||||||
|
autoPtr<label> storedTimeIndex_;
|
||||||
|
autoPtr<dimensionedScalar> storedEndTime_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Print entries for debugging
|
||||||
|
void printOut(const char* functionName);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
unsteadyTimeManipulation(const unsteadyTimeManipulation&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const unsteadyTimeManipulation&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("unsteadyTimeManipulation");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
unsteadyTimeManipulation(const fvMesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~unsteadyTimeManipulation() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return start time of the optimisation loop
|
||||||
|
inline const dimensionedScalar& startTime() const
|
||||||
|
{
|
||||||
|
return startTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return start time of the optimisation loop
|
||||||
|
inline label startTimeIndex() const
|
||||||
|
{
|
||||||
|
return startTimeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return span of the optimisation loop
|
||||||
|
inline label endTimeIndex() const
|
||||||
|
{
|
||||||
|
return endTimeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return span of the optimisation loop
|
||||||
|
inline scalar span() const
|
||||||
|
{
|
||||||
|
return span_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return end time of primal
|
||||||
|
inline scalar primalEndTime() const
|
||||||
|
{
|
||||||
|
return startTime_.value() + span_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
//- Set startTime
|
||||||
|
inline void setStartTime(const scalar startTime)
|
||||||
|
{
|
||||||
|
startTime_.value() = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Set startTimeIndex
|
||||||
|
inline void setStartTimeIndex(const label startTimeIndex)
|
||||||
|
{
|
||||||
|
startTimeIndex_ = startTimeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Set span
|
||||||
|
inline void setSpan(const scalar span)
|
||||||
|
{
|
||||||
|
span_ = span;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Set endTimeIndex
|
||||||
|
inline void setEndTimeIndex(const label endTimeIndex)
|
||||||
|
{
|
||||||
|
endTimeIndex_ = endTimeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Store current endTimeIndex to local copy
|
||||||
|
inline void storeEndTimeIndex()
|
||||||
|
{
|
||||||
|
endTimeIndex_ = time_.timeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Move time to the beginning of the primal
|
||||||
|
// Optionally sets endTime equal to startTime + span
|
||||||
|
void moveToPrimalStartTime(bool setEndTime = true);
|
||||||
|
|
||||||
|
//- Move time to the end of the primal
|
||||||
|
// Optionally sets endTime equal to startTime
|
||||||
|
void moveToAdjointStartTime
|
||||||
|
(
|
||||||
|
bool setEndTime = true,
|
||||||
|
bool setTimeIndex = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Increment time features at the beginning of each optimisation
|
||||||
|
//- cycle
|
||||||
|
void newOptimisationCycle();
|
||||||
|
|
||||||
|
|
||||||
|
//- Store current time features
|
||||||
|
void storeTime();
|
||||||
|
|
||||||
|
//- Retrieve last stored time features
|
||||||
|
void restoreTime();
|
||||||
|
|
||||||
|
//- Write local entries and time entries to stream
|
||||||
|
void writeEntries(Ostream& os) const;
|
||||||
|
|
||||||
|
//- Dummy function required by MeshObject.
|
||||||
|
virtual bool movePoints();
|
||||||
|
|
||||||
|
//- Dummy function required by MeshObject.
|
||||||
|
virtual void updateMesh(const mapPolyMesh&);
|
||||||
|
|
||||||
|
|
||||||
|
// Ostream operators
|
||||||
|
|
||||||
|
friend Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream&,
|
||||||
|
const unsteadyTimeManipulation&
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -27,6 +27,7 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Ostream.H"
|
||||||
#include "adjointSolverManager.H"
|
#include "adjointSolverManager.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -36,6 +37,27 @@ namespace Foam
|
|||||||
defineTypeNameAndDebug(adjointSolverManager, 0);
|
defineTypeNameAndDebug(adjointSolverManager, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::adjointSolverManager::checkIntegrationTimes() const
|
||||||
|
{
|
||||||
|
forAll(adjointSolvers_, i)
|
||||||
|
{
|
||||||
|
const objectiveManager& objManager =
|
||||||
|
adjointSolvers_[i].getObjectiveManager();
|
||||||
|
if (!objManager.hasIntegrationTimes())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "The integration window of at least one of the objectives "
|
||||||
|
<< "of adjointSolver '"<< adjointSolvers_[i].solverName()
|
||||||
|
<< "' is undefined." << endl
|
||||||
|
// << "Either define the integration window "
|
||||||
|
// << "for all objectives or use FFT to one of them."
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -62,6 +84,7 @@ Foam::adjointSolverManager::adjointSolverManager
|
|||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
dict_(dict),
|
dict_(dict),
|
||||||
managerName_(dict.dictName()),
|
managerName_(dict.dictName()),
|
||||||
|
managerType_(managerType),
|
||||||
primalSolverName_(dict.get<word>("primalSolver")),
|
primalSolverName_(dict.get<word>("primalSolver")),
|
||||||
adjointSolvers_(0),
|
adjointSolvers_(0),
|
||||||
objectiveSolverIDs_(0),
|
objectiveSolverIDs_(0),
|
||||||
@ -69,7 +92,8 @@ Foam::adjointSolverManager::adjointSolverManager
|
|||||||
operatingPointWeight_
|
operatingPointWeight_
|
||||||
(
|
(
|
||||||
dict.getOrDefault<scalar>("operatingPointWeight", 1)
|
dict.getOrDefault<scalar>("operatingPointWeight", 1)
|
||||||
)
|
),
|
||||||
|
nActiveAdjointSolvers_(0)
|
||||||
{
|
{
|
||||||
dictionary& adjointSolversDict =
|
dictionary& adjointSolversDict =
|
||||||
const_cast<dictionary&>(dict.subDict("adjointSolvers"));
|
const_cast<dictionary&>(dict.subDict("adjointSolvers"));
|
||||||
@ -99,7 +123,10 @@ Foam::adjointSolverManager::adjointSolverManager
|
|||||||
primalSolverName_
|
primalSolverName_
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
if (adjointSolvers_[namei].active())
|
||||||
|
{
|
||||||
|
nActiveAdjointSolvers_++;
|
||||||
|
}
|
||||||
if (adjointSolvers_[namei].isConstraint())
|
if (adjointSolvers_[namei].isConstraint())
|
||||||
{
|
{
|
||||||
constraintSolverIDs_[nConstraints++] = namei;
|
constraintSolverIDs_[nConstraints++] = namei;
|
||||||
@ -115,6 +142,9 @@ Foam::adjointSolverManager::adjointSolverManager
|
|||||||
Info<< "Found " << nConstraints
|
Info<< "Found " << nConstraints
|
||||||
<< " adjoint solvers acting as constraints" << endl;
|
<< " adjoint solvers acting as constraints" << endl;
|
||||||
|
|
||||||
|
Info<< "Found " << nActiveAdjointSolvers_
|
||||||
|
<< " active adjoint solvers" << endl;
|
||||||
|
|
||||||
// Having more than one non-aggregated objectives per operating point
|
// Having more than one non-aggregated objectives per operating point
|
||||||
// is needlessly expensive. Issue a warning
|
// is needlessly expensive. Issue a warning
|
||||||
if (objectiveSolverIDs_.size() > 1)
|
if (objectiveSolverIDs_.size() > 1)
|
||||||
@ -122,8 +152,9 @@ Foam::adjointSolverManager::adjointSolverManager
|
|||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "Number of adjoint solvers corresponding to objectives "
|
<< "Number of adjoint solvers corresponding to objectives "
|
||||||
<< "is greater than 1 (" << objectiveSolverIDs_.size() << ")" << nl
|
<< "is greater than 1 (" << objectiveSolverIDs_.size() << ")" << nl
|
||||||
<< "Consider aggregating your objectives to one" << endl;
|
<< "Consider aggregating your objectives to one" << nl << endl;
|
||||||
}
|
}
|
||||||
|
checkIntegrationTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -163,6 +194,24 @@ const Foam::dictionary& Foam::adjointSolverManager::dict() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointSolverManager::setWrite(const bool shouldWrite)
|
||||||
|
{
|
||||||
|
forAll(adjointSolvers_, i)
|
||||||
|
{
|
||||||
|
adjointSolvers_[i].getObjectiveManager().setWrite(shouldWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointSolverManager::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
forAll(adjointSolvers_, i)
|
||||||
|
{
|
||||||
|
adjointSolvers_[i].getObjectiveManager().setWriteOption(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::PtrList<Foam::adjointSolver>&
|
const Foam::PtrList<Foam::adjointSolver>&
|
||||||
Foam::adjointSolverManager::adjointSolvers() const
|
Foam::adjointSolverManager::adjointSolvers() const
|
||||||
{
|
{
|
||||||
@ -177,12 +226,51 @@ Foam::adjointSolverManager::adjointSolvers()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::wordList Foam::adjointSolverManager::adjointSolversNames() const
|
||||||
|
{
|
||||||
|
wordList names(adjointSolvers_.size());
|
||||||
|
forAll(adjointSolvers_, sI)
|
||||||
|
{
|
||||||
|
names[sI] = adjointSolvers_[sI].name();
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::adjointSolverManager::operatingPointWeight() const
|
Foam::scalar Foam::adjointSolverManager::operatingPointWeight() const
|
||||||
{
|
{
|
||||||
return operatingPointWeight_;
|
return operatingPointWeight_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::adjointSolverManager::nActiveAdjointSolvers() const
|
||||||
|
{
|
||||||
|
return nActiveAdjointSolvers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::adjointSolverManager::nActiveAdjointSolvers
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const dictionary& adjointSolversDict = dict.subDict("adjointSolvers");
|
||||||
|
const wordList adjSolverNames = adjointSolversDict.toc();
|
||||||
|
label n(0);
|
||||||
|
Switch active(true);
|
||||||
|
forAll(adjSolverNames, namei)
|
||||||
|
{
|
||||||
|
active = adjointSolversDict.subDict(adjSolverNames[namei]).
|
||||||
|
getOrDefault<bool>("active", true);
|
||||||
|
if (active)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::adjointSolverManager::nConstraints() const
|
Foam::label Foam::adjointSolverManager::nConstraints() const
|
||||||
{
|
{
|
||||||
return constraintSolverIDs_.size();
|
return constraintSolverIDs_.size();
|
||||||
@ -316,4 +404,13 @@ void Foam::adjointSolverManager::updatePrimalBasedQuantities(const word& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointSolverManager::postLineSearch()
|
||||||
|
{
|
||||||
|
for (adjointSolver& solver : adjointSolvers_)
|
||||||
|
{
|
||||||
|
solver.postLineSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -77,6 +77,8 @@ protected:
|
|||||||
|
|
||||||
const word managerName_;
|
const word managerName_;
|
||||||
|
|
||||||
|
const word managerType_;
|
||||||
|
|
||||||
const word primalSolverName_;
|
const word primalSolverName_;
|
||||||
|
|
||||||
PtrList<adjointSolver> adjointSolvers_;
|
PtrList<adjointSolver> adjointSolvers_;
|
||||||
@ -87,6 +89,13 @@ protected:
|
|||||||
|
|
||||||
scalar operatingPointWeight_;
|
scalar operatingPointWeight_;
|
||||||
|
|
||||||
|
label nActiveAdjointSolvers_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Check integration times for unsteady runs
|
||||||
|
void checkIntegrationTimes() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -125,15 +134,33 @@ public:
|
|||||||
//- Const access to the construction dictionary
|
//- Const access to the construction dictionary
|
||||||
const dictionary& dict() const;
|
const dictionary& dict() const;
|
||||||
|
|
||||||
|
//- Should the objectives be written to file upon calling the
|
||||||
|
// corresponding write() function?
|
||||||
|
void setWrite(const bool shouldWrite);
|
||||||
|
|
||||||
|
//- Should the localIOdictionary be written?
|
||||||
|
void setWriteOption(IOobject::writeOption w);
|
||||||
|
|
||||||
//- Const access to adjoint solvers
|
//- Const access to adjoint solvers
|
||||||
const PtrList<adjointSolver>& adjointSolvers() const;
|
const PtrList<adjointSolver>& adjointSolvers() const;
|
||||||
|
|
||||||
//- Non-const access to adjoint solvers
|
//- Non-const access to adjoint solvers
|
||||||
PtrList<adjointSolver>& adjointSolvers();
|
PtrList<adjointSolver>& adjointSolvers();
|
||||||
|
|
||||||
|
//- Return the names of all adjointSolvers
|
||||||
|
wordList adjointSolversNames() const;
|
||||||
|
|
||||||
//- Const access to adjoint solvers
|
//- Const access to adjoint solvers
|
||||||
scalar operatingPointWeight() const;
|
scalar operatingPointWeight() const;
|
||||||
|
|
||||||
|
//- Return number of active adjoint solvers, either corresponding
|
||||||
|
// to objectives or constraints
|
||||||
|
label nActiveAdjointSolvers() const;
|
||||||
|
|
||||||
|
//- Static function returning the number of active adjoint
|
||||||
|
// solvers reading dict
|
||||||
|
static label nActiveAdjointSolvers(const dictionary& dict);
|
||||||
|
|
||||||
//- Number of adjoint solvers corresponding to constraints
|
//- Number of adjoint solvers corresponding to constraints
|
||||||
label nConstraints() const;
|
label nConstraints() const;
|
||||||
|
|
||||||
@ -173,6 +200,9 @@ public:
|
|||||||
// For instance, primal fields of adjoint turbulence models
|
// For instance, primal fields of adjoint turbulence models
|
||||||
void updatePrimalBasedQuantities(const word& name);
|
void updatePrimalBasedQuantities(const word& name);
|
||||||
|
|
||||||
|
//- Actions to be executed after the convergence of lineSearch
|
||||||
|
void postLineSearch();
|
||||||
|
|
||||||
|
|
||||||
// IO
|
// IO
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,588 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "pimple.H"
|
||||||
|
#include "adjointPimple.H"
|
||||||
|
#include "findRefCell.H"
|
||||||
|
#include "constrainHbyA.H"
|
||||||
|
#include "constrainPressure.H"
|
||||||
|
#include "adjustPhi.H"
|
||||||
|
#include "fvOptions.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(adjointPimple, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
incompressibleAdjointSolver,
|
||||||
|
adjointPimple,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::incompressibleAdjointVars& Foam::adjointPimple::allocateVars()
|
||||||
|
{
|
||||||
|
vars_.reset
|
||||||
|
(
|
||||||
|
new incompressibleAdjointVars
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
solverControl_(),
|
||||||
|
objectiveManagerPtr_(),
|
||||||
|
primalVars_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return getAdjointVars();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::setDeltaT()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/general/include/setDeltaT.H
|
||||||
|
if (!deltaTList_.empty())
|
||||||
|
{
|
||||||
|
Time& runTime = const_cast<Time&>(mesh_.time());
|
||||||
|
DebugInfo
|
||||||
|
<< "runTime.timeIndex(), primalStartTimeIndex = "
|
||||||
|
<< runTime.timeIndex() << " " << timeManip_.startTimeIndex()
|
||||||
|
<< endl;
|
||||||
|
runTime.setDeltaT
|
||||||
|
(
|
||||||
|
deltaTList_[runTime.timeIndex() - timeManip_.startTimeIndex() -1]
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "deltaT = " << runTime.deltaTValue() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::setTime()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
--time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::CourantNo() const
|
||||||
|
{
|
||||||
|
const surfaceScalarField& phi = primalVars_.phiInst();
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
#include "CourantNo.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::continuityErrors()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/incompressible/continuityErrs.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
const surfaceScalarField& phi = adjointVars_.phiaInst();
|
||||||
|
scalar& cumulativeContErr = cumulativeContErr_;
|
||||||
|
#include "continuityErrs.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::accumulateSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
adjointSensitivity_->accumulateIntegrand(mesh_.time().deltaTValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::adjointPimple::adjointPimple
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& primalSolverName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
incompressibleAdjointSolver
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
managerType,
|
||||||
|
dict,
|
||||||
|
primalSolverName
|
||||||
|
),
|
||||||
|
solverControl_(PIMPLEControl::New(mesh, managerType, *this)),
|
||||||
|
adjointVars_(allocateVars()),
|
||||||
|
cumulativeContErr_(Zero),
|
||||||
|
adjointSensitivity_(nullptr),
|
||||||
|
primalStorage_(getPrimalSolver().getPrimalStorage()),
|
||||||
|
deltaTList_(refCast<pimple>(getPrimalSolver()).getDeltaTList()),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ATCModel_.reset
|
||||||
|
(
|
||||||
|
ATCModel::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
primalVars_,
|
||||||
|
adjointVars_,
|
||||||
|
dict.subDict("ATCModel")
|
||||||
|
).ptr()
|
||||||
|
);
|
||||||
|
|
||||||
|
addExtraSchemes();
|
||||||
|
setRefCell
|
||||||
|
(
|
||||||
|
adjointVars_.paInst(),
|
||||||
|
solverControl_().dict(),
|
||||||
|
solverControl_().pRefCell(),
|
||||||
|
solverControl_().pRefValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
const IOdictionary& optDict =
|
||||||
|
mesh.lookupObject<IOdictionary>("optimisationDict");
|
||||||
|
|
||||||
|
adjointSensitivity_.reset
|
||||||
|
(
|
||||||
|
incompressible::adjointSensitivity::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
optDict.subDict("optimisation").subDict("sensitivities"),
|
||||||
|
*this
|
||||||
|
).ptr()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check integration times of the objectives
|
||||||
|
objectiveManagerPtr_().checkIntegrationTimes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::adjointPimple::readDict(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if (incompressibleAdjointSolver::readDict(dict))
|
||||||
|
{
|
||||||
|
if (adjointSensitivity_.valid())
|
||||||
|
{
|
||||||
|
const IOdictionary& optDict =
|
||||||
|
mesh_.lookupObject<IOdictionary>("optimisationDict");
|
||||||
|
|
||||||
|
adjointSensitivity_().readDict
|
||||||
|
(
|
||||||
|
optDict.subDict("optimisation").subDict("sensitivities")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::solveIter()
|
||||||
|
{
|
||||||
|
CourantNo();
|
||||||
|
setDeltaT();
|
||||||
|
setTime();
|
||||||
|
|
||||||
|
// Retrieve primal fields of the time step. Retrieving of the first
|
||||||
|
// time-step of the adjoint loop is also necessary if more than one adjoint
|
||||||
|
// solvers are used. Includes potential recomputation of the primal fields,
|
||||||
|
// depending on the primal storage strategy
|
||||||
|
primalStorage_->retrieveVariables();
|
||||||
|
const Time& time = mesh_.time();
|
||||||
|
Info<< "Time = " << time.timeName() << "\n" << endl;
|
||||||
|
|
||||||
|
// Update objective related fields
|
||||||
|
objectiveManagerPtr_->updateOrNullify();
|
||||||
|
|
||||||
|
// Update turbulence model and ATC related terms
|
||||||
|
incompressibleAdjointSolver::updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
// Grab primal references
|
||||||
|
const surfaceScalarField& phi = primalVars_.phi();
|
||||||
|
// Grab adjoint references
|
||||||
|
volScalarField& pa = adjointVars_.paInst();
|
||||||
|
volVectorField& Ua = adjointVars_.UaInst();
|
||||||
|
surfaceScalarField& phia = adjointVars_.phiaInst();
|
||||||
|
autoPtr<incompressibleAdjoint::adjointRASModel>& adjointTurbulence =
|
||||||
|
adjointVars_.adjointTurbulence();
|
||||||
|
const label& paRefCell = solverControl_().pRefCell();
|
||||||
|
const scalar& paRefValue = solverControl_().pRefValue();
|
||||||
|
fv::options& fvOptions(fv::options::New(this->mesh_));
|
||||||
|
|
||||||
|
while (solverControl_().loop())
|
||||||
|
{
|
||||||
|
// Momentum predictor
|
||||||
|
//~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
tmp<fvVectorMatrix> tUaEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(Ua) + fvm::div(-phi, Ua)
|
||||||
|
+ adjointTurbulence->divDevReff(Ua)
|
||||||
|
+ adjointTurbulence->adjointMeanFlowSource()
|
||||||
|
==
|
||||||
|
fvOptions(Ua)
|
||||||
|
);
|
||||||
|
fvVectorMatrix& UaEqn = tUaEqn.ref();
|
||||||
|
|
||||||
|
// Add sources from boundary conditions
|
||||||
|
UaEqn.boundaryManipulate(Ua.boundaryFieldRef());
|
||||||
|
|
||||||
|
// Add sources from volume-based objectives
|
||||||
|
objectiveManagerPtr_().addUaEqnSource(UaEqn);
|
||||||
|
|
||||||
|
// Add ATC term
|
||||||
|
ATCModel_->addATC(UaEqn);
|
||||||
|
|
||||||
|
UaEqn.relax();
|
||||||
|
|
||||||
|
fvOptions.constrain(UaEqn);
|
||||||
|
|
||||||
|
if (solverControl_().momentumPredictor())
|
||||||
|
{
|
||||||
|
Foam::solve(UaEqn == -fvc::grad(pa));
|
||||||
|
|
||||||
|
fvOptions.correct(Ua);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pressure Eq
|
||||||
|
//~~~~~~~~~~~~
|
||||||
|
while (solverControl_().correct())
|
||||||
|
{
|
||||||
|
volScalarField rAUa(1.0/UaEqn.A());
|
||||||
|
volVectorField HabyA(constrainHbyA(rAUa*UaEqn.H(), Ua, pa));
|
||||||
|
surfaceScalarField phiaHbyA
|
||||||
|
(
|
||||||
|
"phiaHbyA",
|
||||||
|
fvc::flux(HabyA)
|
||||||
|
//+ MRF_.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pa.needReference())
|
||||||
|
{
|
||||||
|
fvc::makeRelative(phiaHbyA, Ua);
|
||||||
|
adjustPhi(phiaHbyA, Ua, pa);
|
||||||
|
fvc::makeAbsolute(phiaHbyA, Ua);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<volScalarField> rAtUa(rAUa);
|
||||||
|
|
||||||
|
if (solverControl_().consistent())
|
||||||
|
{
|
||||||
|
rAtUa = 1.0/max(1.0/rAUa - UaEqn.H1(), 0.1/rAUa);
|
||||||
|
phiaHbyA +=
|
||||||
|
fvc::interpolate(rAtUa() - rAUa)*fvc::snGrad(pa)*mesh_.magSf();
|
||||||
|
HabyA -= (rAUa - rAtUa())*fvc::grad(pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solverControl_().nCorrPISO() <= 1)
|
||||||
|
{
|
||||||
|
tUaEqn.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-orthogonal pressure corrector loop
|
||||||
|
while (solverControl_().correctNonOrthogonal())
|
||||||
|
{
|
||||||
|
fvScalarMatrix paEqn
|
||||||
|
(
|
||||||
|
fvm::laplacian(rAtUa(), pa) == fvc::div(phiaHbyA)
|
||||||
|
);
|
||||||
|
|
||||||
|
paEqn.boundaryManipulate(pa.boundaryFieldRef());
|
||||||
|
|
||||||
|
fvOptions.constrain(paEqn);
|
||||||
|
paEqn.setReference(paRefCell, paRefValue);
|
||||||
|
|
||||||
|
paEqn.solve
|
||||||
|
(
|
||||||
|
mesh_.solver(pa.select(solverControl_().finalInnerIter()))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (solverControl_().finalNonOrthogonalIter())
|
||||||
|
{
|
||||||
|
phia = phiaHbyA - paEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuityErrors();
|
||||||
|
|
||||||
|
// Explicitly relax pressure for momentum corrector
|
||||||
|
pa.relax();
|
||||||
|
|
||||||
|
Ua = HabyA - rAtUa()*fvc::grad(pa);
|
||||||
|
Ua.correctBoundaryConditions();
|
||||||
|
fvOptions.correct(Ua);
|
||||||
|
pa.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solverControl_().turbCorr())
|
||||||
|
{
|
||||||
|
adjointTurbulence->correct();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solverControl_().printMaxMags())
|
||||||
|
{
|
||||||
|
dimensionedScalar maxUa = max(mag(Ua)());
|
||||||
|
dimensionedScalar maxpa = max(mag(pa)());
|
||||||
|
Info<< "Max mag of adjoint velocity = " << maxUa.value() << endl;
|
||||||
|
Info<< "Max mag of adjoint pressure = " << maxpa.value() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average fields if necessary
|
||||||
|
adjointVars_.computeMeanUnsteadyFields(timeManip_.primalEndTime());
|
||||||
|
|
||||||
|
// Calls time.write()
|
||||||
|
solverControl_().writeFields();
|
||||||
|
|
||||||
|
// Print execution time
|
||||||
|
time.printExecutionTime(Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::solve()
|
||||||
|
{
|
||||||
|
// Iterate
|
||||||
|
if (active_)
|
||||||
|
{
|
||||||
|
preLoop();
|
||||||
|
while (loop())
|
||||||
|
{
|
||||||
|
solveIter();
|
||||||
|
accumulateSensitivities();
|
||||||
|
}
|
||||||
|
postLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::adjointPimple::run()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
return time.reverseRun();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::adjointPimple::loop()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
// mesh_.time().reverseRun() is actually needed here. Not a mistake.
|
||||||
|
// Chosen for compatibility reasons with the piso algorithm
|
||||||
|
// and the 'solveWithArgs' function at solverTemplates.C
|
||||||
|
return time.reverseRun();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::preLoop()
|
||||||
|
{
|
||||||
|
// Disable re-writting of primal fields
|
||||||
|
primalVars_.setWriteOption(IOobject::NO_WRITE);
|
||||||
|
|
||||||
|
// Reset time to the beginning of the adjoint loop.
|
||||||
|
// Resets endTime too
|
||||||
|
timeManip_.moveToAdjointStartTime();
|
||||||
|
|
||||||
|
// TODO: To be able to stop the adjoint solution midway and continue
|
||||||
|
// thereafter, the oldTimes of the adjoint fields are required to be
|
||||||
|
// correctly read. Make sure that these are not reset due to change in
|
||||||
|
// time, upon calling oldTime() function.
|
||||||
|
|
||||||
|
// Reset all adjoint fields to zero
|
||||||
|
adjointVars_.nullify();
|
||||||
|
adjointVars_.resetMeanFields();
|
||||||
|
|
||||||
|
// Copy pointers to storage instances and possibly read compressed fields
|
||||||
|
// in cases of restarted runs
|
||||||
|
primalStorage_->preAdjointLoop();
|
||||||
|
|
||||||
|
// The adjoint equations should be also solved at the last primal time-step.
|
||||||
|
// Advance time once more to get to the correct time during the solution
|
||||||
|
// of the first adjoint time-setp
|
||||||
|
const_cast<Time&>(mesh_.time())++;
|
||||||
|
|
||||||
|
// Print out
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Solving adjoint equations for solver " << solverName() << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::postLoop()
|
||||||
|
{
|
||||||
|
// rite adjoint fields at primalEndTime. Although the adjoint equations
|
||||||
|
// are integrated backwards in time starting from primalEndTime and ending
|
||||||
|
// at primalStartTime, the appropriate time to write the adjoint fields is
|
||||||
|
// the primalEndTime. This is not only to have both the primal and adjoint
|
||||||
|
// fields of each optimization cycle written at the same time, but more
|
||||||
|
// importantly to have consistency between the written grid and the adjoint
|
||||||
|
// fields. To do so, reset only the time value to that corresponding to the
|
||||||
|
// end of the primal. Keep the timeIndex unchanged, so that
|
||||||
|
// GeometricField::storeOldTime() function is not called by the time
|
||||||
|
// GeometricField::oldTime() is called from the
|
||||||
|
// incompressibleAdjointVars::write() function. This way, the adjoint
|
||||||
|
// fields will be written correctly in disk without oldTimes to been
|
||||||
|
// shifted
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
timeManip_.moveToAdjointStartTime(false, false);
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
adjointVars_.write();
|
||||||
|
}
|
||||||
|
// Completely reset time to that corresponding to the end of the primal
|
||||||
|
// problem.
|
||||||
|
timeManip_.moveToAdjointStartTime();
|
||||||
|
// Write data except for the adjoint fields that have already been written
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
adjointVars_.setWriteOption(IOobject::NO_WRITE);
|
||||||
|
time.writeNow();
|
||||||
|
this->writeNow();
|
||||||
|
adjointVars_.setWriteOption(IOobject::AUTO_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print useful info and rewind storage pointers
|
||||||
|
primalStorage_->postAdjointLoop();
|
||||||
|
|
||||||
|
// Compute sensitivities
|
||||||
|
adjointSolver::postLoop();
|
||||||
|
|
||||||
|
//- Re-enable writting of primal fields
|
||||||
|
primalVars_.setWriteOption(IOobject::AUTO_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::postLineSearch()
|
||||||
|
{
|
||||||
|
// Set integration times for the next optimisation cycle
|
||||||
|
objectiveManagerPtr_().incrementIntegrationTimes(timeManip_.span());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::computeObjectiveSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
const scalarField& sens = adjointSensitivity_->calculateSensitivities();
|
||||||
|
if (!sensitivities_)
|
||||||
|
{
|
||||||
|
sensitivities_.reset(new scalarField(sens.size(), scalar(0)));
|
||||||
|
}
|
||||||
|
sensitivities_.ref() = sens;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sensitivities_.reset(new scalarField(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::scalarField& Foam::adjointPimple::getObjectiveSensitivities()
|
||||||
|
{
|
||||||
|
if (!sensitivities_.valid())
|
||||||
|
{
|
||||||
|
computeObjectiveSensitivities();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sensitivities_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::clearSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
adjointSensitivity_->clearSensitivities();
|
||||||
|
adjointSolver::clearSensitivities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::sensitivity& Foam::adjointPimple::getSensitivityBase()
|
||||||
|
{
|
||||||
|
if (adjointSensitivity_.valid())
|
||||||
|
{
|
||||||
|
return adjointSensitivity_();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Sensitivity object not allocated \n"
|
||||||
|
<< "Turn computeSensitivities on in "
|
||||||
|
<< solverName_
|
||||||
|
<< nl << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
|
||||||
|
return adjointSensitivity_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPimple::updatePrimalBasedQuantities()
|
||||||
|
{
|
||||||
|
// Update turbulence model and ATC related terms
|
||||||
|
incompressibleAdjointSolver::updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
// Write mean values for all objectives
|
||||||
|
PtrList<objective>& objectives
|
||||||
|
= objectiveManagerPtr_->getObjectiveFunctions();
|
||||||
|
for (objective& obj : objectives)
|
||||||
|
{
|
||||||
|
if (obj.shouldWrite())
|
||||||
|
{
|
||||||
|
obj.writeMeanValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::adjointPimple::writeData(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.writeEntry("averageIter", solverControl_().averageIter());
|
||||||
|
return adjointSolver::writeData(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,218 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::adjointPimple
|
||||||
|
|
||||||
|
Description
|
||||||
|
Solution of the incompressible, unsteady adjoint equations using the PIMPLE
|
||||||
|
algorithm
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef adjointPimple_H
|
||||||
|
#define adjointPimple_H
|
||||||
|
|
||||||
|
#include "incompressibleAdjointSolver.H"
|
||||||
|
#include "PIMPLEControl.H"
|
||||||
|
#include "incompressibleVars.H"
|
||||||
|
#include "incompressibleAdjointVars.H"
|
||||||
|
#include "adjointSensitivityIncompressible.H"
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class adjointPimple Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class adjointPimple
|
||||||
|
:
|
||||||
|
public incompressibleAdjointSolver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
adjointPimple(const adjointPimple&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const adjointPimple&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Solver control
|
||||||
|
autoPtr<PIMPLEControl> solverControl_;
|
||||||
|
|
||||||
|
//- Reference to incompressibleAdjointVars
|
||||||
|
// Used for convenience and to avoid repetitive dynamic_casts
|
||||||
|
// Same as getAdjointVars()
|
||||||
|
incompressibleAdjointVars& adjointVars_;
|
||||||
|
|
||||||
|
//- Cumulative continuity error
|
||||||
|
scalar cumulativeContErr_;
|
||||||
|
|
||||||
|
//- Sensitivity Derivatives engine
|
||||||
|
autoPtr<incompressible::adjointSensitivity> adjointSensitivity_;
|
||||||
|
|
||||||
|
//- Reference to primal storage mechanism
|
||||||
|
autoPtr<primalStorage>& primalStorage_;
|
||||||
|
|
||||||
|
//- labelList containing all the time-step dependent pointers necessary
|
||||||
|
// for the sucessfull retrieving of the variableSet
|
||||||
|
labelList storagePtrs_;
|
||||||
|
|
||||||
|
//- Time instances and indices at the beginning and end of each
|
||||||
|
//- optimisation loop
|
||||||
|
dimensionedScalar primalEndTime_;
|
||||||
|
|
||||||
|
//- Reference to the deltaTList of the primal solver
|
||||||
|
const DynamicList<scalar>& deltaTList_;
|
||||||
|
|
||||||
|
//- Time manipulation, common for all primal and adjoint solvers
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Allocate incompressibleAdjointVars and return reference to be used
|
||||||
|
//- for convenience in the rest of the class.
|
||||||
|
incompressibleAdjointVars& allocateVars();
|
||||||
|
|
||||||
|
//- Reset time-step to maintain a constant maximum courant Number.
|
||||||
|
// Reduction of time-step is immediate, but increase is damped to
|
||||||
|
// avoid unstable oscillations.
|
||||||
|
void setDeltaT();
|
||||||
|
|
||||||
|
//- Decrease time
|
||||||
|
void setTime();
|
||||||
|
|
||||||
|
//- Compute Courant No
|
||||||
|
void CourantNo() const;
|
||||||
|
|
||||||
|
//- Compute continuity errors
|
||||||
|
void continuityErrors();
|
||||||
|
|
||||||
|
//- Accumulate sensitivities from the various time instances
|
||||||
|
void accumulateSensitivities();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("adjointPimple");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh and dictionary
|
||||||
|
adjointPimple
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& primalSolverName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~adjointPimple() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool readDict(const dictionary& dict);
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Execute one iteration of the solution algorithm
|
||||||
|
virtual void solveIter();
|
||||||
|
|
||||||
|
//- Main control loop
|
||||||
|
virtual void solve();
|
||||||
|
|
||||||
|
//- Looper (advances iters, time step)
|
||||||
|
virtual bool run();
|
||||||
|
|
||||||
|
//- Looper (advances iters, time step)
|
||||||
|
virtual bool loop();
|
||||||
|
|
||||||
|
//- Functions to be called before loop
|
||||||
|
virtual void preLoop();
|
||||||
|
|
||||||
|
//- Functions to be called after loop
|
||||||
|
virtual void postLoop();
|
||||||
|
|
||||||
|
//- Functions to be called after the convergence of linearSearch
|
||||||
|
virtual void postLineSearch();
|
||||||
|
|
||||||
|
//- Compute sensitivities of the underlaying objectives
|
||||||
|
virtual void computeObjectiveSensitivities();
|
||||||
|
|
||||||
|
//- Grab a reference to the computed sensitivities
|
||||||
|
virtual const scalarField& getObjectiveSensitivities();
|
||||||
|
|
||||||
|
//- Clears the sensitivity field known by the adjoint solver
|
||||||
|
//- and zeros sensitivities constituents
|
||||||
|
virtual void clearSensitivities();
|
||||||
|
|
||||||
|
//- Return the base sensitivity object
|
||||||
|
virtual sensitivity& getSensitivityBase();
|
||||||
|
|
||||||
|
//- Update primal based quantities
|
||||||
|
//- related to the objective functions.
|
||||||
|
// Also writes the objective function values to files.
|
||||||
|
// Written here and not in the postLoop function of the primal
|
||||||
|
// to make sure we don't pollute the objective files with
|
||||||
|
// objectives of non-converged linearSearch iterations
|
||||||
|
virtual void updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
//- Write average iteration
|
||||||
|
virtual bool writeData(Ostream& os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,576 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "adjointPiso.H"
|
||||||
|
#include "findRefCell.H"
|
||||||
|
#include "constrainHbyA.H"
|
||||||
|
#include "constrainPressure.H"
|
||||||
|
#include "adjustPhi.H"
|
||||||
|
#include "fvOptions.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(adjointPiso, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
incompressibleAdjointSolver,
|
||||||
|
adjointPiso,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::adjointPiso::printFields()
|
||||||
|
{
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
const word timeName = mesh_.time().timeName();
|
||||||
|
const word prefix = "after solving for t = " + timeName + " ";
|
||||||
|
volScalarField& pa = adjointVars_.paInst();
|
||||||
|
volVectorField& Ua = adjointVars_.UaInst();
|
||||||
|
surfaceScalarField& phia = adjointVars_.phiaInst();
|
||||||
|
Info<< "Debug: Ua.nOldTimes() = " << Ua.nOldTimes() << endl;
|
||||||
|
Info<< "Debug: phia.nOldTimes() = " << phia.nOldTimes() << endl;
|
||||||
|
Info<< prefix << "pa:\n" << pa << endl;
|
||||||
|
Info<< prefix << "Ua:\n" << Ua << endl;
|
||||||
|
Info<< prefix << "Ua.oldTime():\n" << Ua.oldTime() << endl;
|
||||||
|
Info<< prefix << "phia:\n" << phia << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::printPrimalFields()
|
||||||
|
{
|
||||||
|
if (debug > 2)
|
||||||
|
{
|
||||||
|
const word timeName = mesh_.time().timeName();
|
||||||
|
const word prefix = "primal fields for t = " + timeName + " ";
|
||||||
|
volScalarField& p = primalVars_.pInst();
|
||||||
|
volVectorField& U = primalVars_.UInst();
|
||||||
|
surfaceScalarField& phi = primalVars_.phiInst();
|
||||||
|
Info<< prefix << "p:\n" << p << endl;
|
||||||
|
Info<< prefix << "U:\n" << U << endl;
|
||||||
|
Info<< prefix << "phi:\n" << phi << endl;
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
primalVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
Info << prefix << " TMVar1:\n" << rasVars.TMVar1Inst() << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
Info << prefix << " TMVar2:\n" << rasVars.TMVar2Inst() << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasNut())
|
||||||
|
{
|
||||||
|
Info << prefix << " nut:\n" << rasVars.nutRefInst() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::incompressibleAdjointVars& Foam::adjointPiso::allocateVars()
|
||||||
|
{
|
||||||
|
vars_.reset
|
||||||
|
(
|
||||||
|
new incompressibleAdjointVars
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
solverControl_(),
|
||||||
|
objectiveManagerPtr_(),
|
||||||
|
primalVars_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return getAdjointVars();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::CourantNo() const
|
||||||
|
{
|
||||||
|
const surfaceScalarField& phi = primalVars_.phiInst();
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
#include "CourantNo.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::continuityErrors()
|
||||||
|
{
|
||||||
|
const surfaceScalarField& phia = adjointVars_.phiaInst();
|
||||||
|
volScalarField contErr(fvc::div(phia));
|
||||||
|
|
||||||
|
scalar sumLocalContErr = mesh_.time().deltaTValue()*
|
||||||
|
mag(contErr)().weightedAverage(mesh_.V()).value();
|
||||||
|
|
||||||
|
scalar globalContErr = mesh_.time().deltaTValue()*
|
||||||
|
contErr.weightedAverage(mesh_.V()).value();
|
||||||
|
cumulativeContErr_ += globalContErr;
|
||||||
|
|
||||||
|
Info<< "time step continuity errors : sum local = " << sumLocalContErr
|
||||||
|
<< ", global = " << globalContErr
|
||||||
|
<< ", cumulative = " << cumulativeContErr_
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::accumulateSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
adjointSensitivity_->accumulateIntegrand(mesh_.time().deltaTValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::adjointPiso::adjointPiso
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& primalSolverName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
incompressibleAdjointSolver
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
managerType,
|
||||||
|
dict,
|
||||||
|
primalSolverName
|
||||||
|
),
|
||||||
|
solverControl_(PISOControl::New(mesh, managerType, *this)),
|
||||||
|
adjointVars_(allocateVars()),
|
||||||
|
cumulativeContErr_(Zero),
|
||||||
|
adjointSensitivity_(nullptr),
|
||||||
|
primalStorage_(getPrimalSolver().getPrimalStorage()),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ATCModel_.reset
|
||||||
|
(
|
||||||
|
ATCModel::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
primalVars_,
|
||||||
|
adjointVars_,
|
||||||
|
dict.subDict("ATCModel")
|
||||||
|
).ptr()
|
||||||
|
);
|
||||||
|
|
||||||
|
addExtraSchemes();
|
||||||
|
setRefCell
|
||||||
|
(
|
||||||
|
adjointVars_.paInst(),
|
||||||
|
solverControl_().dict(),
|
||||||
|
solverControl_().pRefCell(),
|
||||||
|
solverControl_().pRefValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
const IOdictionary& optDict =
|
||||||
|
mesh.lookupObject<IOdictionary>("optimisationDict");
|
||||||
|
|
||||||
|
adjointSensitivity_.reset
|
||||||
|
(
|
||||||
|
incompressible::adjointSensitivity::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
optDict.subDict("optimisation").subDict("sensitivities"),
|
||||||
|
*this
|
||||||
|
).ptr()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check integration times of the objectives
|
||||||
|
objectiveManagerPtr_().checkIntegrationTimes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::adjointPiso::readDict(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if (incompressibleAdjointSolver::readDict(dict))
|
||||||
|
{
|
||||||
|
if (adjointSensitivity_.valid())
|
||||||
|
{
|
||||||
|
const IOdictionary& optDict =
|
||||||
|
mesh_.lookupObject<IOdictionary>("optimisationDict");
|
||||||
|
|
||||||
|
adjointSensitivity_().readDict
|
||||||
|
(
|
||||||
|
optDict.subDict("optimisation").subDict("sensitivities")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::solveIter()
|
||||||
|
{
|
||||||
|
// Retrieve primal fields of the time step. Retrieving of the first
|
||||||
|
// time-step of the adjoint loop is also necessary if more than one adjoint
|
||||||
|
// solvers are used. Includes potential recomputation of the primal fields,
|
||||||
|
// depending on the primal storage strategy
|
||||||
|
primalStorage_->retrieveVariables();
|
||||||
|
const Time& time = mesh_.time();
|
||||||
|
Info << "Time = " << time.timeName() << "\n" << endl;
|
||||||
|
printPrimalFields();
|
||||||
|
|
||||||
|
// Update objective related fields
|
||||||
|
objectiveManagerPtr_->updateOrNullify();
|
||||||
|
|
||||||
|
// Update turbulence model and ATC related terms
|
||||||
|
incompressibleAdjointSolver::updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
// Grab primal references
|
||||||
|
const surfaceScalarField& phi = primalVars_.phi();
|
||||||
|
// Grab adjoint references
|
||||||
|
volScalarField& pa = adjointVars_.paInst();
|
||||||
|
volVectorField& Ua = adjointVars_.UaInst();
|
||||||
|
surfaceScalarField& phia = adjointVars_.phiaInst();
|
||||||
|
autoPtr<incompressibleAdjoint::adjointRASModel>& adjointTurbulence =
|
||||||
|
adjointVars_.adjointTurbulence();
|
||||||
|
const label& paRefCell = solverControl_().pRefCell();
|
||||||
|
const scalar& paRefValue = solverControl_().pRefValue();
|
||||||
|
fv::options& fvOptions(fv::options::New(this->mesh_));
|
||||||
|
|
||||||
|
CourantNo();
|
||||||
|
|
||||||
|
// Momentum predictor
|
||||||
|
//~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
tmp<fvVectorMatrix> tUaEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(Ua) + fvm::div(-phi, Ua)
|
||||||
|
+ adjointTurbulence->divDevReff(Ua)
|
||||||
|
+ adjointTurbulence->adjointMeanFlowSource()
|
||||||
|
==
|
||||||
|
fvOptions(Ua)
|
||||||
|
);
|
||||||
|
fvVectorMatrix& UaEqn = tUaEqn.ref();
|
||||||
|
|
||||||
|
// Add sources from boundary conditions
|
||||||
|
UaEqn.boundaryManipulate(Ua.boundaryFieldRef());
|
||||||
|
|
||||||
|
// Add sources from volume-based objectives
|
||||||
|
objectiveManagerPtr_().addUaEqnSource(UaEqn);
|
||||||
|
|
||||||
|
// Add ATC term
|
||||||
|
ATCModel_->addATC(UaEqn);
|
||||||
|
|
||||||
|
UaEqn.relax();
|
||||||
|
|
||||||
|
fvOptions.constrain(UaEqn);
|
||||||
|
|
||||||
|
if (solverControl_().momentumPredictor())
|
||||||
|
{
|
||||||
|
Foam::solve(UaEqn == -fvc::grad(pa));
|
||||||
|
|
||||||
|
fvOptions.correct(Ua);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pressure Eq
|
||||||
|
//~~~~~~~~~~~~
|
||||||
|
while (solverControl_().correct())
|
||||||
|
{
|
||||||
|
volScalarField rAUa(1.0/UaEqn.A());
|
||||||
|
volVectorField HabyA(constrainHbyA(rAUa*UaEqn.H(), Ua, pa));
|
||||||
|
surfaceScalarField phiaHbyA
|
||||||
|
(
|
||||||
|
"phiaHbyA",
|
||||||
|
fvc::flux(HabyA)
|
||||||
|
//+ MRF_.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi))
|
||||||
|
);
|
||||||
|
adjustPhi(phiaHbyA, Ua, pa);
|
||||||
|
|
||||||
|
// Non-orthogonal pressure corrector loop
|
||||||
|
while (solverControl_().correctNonOrthogonal())
|
||||||
|
{
|
||||||
|
fvScalarMatrix paEqn
|
||||||
|
(
|
||||||
|
fvm::laplacian(rAUa, pa) == fvc::div(phiaHbyA)
|
||||||
|
);
|
||||||
|
|
||||||
|
paEqn.boundaryManipulate(pa.boundaryFieldRef());
|
||||||
|
|
||||||
|
fvOptions.constrain(paEqn);
|
||||||
|
paEqn.setReference(paRefCell, paRefValue);
|
||||||
|
|
||||||
|
paEqn.solve
|
||||||
|
(
|
||||||
|
mesh_.solver(pa.select(solverControl_().finalInnerIter()))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (solverControl_().finalNonOrthogonalIter())
|
||||||
|
{
|
||||||
|
phia = phiaHbyA - paEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuityErrors();
|
||||||
|
|
||||||
|
Ua = HabyA - rAUa*fvc::grad(pa);
|
||||||
|
Ua.correctBoundaryConditions();
|
||||||
|
fvOptions.correct(Ua);
|
||||||
|
pa.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
adjointTurbulence->correct();
|
||||||
|
|
||||||
|
if (solverControl_().printMaxMags())
|
||||||
|
{
|
||||||
|
dimensionedScalar maxUa = max(mag(Ua)());
|
||||||
|
dimensionedScalar maxpa = max(mag(pa)());
|
||||||
|
Info<< "Max mag of adjoint velocity = " << maxUa.value() << endl;
|
||||||
|
Info<< "Max mag of adjoint pressure = " << maxpa.value() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average fields if necessary
|
||||||
|
adjointVars_.computeMeanUnsteadyFields(timeManip_.primalEndTime());
|
||||||
|
|
||||||
|
// Calls time.write()
|
||||||
|
solverControl_().writeFields();
|
||||||
|
|
||||||
|
// Print execution time
|
||||||
|
time.printExecutionTime(Info);
|
||||||
|
|
||||||
|
printFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::solve()
|
||||||
|
{
|
||||||
|
// Iterate
|
||||||
|
if (active_)
|
||||||
|
{
|
||||||
|
preLoop();
|
||||||
|
while (loop())
|
||||||
|
{
|
||||||
|
this->solveIter();
|
||||||
|
accumulateSensitivities();
|
||||||
|
}
|
||||||
|
postLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::adjointPiso::loop()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
return time.reverseLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::preLoop()
|
||||||
|
{
|
||||||
|
// Disable re-writting of primal fields
|
||||||
|
primalVars_.setWriteOption(IOobject::NO_WRITE);
|
||||||
|
|
||||||
|
// Reset time to the beginning of the adjoint loop.
|
||||||
|
// Resets endTime too
|
||||||
|
timeManip_.moveToAdjointStartTime();
|
||||||
|
|
||||||
|
// TODO: To be able to stop the adjoint solution midway and continue
|
||||||
|
// thereafter, the oldTimes of the adjoint fields are required to be
|
||||||
|
// correctly read. Make sure that these are not reset due to change in
|
||||||
|
// time, upon calling oldTime() function.
|
||||||
|
|
||||||
|
// Reset all adjoint fields to zero
|
||||||
|
adjointVars_.nullify();
|
||||||
|
adjointVars_.resetMeanFields();
|
||||||
|
|
||||||
|
// Copy pointers to storage instances and possibly read compressed fields
|
||||||
|
// in cases of restarted runs
|
||||||
|
primalStorage_->preAdjointLoop();
|
||||||
|
|
||||||
|
// The adjoint equations should be also solved at the last primal time-step.
|
||||||
|
// Advance time once more to get to the correct time during the solution
|
||||||
|
// of the first adjoint time-setp
|
||||||
|
const_cast<Time&>(mesh_.time())++;
|
||||||
|
|
||||||
|
// Print out
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Solving adjoint equations for solver " << solverName() << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
|
||||||
|
printFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::postLoop()
|
||||||
|
{
|
||||||
|
// Write adjoint fields at primalEndTime. Although the adjoint equations
|
||||||
|
// are integrated backwards in time starting from primalEndTime and ending
|
||||||
|
// at primalStartTime, the appropriate time to write the adjoint fields is
|
||||||
|
// the primalEndTime. This is not only to have both the primal and adjoint
|
||||||
|
// fields of each optimization cycle written at the same time, but more
|
||||||
|
// importantly to have consistency between the written grid and the adjoint
|
||||||
|
// fields. To do so, reset only the time value to that corresponding to the
|
||||||
|
// end of the primal. Keep the timeIndex unchanged, so that
|
||||||
|
// GeometricField::storeOldTime() is not called by the time
|
||||||
|
// GeometricField::oldTime() is called from
|
||||||
|
// incompressibleAdjointVars::write(). This way, the adjoint
|
||||||
|
// fields will be written correctly in disk without oldTimes been
|
||||||
|
// shifted
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
timeManip_.moveToAdjointStartTime(false, false);
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
adjointVars_.write();
|
||||||
|
}
|
||||||
|
// Completely reset time to that corresponding to the end of the primal
|
||||||
|
// problem.
|
||||||
|
timeManip_.moveToAdjointStartTime();
|
||||||
|
// Write data except for the adjoint fields that have already been written
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
adjointVars_.setWriteOption(IOobject::NO_WRITE);
|
||||||
|
time.writeNow();
|
||||||
|
this->writeNow();
|
||||||
|
adjointVars_.setWriteOption(IOobject::AUTO_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print useful info and rewind storage pointers
|
||||||
|
primalStorage_->postAdjointLoop();
|
||||||
|
|
||||||
|
// Compute sensitivities
|
||||||
|
adjointSolver::postLoop();
|
||||||
|
|
||||||
|
// Re-enable writting of primal fields
|
||||||
|
primalVars_.setWriteOption(IOobject::AUTO_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::postLineSearch()
|
||||||
|
{
|
||||||
|
// Set integration times for the next optimisation cycle
|
||||||
|
objectiveManagerPtr_().incrementIntegrationTimes(timeManip_.span());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::computeObjectiveSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
const scalarField& sens = adjointSensitivity_->calculateSensitivities();
|
||||||
|
if (!sensitivities_)
|
||||||
|
{
|
||||||
|
sensitivities_.reset(new scalarField(sens.size(), scalar(0)));
|
||||||
|
}
|
||||||
|
sensitivities_.ref() = sens;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sensitivities_.reset(new scalarField(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::scalarField& Foam::adjointPiso::getObjectiveSensitivities()
|
||||||
|
{
|
||||||
|
if (!sensitivities_.valid())
|
||||||
|
{
|
||||||
|
computeObjectiveSensitivities();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sensitivities_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::clearSensitivities()
|
||||||
|
{
|
||||||
|
if (computeSensitivities_)
|
||||||
|
{
|
||||||
|
adjointSensitivity_->clearSensitivities();
|
||||||
|
adjointSolver::clearSensitivities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::sensitivity& Foam::adjointPiso::getSensitivityBase()
|
||||||
|
{
|
||||||
|
if (adjointSensitivity_.valid())
|
||||||
|
{
|
||||||
|
return adjointSensitivity_();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Sensitivity object not allocated \n"
|
||||||
|
<< "Turn computeSensitivities on in "
|
||||||
|
<< solverName_
|
||||||
|
<< nl << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
|
||||||
|
return adjointSensitivity_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::adjointPiso::updatePrimalBasedQuantities()
|
||||||
|
{
|
||||||
|
// Update turbulence model and ATC related terms
|
||||||
|
incompressibleAdjointSolver::updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
// Write mean values for all objectives
|
||||||
|
PtrList<objective>& objectives
|
||||||
|
= objectiveManagerPtr_->getObjectiveFunctions();
|
||||||
|
for (objective& obj : objectives)
|
||||||
|
{
|
||||||
|
if (obj.shouldWrite())
|
||||||
|
{
|
||||||
|
obj.writeMeanValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::adjointPiso::writeData(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.writeEntry("averageIter", solverControl_().averageIter());
|
||||||
|
return adjointSolver::writeData(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::adjointPiso
|
||||||
|
|
||||||
|
Description
|
||||||
|
Solution of the incompressible, unsteady adjoint equations using the PISO
|
||||||
|
algorithm
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef adjointPiso_H
|
||||||
|
#define adjointPiso_H
|
||||||
|
|
||||||
|
#include "incompressibleAdjointSolver.H"
|
||||||
|
#include "PISOControl.H"
|
||||||
|
#include "incompressibleVars.H"
|
||||||
|
#include "incompressibleAdjointVars.H"
|
||||||
|
#include "adjointSensitivityIncompressible.H"
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class adjointPiso Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class adjointPiso
|
||||||
|
:
|
||||||
|
public incompressibleAdjointSolver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
adjointPiso(const adjointPiso&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const adjointPiso&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Solver control
|
||||||
|
autoPtr<PISOControl> solverControl_;
|
||||||
|
|
||||||
|
//- Reference to incompressibleAdjointVars
|
||||||
|
// Used for convenience and to avoid repetitive dynamic_casts
|
||||||
|
// Same as getAdjointVars()
|
||||||
|
incompressibleAdjointVars& adjointVars_;
|
||||||
|
|
||||||
|
//- Cumulative continuity error
|
||||||
|
scalar cumulativeContErr_;
|
||||||
|
|
||||||
|
//- Sensitivity Derivatives engine
|
||||||
|
autoPtr<incompressible::adjointSensitivity> adjointSensitivity_;
|
||||||
|
|
||||||
|
//- Reference to primal storage mechanism
|
||||||
|
autoPtr<primalStorage>& primalStorage_;
|
||||||
|
|
||||||
|
//- Time manipulation, common for all primal and adjoint solvers
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Print adjoint fields if in debug mode
|
||||||
|
void printFields();
|
||||||
|
|
||||||
|
//- Print primal fields if in debug mode
|
||||||
|
void printPrimalFields();
|
||||||
|
|
||||||
|
//- Allocate incompressibleAdjointVars and return reference to be used
|
||||||
|
//- for convenience in the rest of the class.
|
||||||
|
incompressibleAdjointVars& allocateVars();
|
||||||
|
|
||||||
|
//- Compute Courant No
|
||||||
|
void CourantNo() const;
|
||||||
|
|
||||||
|
//- Compute continuity errors
|
||||||
|
void continuityErrors();
|
||||||
|
|
||||||
|
//- Accumulate sensitivities from the various time instances
|
||||||
|
void accumulateSensitivities();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("adjointPiso");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh and dictionary
|
||||||
|
adjointPiso
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& primalSolverName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~adjointPiso() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool readDict(const dictionary& dict);
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Execute one iteration of the solution algorithm
|
||||||
|
virtual void solveIter();
|
||||||
|
|
||||||
|
//- Main control loop
|
||||||
|
virtual void solve();
|
||||||
|
|
||||||
|
//- Looper (advances iters, time step)
|
||||||
|
virtual bool loop();
|
||||||
|
|
||||||
|
//- Functions to be called before loop
|
||||||
|
virtual void preLoop();
|
||||||
|
|
||||||
|
//- Functions to be called after loop
|
||||||
|
virtual void postLoop();
|
||||||
|
|
||||||
|
//- Functions to be called after the convergence of linearSearch
|
||||||
|
virtual void postLineSearch();
|
||||||
|
|
||||||
|
//- Compute sensitivities of the underlaying objectives
|
||||||
|
virtual void computeObjectiveSensitivities();
|
||||||
|
|
||||||
|
//- Grab a reference to the computed sensitivities
|
||||||
|
virtual const scalarField& getObjectiveSensitivities();
|
||||||
|
|
||||||
|
//- Clears the sensitivity field known by the adjoint solver
|
||||||
|
//- and zeros sensitivities constituents
|
||||||
|
virtual void clearSensitivities();
|
||||||
|
|
||||||
|
//- Return the base sensitivity object
|
||||||
|
virtual sensitivity& getSensitivityBase();
|
||||||
|
|
||||||
|
//- Update primal based quantities
|
||||||
|
//- related to the objective functions.
|
||||||
|
// Also writes the objective function values to files.
|
||||||
|
// Written here and not in the postLoop function of the primal
|
||||||
|
// to make sure we don't pollute the objective files with
|
||||||
|
// objectives of non-converged linearSearch iterations
|
||||||
|
virtual void updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
//- Write average iteration
|
||||||
|
virtual bool writeData(Ostream& os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -66,20 +66,6 @@ Foam::incompressibleAdjointVars& Foam::adjointSimple::allocateVars()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::adjointSimple::addExtraSchemes()
|
|
||||||
{
|
|
||||||
if (adjointVars_.useSolverNameForFields())
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "useSolverNameForFields is set to true for adjointSolver "
|
|
||||||
<< solverName() << nl << tab
|
|
||||||
<< "Appending variable names with the solver name" << nl << tab
|
|
||||||
<< "Please adjust the necessary entries in fvSchemes and fvSolution"
|
|
||||||
<< nl << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::adjointSimple::continuityErrors()
|
void Foam::adjointSimple::continuityErrors()
|
||||||
{
|
{
|
||||||
const surfaceScalarField& phia = adjointVars_.phiaInst();
|
const surfaceScalarField& phia = adjointVars_.phiaInst();
|
||||||
|
|||||||
@ -103,13 +103,6 @@ protected:
|
|||||||
//- for convenience in the rest of the class.
|
//- for convenience in the rest of the class.
|
||||||
incompressibleAdjointVars& allocateVars();
|
incompressibleAdjointVars& allocateVars();
|
||||||
|
|
||||||
//- In case variable names are different than the base ones,
|
|
||||||
//- add extra schemes and relaxation factors to the appropriate dicts
|
|
||||||
// Note: 160813: Changes in the baseline solution and fvSchemes classes
|
|
||||||
// have to be made in order to add schemes in the dict at run time.
|
|
||||||
// Not supported for now
|
|
||||||
void addExtraSchemes();
|
|
||||||
|
|
||||||
//- Compute continuity errors
|
//- Compute continuity errors
|
||||||
void continuityErrors();
|
void continuityErrors();
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,22 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::incompressibleAdjointSolver::addExtraSchemes()
|
||||||
|
{
|
||||||
|
if (vars_().useSolverNameForFields())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "useSolverNameForFields is set to true for adjointSolver "
|
||||||
|
<< solverName() << nl << tab
|
||||||
|
<< "Appending variable names with the solver name" << nl << tab
|
||||||
|
<< "Please adjust the necessary entries in fvSchemes and fvSolution"
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::incompressibleAdjointSolver::incompressibleAdjointSolver
|
Foam::incompressibleAdjointSolver::incompressibleAdjointSolver
|
||||||
|
|||||||
@ -80,6 +80,15 @@ protected:
|
|||||||
autoPtr<ATCModel> ATCModel_;
|
autoPtr<ATCModel> ATCModel_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- In case variable names are different than the base ones,
|
||||||
|
//- add extra schemes and relaxation factors to the appropriate dicts
|
||||||
|
// Note: 160813: Changes in the baseline solution and fvSchemes classes
|
||||||
|
// have to be made in order to add schemes in the dict at run time.
|
||||||
|
// Not supported for now
|
||||||
|
void addExtraSchemes();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -61,10 +61,11 @@ Foam::RASTurbulenceModel::RASTurbulenceModel
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
incompressiblePrimalSolver(mesh, managerType, dict),
|
incompressiblePrimalSolver(mesh, managerType, dict, useCustomReadTime),
|
||||||
solverControl_(SIMPLEControl::New(mesh, managerType, *this)),
|
solverControl_(SIMPLEControl::New(mesh, managerType, *this)),
|
||||||
incoVars_(allocateVars())
|
incoVars_(allocateVars())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -98,7 +98,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,21 @@ namespace Foam
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::incompressiblePrimalSolver::addExtraSchemes()
|
||||||
|
{
|
||||||
|
if (vars_().useSolverNameForFields())
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "useSolverNameForFields is set to true for primalSolver "
|
||||||
|
<< solverName() << nl << tab
|
||||||
|
<< "Appending variable names with the solver name" << nl << tab
|
||||||
|
<< "Please adjust the necessary entries in fvSchemes and fvSolution"
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -55,10 +70,11 @@ Foam::incompressiblePrimalSolver::incompressiblePrimalSolver
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
primalSolver(mesh, managerType, dict),
|
primalSolver(mesh, managerType, dict, useCustomReadTime),
|
||||||
phiReconstructionTol_
|
phiReconstructionTol_
|
||||||
(
|
(
|
||||||
dict.subOrEmptyDict("fieldReconstruction").
|
dict.subOrEmptyDict("fieldReconstruction").
|
||||||
@ -79,7 +95,8 @@ Foam::incompressiblePrimalSolver::New
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const word solverType(dict.get<word>("solver"));
|
const word solverType(dict.get<word>("solver"));
|
||||||
@ -99,7 +116,7 @@ Foam::incompressiblePrimalSolver::New
|
|||||||
return
|
return
|
||||||
autoPtr<incompressiblePrimalSolver>
|
autoPtr<incompressiblePrimalSolver>
|
||||||
(
|
(
|
||||||
ctorPtr(mesh, managerType, dict)
|
ctorPtr(mesh, managerType, dict, useCustomReadTime)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,14 @@ protected:
|
|||||||
label phiReconstructionIters_;
|
label phiReconstructionIters_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Protected Member Functions
|
||||||
|
|
||||||
|
//- In case variable names are different than the base ones,
|
||||||
|
//- add extra schemes and relaxation factors to the appropriate dicts
|
||||||
|
// Note: Not supported for now
|
||||||
|
void addExtraSchemes();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
@ -96,9 +104,10 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
),
|
),
|
||||||
(mesh, managerType, dict)
|
(mesh, managerType, dict, useCustomReadTime)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +118,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +130,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,686 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "pimple.H"
|
||||||
|
#include "findRefCell.H"
|
||||||
|
#include "constrainHbyA.H"
|
||||||
|
#include "constrainPressure.H"
|
||||||
|
#include "adjustPhi.H"
|
||||||
|
#include "CorrectPhi.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "fvOptions.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(pimple, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
incompressiblePrimalSolver,
|
||||||
|
pimple,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::incompressibleVars& Foam::pimple::allocateVars(scalar readTime)
|
||||||
|
{
|
||||||
|
vars_.reset(new incompressibleVars(mesh_, solverControl_(), readTime));
|
||||||
|
return getIncoVars();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::readTimeControls()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/general/include/readTimeControls.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
bool& adjustTimeStep = adjustTimeStep_;
|
||||||
|
scalar& maxCo = maxCo_;
|
||||||
|
scalar& maxDeltaT = maxDeltaT_;
|
||||||
|
#include "readTimeControls.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::CourantNo()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/incompressible/CourantNo.H
|
||||||
|
const surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
#include "CourantNo.H"
|
||||||
|
CoNum_ = CoNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::continuityErrors()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/incompressible/continuityErrs.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
const surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
scalar& cumulativeContErr = cumulativeContErr_;
|
||||||
|
#include "continuityErrs.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::setDeltaT()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/general/include/setDeltaT.H
|
||||||
|
Time& runTime = const_cast<Time&>(mesh_.time());
|
||||||
|
bool& adjustTimeStep = adjustTimeStep_;
|
||||||
|
scalar& maxCo = maxCo_;
|
||||||
|
scalar& maxDeltaT = maxDeltaT_;
|
||||||
|
scalar& CoNum = CoNum_;
|
||||||
|
#include "setDeltaT.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::setInitialDeltaT()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/general/include/setInitialDeltaT.H
|
||||||
|
Time& runTime = const_cast<Time&>(mesh_.time());
|
||||||
|
const bool& adjustTimeStep = adjustTimeStep_;
|
||||||
|
const scalar& CoNum = CoNum_;
|
||||||
|
const scalar& maxCo = maxCo_;
|
||||||
|
const scalar& maxDeltaT = maxDeltaT_;
|
||||||
|
#include "setInitialDeltaT.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::setTime()
|
||||||
|
{
|
||||||
|
Time& runTime = const_cast<Time&>(mesh_.time());
|
||||||
|
++runTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::storeDeltaT()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
if (adjustTimeStep_)
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "time.timeIndex() - primalStartTimeIndex = "
|
||||||
|
<< time.timeIndex() - timeManip_.startTimeIndex() << nl
|
||||||
|
<< "time.timeIndex(), primalStartTimeIndex = "
|
||||||
|
<< time.timeIndex() << " " << timeManip_.startTimeIndex()
|
||||||
|
<< endl;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
deltaTList_.empty()
|
||||||
|
&& (time.timeIndex() > timeManip_.startTimeIndex())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
deltaTList_.
|
||||||
|
setSize
|
||||||
|
(
|
||||||
|
time.timeIndex() - timeManip_.startTimeIndex(),
|
||||||
|
deltaT0_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
deltaTList_.append(time.deltaTValue());
|
||||||
|
}
|
||||||
|
DebugInfo
|
||||||
|
<< "deltaTList.size() = " << deltaTList_.size() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::scratchDeltaTHistory()
|
||||||
|
{
|
||||||
|
const Time& time = mesh_.time();
|
||||||
|
deltaT0_ = time.deltaTValue();
|
||||||
|
primalStartTimeIndex_ = time.timeIndex();
|
||||||
|
deltaTList_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::DynamicList<Foam::scalar>& Foam::pimple::getDeltaTList() const
|
||||||
|
{
|
||||||
|
return deltaTList_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*void Foam::pimple::readDyMControls()
|
||||||
|
{
|
||||||
|
// Original function at src/dynamicFvMesh/include/readDyMControls.H
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/general/include/readTimeControls.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const PIMPLEControl& pimple = solverControl_();
|
||||||
|
bool& moveMeshOuterCorrectors = moveMeshOuterCorrectors_;
|
||||||
|
bool& checkMeshCourantNo = checkMeshCourantNo_;
|
||||||
|
bool& correctPhi = correctPhi_;
|
||||||
|
bool& adjustTimeStep = adjustTimeStep_;
|
||||||
|
scalar& maxCo = maxCo_;
|
||||||
|
scalar& maxDeltaT = maxDeltaT_;
|
||||||
|
#include "readDyMControls.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::meshCourantNo()
|
||||||
|
{
|
||||||
|
// Original function at src/dynamicFvMesh/include/meshCourantNo.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
#include "meshCourantNo.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::correctPhi()
|
||||||
|
{
|
||||||
|
// Original function at the location of the solver
|
||||||
|
// CorrectPhi at src/finiteVolume/cfdTools/general/CorrectPhi/CorrectPhi.H
|
||||||
|
volScalarField& p = incoVars_.pInst();
|
||||||
|
volVectorField& U = incoVars_.UInst();
|
||||||
|
surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
CorrectPhi
|
||||||
|
(
|
||||||
|
U,
|
||||||
|
phi,
|
||||||
|
p,
|
||||||
|
dimensionedScalar("rAUf", dimTime, 1),
|
||||||
|
geometricZeroField(),
|
||||||
|
solverControl_()
|
||||||
|
);
|
||||||
|
continuityErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::createUfIfPresent()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/incompressible/createUfIfPresent.H
|
||||||
|
if (mesh_.dynamic())
|
||||||
|
{
|
||||||
|
volVectorField& U = incoVars_.UInst();
|
||||||
|
|
||||||
|
Info<< "Constructing face velocity Uf\n" << endl;
|
||||||
|
|
||||||
|
Uf_.reset
|
||||||
|
(
|
||||||
|
new surfaceVectorField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"Uf",
|
||||||
|
mesh_.time().timeName(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
fvc::interpolate(U)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::pimple::pimple
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
|
)
|
||||||
|
:
|
||||||
|
incompressiblePrimalSolver
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
managerType,
|
||||||
|
dict,
|
||||||
|
useCustomReadTime
|
||||||
|
),
|
||||||
|
solverControl_(PIMPLEControl::New(mesh, managerType, *this)),
|
||||||
|
shouldResetMeanFields_(useCustomReadTime),
|
||||||
|
incoVars_
|
||||||
|
(
|
||||||
|
allocateVars
|
||||||
|
(
|
||||||
|
useCustomReadTime ? dict.getOrDefault<scalar>("readTime", 0) : -1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
MRF_(mesh, word(useSolverNameForFields() ? solverName() : word::null)),
|
||||||
|
cumulativeContErr_(Zero),
|
||||||
|
objectives_(0),
|
||||||
|
adjustTimeStep_
|
||||||
|
(
|
||||||
|
mesh.time().controlDict().getOrDefault("adjustTimeStep", false)
|
||||||
|
),
|
||||||
|
maxCo_
|
||||||
|
(
|
||||||
|
mesh.time().controlDict().getOrDefault<scalar>("maxCo", 1.0)
|
||||||
|
),
|
||||||
|
maxDeltaT_
|
||||||
|
(
|
||||||
|
mesh.time().controlDict().getOrDefault<scalar>("maxDeltaT", GREAT)
|
||||||
|
),
|
||||||
|
primalStartTimeIndex_(mesh_.time().timeIndex()),
|
||||||
|
deltaTList_(0),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
/*correctPhi_
|
||||||
|
(
|
||||||
|
solverControl_().dict().getOrDefault("correctPhi", mesh_.dynamic())
|
||||||
|
),
|
||||||
|
checkMeshCourantNo_
|
||||||
|
(
|
||||||
|
solverControl_().dict().getOrDefault("checkMeshCourantNo", false)
|
||||||
|
),
|
||||||
|
moveMeshOuterCorrectors_
|
||||||
|
(
|
||||||
|
solverControl_().dict().getOrDefault("moveMeshOuterCorrectors", false)
|
||||||
|
)*/
|
||||||
|
{
|
||||||
|
addExtraSchemes();
|
||||||
|
setRefCell
|
||||||
|
(
|
||||||
|
incoVars_.pInst(),
|
||||||
|
solverControl_().dict(),
|
||||||
|
solverControl_().pRefCell(),
|
||||||
|
solverControl_().pRefValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decide primal storage mechanism
|
||||||
|
if (dict.isDict("storage"))
|
||||||
|
{
|
||||||
|
primalStorage_.reset
|
||||||
|
(
|
||||||
|
primalStorage::New(*this, dict.subDict("storage"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::pimple::readDict(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if (incompressiblePrimalSolver::readDict(dict))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::solveIter()
|
||||||
|
{
|
||||||
|
const Time& time = mesh_.time();
|
||||||
|
//readDyMControls();
|
||||||
|
readTimeControls();
|
||||||
|
setDeltaT();
|
||||||
|
storeDeltaT();
|
||||||
|
setTime();
|
||||||
|
|
||||||
|
// The primal solution at the first time-step does not need to be stored.
|
||||||
|
// When checkpointing is used, the checkpoint at the first time step must
|
||||||
|
// be set, else storeInitialVariables() does nothing
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
if (time.timeIndex() == timeManip_.startTimeIndex() + 1)
|
||||||
|
{
|
||||||
|
primalStorage_().storeInitialVariables();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
primalStorage_().storeVariables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info<< "Time = " << mesh_.time().timeName() << "\n" << endl;
|
||||||
|
|
||||||
|
// Grab references
|
||||||
|
volScalarField& p = incoVars_.pInst();
|
||||||
|
volVectorField& U = incoVars_.UInst();
|
||||||
|
surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
autoPtr<incompressible::turbulenceModel>& turbulence =
|
||||||
|
incoVars_.turbulence();
|
||||||
|
label& pRefCell = solverControl_().pRefCell();
|
||||||
|
scalar& pRefValue = solverControl_().pRefValue();
|
||||||
|
fv::options& fvOptions(fv::options::New(this->mesh_));
|
||||||
|
|
||||||
|
CourantNo();
|
||||||
|
|
||||||
|
while (solverControl_().loop())
|
||||||
|
{
|
||||||
|
// No moving geometries supported for now
|
||||||
|
/*
|
||||||
|
if (solverControl_().firstIter() || moveMeshOuterCorrectors_)
|
||||||
|
{
|
||||||
|
//mesh_.update();
|
||||||
|
|
||||||
|
if (mesh_.changing())
|
||||||
|
{
|
||||||
|
MRF_.update();
|
||||||
|
|
||||||
|
if (correctPhi_)
|
||||||
|
{
|
||||||
|
// Calculate absolute flux
|
||||||
|
// from the mapped surface velocity
|
||||||
|
phi = mesh_.Sf() & Uf_();
|
||||||
|
|
||||||
|
correctPhi();
|
||||||
|
|
||||||
|
// Make the flux relative to the mesh motion
|
||||||
|
fvc::makeRelative(phi, U);
|
||||||
|
}
|
||||||
|
if (checkMeshCourantNo_)
|
||||||
|
{
|
||||||
|
meshCourantNo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Momentum predictor
|
||||||
|
//~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
MRF_.correctBoundaryVelocity(U);
|
||||||
|
|
||||||
|
tmp<fvVectorMatrix> tUEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(U) + fvm::div(phi, U)
|
||||||
|
+ MRF_.DDt(U)
|
||||||
|
+ turbulence->divDevReff(U)
|
||||||
|
==
|
||||||
|
fvOptions(U)
|
||||||
|
);
|
||||||
|
fvVectorMatrix& UEqn = tUEqn.ref();
|
||||||
|
|
||||||
|
UEqn.relax();
|
||||||
|
|
||||||
|
fvOptions.constrain(UEqn);
|
||||||
|
|
||||||
|
if (solverControl_().momentumPredictor())
|
||||||
|
{
|
||||||
|
Foam::solve(UEqn == -fvc::grad(p));
|
||||||
|
|
||||||
|
fvOptions.correct(U);
|
||||||
|
}
|
||||||
|
// Pressure Eq
|
||||||
|
//~~~~~~~~~~~~
|
||||||
|
while (solverControl_().correct())
|
||||||
|
{
|
||||||
|
volScalarField rAU(1.0/UEqn.A());
|
||||||
|
volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));
|
||||||
|
surfaceScalarField phiHbyA
|
||||||
|
(
|
||||||
|
"phiHbyA",
|
||||||
|
fvc::flux(HbyA)
|
||||||
|
+ MRF_.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi, Uf_))
|
||||||
|
);
|
||||||
|
|
||||||
|
MRF_.makeRelative(phiHbyA);
|
||||||
|
|
||||||
|
if (p.needReference())
|
||||||
|
{
|
||||||
|
fvc::makeRelative(phiHbyA, U);
|
||||||
|
adjustPhi(phiHbyA, U, p);
|
||||||
|
fvc::makeAbsolute(phiHbyA, U);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<volScalarField> rAtU(rAU);
|
||||||
|
|
||||||
|
if (solverControl_().consistent())
|
||||||
|
{
|
||||||
|
rAtU = 1.0/max(1.0/rAU - UEqn.H1(), 0.1/rAU);
|
||||||
|
phiHbyA +=
|
||||||
|
fvc::interpolate(rAtU() - rAU)*fvc::snGrad(p)*mesh_.magSf();
|
||||||
|
HbyA -= (rAU - rAtU())*fvc::grad(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solverControl_().nCorrPISO() <= 1)
|
||||||
|
{
|
||||||
|
tUEqn.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the pressure BCs to ensure flux consistency
|
||||||
|
constrainPressure(p, U, phiHbyA, rAtU(), MRF_);
|
||||||
|
|
||||||
|
// Non-orthogonal pressure corrector loop
|
||||||
|
while (solverControl_().correctNonOrthogonal())
|
||||||
|
{
|
||||||
|
fvScalarMatrix pEqn
|
||||||
|
(
|
||||||
|
fvm::laplacian(rAtU(), p) == fvc::div(phiHbyA)
|
||||||
|
);
|
||||||
|
|
||||||
|
pEqn.setReference(pRefCell, pRefValue);
|
||||||
|
|
||||||
|
fvOptions.constrain(pEqn);
|
||||||
|
|
||||||
|
pEqn.solve
|
||||||
|
(
|
||||||
|
mesh_.solver(p.select(solverControl_().finalInnerIter()))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (solverControl_().finalNonOrthogonalIter())
|
||||||
|
{
|
||||||
|
phi = phiHbyA - pEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuityErrors();
|
||||||
|
|
||||||
|
// Explicitly relax pressure for momentum corrector
|
||||||
|
p.relax();
|
||||||
|
|
||||||
|
U = HbyA - rAtU*fvc::grad(p);
|
||||||
|
U.correctBoundaryConditions();
|
||||||
|
fvOptions.correct(U);
|
||||||
|
|
||||||
|
// Correct Uf if the mesh is moving
|
||||||
|
fvc::correctUf(Uf_, U, phi);
|
||||||
|
|
||||||
|
// Make the fluxes relative to the mesh motion
|
||||||
|
fvc::makeRelative(phi, U);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solverControl_().turbCorr())
|
||||||
|
{
|
||||||
|
incoVars_.laminarTransport().correct();
|
||||||
|
turbulence->correct();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print objective values to screen and compute mean value
|
||||||
|
Info<< nl;
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
Info<< obj->objectiveName() << " : " << obj->J() << endl;
|
||||||
|
obj->accumulateJMean();
|
||||||
|
obj->writeInstantaneousValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average fields if necessary
|
||||||
|
incoVars_.computeMeanUnsteadyFields();
|
||||||
|
|
||||||
|
// Calls time.write()
|
||||||
|
solverControl_().writeFields();
|
||||||
|
|
||||||
|
// Print execution time
|
||||||
|
time.printExecutionTime(Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::solve()
|
||||||
|
{
|
||||||
|
// Iterate
|
||||||
|
if (active_)
|
||||||
|
{
|
||||||
|
preLoop();
|
||||||
|
while (loop())
|
||||||
|
{
|
||||||
|
solveIter();
|
||||||
|
}
|
||||||
|
postLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::pimple::run()
|
||||||
|
{
|
||||||
|
//return solverControl_().run();
|
||||||
|
return mesh_.time().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::pimple::loop()
|
||||||
|
{
|
||||||
|
// mesh_.time().run() is actually needed here. Not a mistake.
|
||||||
|
// Chosen for compatibility reasons with the simple and piso algorithms
|
||||||
|
// and the 'solveWithArgs' function at solverTemplates.C
|
||||||
|
return mesh_.time().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::restoreInitValues()
|
||||||
|
{
|
||||||
|
incoVars_.restoreInitValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::preLoop()
|
||||||
|
{
|
||||||
|
// Move to the correct time, if changed by a previous primal solver
|
||||||
|
timeManip_.moveToPrimalStartTime();
|
||||||
|
|
||||||
|
// Get the objectives for this solver
|
||||||
|
if (objectives_.empty())
|
||||||
|
{
|
||||||
|
objectives_ = getObjectiveFunctions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset initial and mean fields before solving
|
||||||
|
restoreInitValues();
|
||||||
|
if (shouldResetMeanFields_)
|
||||||
|
{
|
||||||
|
incoVars_.resetMeanFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate turbulence model fields
|
||||||
|
incoVars_.turbulence()->validate();
|
||||||
|
|
||||||
|
// nullify JMean for all objectives
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
obj->resetJMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset primal storage
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
primalStorage_().scratch();
|
||||||
|
}
|
||||||
|
scratchDeltaTHistory();
|
||||||
|
CourantNo();
|
||||||
|
//createUfIfPresent();
|
||||||
|
setInitialDeltaT();
|
||||||
|
|
||||||
|
// Print out
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Solving primal equations for solver " << solverName() << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::postLoop()
|
||||||
|
{
|
||||||
|
// Store last time instance. Redundant if a single adjoint solver is used,
|
||||||
|
// but necessary for more than one adjoint solvers
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
// Advance time to avoid implications with the checkpointing
|
||||||
|
// implementation and store variables
|
||||||
|
timeManip_.storeTime();
|
||||||
|
const_cast<Time&>(mesh_.time())++;
|
||||||
|
primalStorage_().storeVariables();
|
||||||
|
|
||||||
|
// Retrive time
|
||||||
|
timeManip_.restoreTime();
|
||||||
|
|
||||||
|
// Print storage metrics
|
||||||
|
primalStorage_().storageMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write separators in objective files
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
obj->writeInstantaneousSeparator();
|
||||||
|
}
|
||||||
|
// Safety
|
||||||
|
objectives_.clear();
|
||||||
|
|
||||||
|
// Avoid writting fields if already in an outputTime iter
|
||||||
|
// since results will be written by the solver class either way
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
// Write all fields
|
||||||
|
time.writeNow();
|
||||||
|
// Write dummy turbulence fields if multiple primal solvers exist
|
||||||
|
this->writeNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow mean fields to be zeroed at the next call of preLoop
|
||||||
|
shouldResetMeanFields_ = true;
|
||||||
|
|
||||||
|
// Store endTimeIndex, to be retrieved later by the adjoint
|
||||||
|
timeManip_.storeEndTimeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::pimple::postLineSearch()
|
||||||
|
{
|
||||||
|
// Update averaging window for the next optimisation cycle
|
||||||
|
solverControl_().updateAverageStartTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::pimple::writeData(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.writeEntry("averageIter", solverControl_().averageIter());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,240 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::pimple
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for solution control classes
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef pimple_H
|
||||||
|
#define pimple_H
|
||||||
|
|
||||||
|
#include "incompressiblePrimalSolver.H"
|
||||||
|
#include "PIMPLEControl.H"
|
||||||
|
#include "IOMRFZoneList.H"
|
||||||
|
#include "objective.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class pimple Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class pimple
|
||||||
|
:
|
||||||
|
public incompressiblePrimalSolver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
pimple(const pimple&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const pimple&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Solver control
|
||||||
|
autoPtr<PIMPLEControl> solverControl_;
|
||||||
|
|
||||||
|
//- Boolean defining if primal fields will be initialized from
|
||||||
|
// the current or a costum time-step provided by the user
|
||||||
|
Switch shouldResetMeanFields_;
|
||||||
|
|
||||||
|
//- Reference to incompressibleVars
|
||||||
|
// Used for convenience and to avoid repetitive dynamic_casts
|
||||||
|
// Same as getIncoVars()
|
||||||
|
incompressibleVars& incoVars_;
|
||||||
|
|
||||||
|
//- MRF zones
|
||||||
|
IOMRFZoneList MRF_;
|
||||||
|
|
||||||
|
//- Cumulative continuity error
|
||||||
|
scalar cumulativeContErr_;
|
||||||
|
|
||||||
|
//- List of objectives related to this primal solver
|
||||||
|
List<objective*> objectives_;
|
||||||
|
|
||||||
|
//- Boolean and scalar entries for readDyMControls and
|
||||||
|
// setDeltaT functions
|
||||||
|
bool adjustTimeStep_;
|
||||||
|
scalar maxCo_;
|
||||||
|
scalar maxDeltaT_;
|
||||||
|
scalar CoNum_;
|
||||||
|
/*bool correctPhi_;
|
||||||
|
bool checkMeshCourantNo_;
|
||||||
|
bool moveMeshOuterCorrectors_;*/
|
||||||
|
|
||||||
|
//- velocity field Uf (set only if required)
|
||||||
|
autoPtr<surfaceVectorField> Uf_;
|
||||||
|
|
||||||
|
scalar deltaT0_;
|
||||||
|
|
||||||
|
//- Time-index at the beggining of the primal solution
|
||||||
|
label primalStartTimeIndex_;
|
||||||
|
|
||||||
|
//- List with deltaT values during the solution of the primal problem
|
||||||
|
DynamicList<scalar> deltaTList_;
|
||||||
|
|
||||||
|
//- Time manipulation, common for all primal and adjoint solvers
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Allocate incompressibleVars and return reference to be used for
|
||||||
|
//- convenience in the rest of the class.
|
||||||
|
incompressibleVars& allocateVars(scalar readTime);
|
||||||
|
|
||||||
|
//- Read only the control parameters used by setDeltaT
|
||||||
|
void readTimeControls();
|
||||||
|
|
||||||
|
//- Compute Courant No
|
||||||
|
void CourantNo();
|
||||||
|
|
||||||
|
//- Compute continuity errors
|
||||||
|
void continuityErrors();
|
||||||
|
|
||||||
|
//- Reset time-step to maintain a constant maximum courant Number.
|
||||||
|
// Reduction of time-step is immediate, but increase is damped to
|
||||||
|
// avoid unstable oscillations.
|
||||||
|
void setDeltaT();
|
||||||
|
|
||||||
|
//- Set the initial timestep corresponding to the timestep
|
||||||
|
// adjustment algorithm in setDeltaT but only if it would
|
||||||
|
// reduce the timestep.
|
||||||
|
void setInitialDeltaT();
|
||||||
|
|
||||||
|
//- Increase time
|
||||||
|
void setTime();
|
||||||
|
|
||||||
|
//- Store the current deltaT
|
||||||
|
void storeDeltaT();
|
||||||
|
|
||||||
|
//- Scratch deltaTList_ and deltaT0_
|
||||||
|
void scratchDeltaTHistory();
|
||||||
|
|
||||||
|
/*
|
||||||
|
//- Read among other the control parameters used by setDeltaT
|
||||||
|
void readDyMControls();
|
||||||
|
|
||||||
|
//- Calculates and outputs the mean and maximum Courant Numbers.
|
||||||
|
void meshCourantNo();
|
||||||
|
|
||||||
|
//- Flux correction functions to ensure continuity
|
||||||
|
void correctPhi();
|
||||||
|
|
||||||
|
//- Creates and initialises the velocity field Uf if required.
|
||||||
|
void createUfIfPresent();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("pimple");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh and dictionary
|
||||||
|
pimple
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~pimple() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool readDict(const dictionary& dict) override;
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Execute one iteration of the solution algorithm
|
||||||
|
virtual void solveIter() override;
|
||||||
|
|
||||||
|
//- Main control loop
|
||||||
|
virtual void solve() override;
|
||||||
|
|
||||||
|
//- Looper (advances iters, time step)
|
||||||
|
virtual bool run();
|
||||||
|
virtual bool loop() override;
|
||||||
|
|
||||||
|
//- Restore initial field values if necessary
|
||||||
|
virtual void restoreInitValues() override;
|
||||||
|
|
||||||
|
//- Functions to be called before loop
|
||||||
|
virtual void preLoop() override;
|
||||||
|
|
||||||
|
//- Functions to be called after loop
|
||||||
|
virtual void postLoop() override;
|
||||||
|
|
||||||
|
//- Functions to be called after lineSearch has converged
|
||||||
|
virtual void postLineSearch() override;
|
||||||
|
|
||||||
|
//- Write average iteration
|
||||||
|
virtual bool writeData(Ostream& os) const override;
|
||||||
|
|
||||||
|
|
||||||
|
// Info to the AdjointSolver
|
||||||
|
|
||||||
|
//- Return a scalarList with all deltaT of the primal solution
|
||||||
|
const DynamicList<scalar>& getDeltaTList() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,467 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "piso.H"
|
||||||
|
#include "findRefCell.H"
|
||||||
|
#include "constrainHbyA.H"
|
||||||
|
#include "constrainPressure.H"
|
||||||
|
#include "adjustPhi.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "fvOptions.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "profiling.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(piso, 0);
|
||||||
|
addToRunTimeSelectionTable(incompressiblePrimalSolver, piso, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::piso::printFields()
|
||||||
|
{
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
const word timeName = mesh_.time().timeName();
|
||||||
|
const word prefix = "after solving for t = " + timeName + " ";
|
||||||
|
volScalarField& p = incoVars_.pInst();
|
||||||
|
volVectorField& U = incoVars_.UInst();
|
||||||
|
surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
Info<< "Debug: U.nOldTimes() = " << U.nOldTimes() << endl;
|
||||||
|
Info<< "Debug: phi.nOldTimes() = " << phi.nOldTimes() << endl;
|
||||||
|
Info<< prefix << "p:\n" << p << endl;
|
||||||
|
Info<< prefix << "U:\n" << U << endl;
|
||||||
|
Info<< prefix << "U.oldTime():\n" << U.oldTime() << endl;
|
||||||
|
Info<< prefix << "phi:\n" << phi << endl;
|
||||||
|
Info<< prefix << "phi.oldTime():\n" << phi.oldTime() << endl;
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
Info<< "Debug: TMVar1.nOldTimes() = "
|
||||||
|
<< rasVars.TMVar1Inst().nOldTimes() << endl;
|
||||||
|
Info<< prefix << " TMVar1:\n" << rasVars.TMVar1Inst() << endl;
|
||||||
|
Info<< prefix << " TMVar1.oldTime():\n"
|
||||||
|
<< rasVars.TMVar1Inst().oldTime() << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
Info<< "Debug: TMVar2.nOldTimes() = "
|
||||||
|
<< rasVars.TMVar2Inst().nOldTimes() << endl;
|
||||||
|
Info<< prefix << " TMVar2:\n" << rasVars.TMVar2Inst() << endl;
|
||||||
|
Info<< prefix << " TMVar2.oldTime():\n"
|
||||||
|
<< rasVars.TMVar2Inst().oldTime() << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasNut())
|
||||||
|
{
|
||||||
|
Info << prefix << " nut:\n" << rasVars.nutRefInst() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::incompressibleVars& Foam::piso::allocateVars(scalar readTime)
|
||||||
|
{
|
||||||
|
vars_.reset(new incompressibleVars(mesh_, solverControl_(), readTime));
|
||||||
|
return getIncoVars();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::CourantNo() const
|
||||||
|
{
|
||||||
|
const surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
#include "CourantNo.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::continuityErrors()
|
||||||
|
{
|
||||||
|
// Original function at
|
||||||
|
// src/finiteVolume/cfdTools/incompressible/continuityErrs.H
|
||||||
|
const Time& runTime = mesh_.time();
|
||||||
|
const fvMesh& mesh = mesh_;
|
||||||
|
const surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
scalar& cumulativeContErr = cumulativeContErr_;
|
||||||
|
#include "continuityErrs.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::piso::piso
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
|
)
|
||||||
|
:
|
||||||
|
incompressiblePrimalSolver
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
managerType,
|
||||||
|
dict,
|
||||||
|
useCustomReadTime
|
||||||
|
),
|
||||||
|
solverControl_(PISOControl::New(mesh, managerType, *this)),
|
||||||
|
shouldResetMeanFields_(useCustomReadTime),
|
||||||
|
incoVars_
|
||||||
|
(
|
||||||
|
allocateVars
|
||||||
|
(
|
||||||
|
useCustomReadTime ? dict.getOrDefault<scalar>("readTime", 0) : -1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
MRF_(mesh, word(useSolverNameForFields() ? solverName() : word::null)),
|
||||||
|
cumulativeContErr_(Zero),
|
||||||
|
objectives_(0),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
addExtraSchemes();
|
||||||
|
setRefCell
|
||||||
|
(
|
||||||
|
incoVars_.pInst(),
|
||||||
|
solverControl_().dict(),
|
||||||
|
solverControl_().pRefCell(),
|
||||||
|
solverControl_().pRefValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decide primal storage mechanism
|
||||||
|
if (dict.isDict("storage"))
|
||||||
|
{
|
||||||
|
primalStorage_.reset
|
||||||
|
(
|
||||||
|
primalStorage::New(*this, dict.subDict("storage"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::piso::readDict(const dictionary& dict)
|
||||||
|
{
|
||||||
|
if (incompressiblePrimalSolver::readDict(dict))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::solveIter()
|
||||||
|
{
|
||||||
|
addProfiling(piso, "piso::solveIter()");
|
||||||
|
const Time& time = mesh_.time();
|
||||||
|
// The primal solution at the first time-step does not need to be stored.
|
||||||
|
// However, when checkpointing is used, the checkpoint at the first time
|
||||||
|
// step must be set; storeInitialVariables() does nothing in other cases.
|
||||||
|
// Note: would make sense to be at the end of the iteration but
|
||||||
|
// checkpoint intricaties suggest it should remain here
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
if (time.timeIndex() == timeManip_.startTimeIndex() + 1)
|
||||||
|
{
|
||||||
|
primalStorage_().storeInitialVariables();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
primalStorage_().storeVariables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info<< "Time = " << mesh_.time().timeName() << "\n" << endl;
|
||||||
|
|
||||||
|
// Grab references
|
||||||
|
volScalarField& p = incoVars_.pInst();
|
||||||
|
volVectorField& U = incoVars_.UInst();
|
||||||
|
surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
|
autoPtr<incompressible::turbulenceModel>& turbulence =
|
||||||
|
incoVars_.turbulence();
|
||||||
|
label& pRefCell = solverControl_().pRefCell();
|
||||||
|
scalar& pRefValue = solverControl_().pRefValue();
|
||||||
|
fv::options& fvOptions(fv::options::New(this->mesh_));
|
||||||
|
|
||||||
|
CourantNo();
|
||||||
|
|
||||||
|
// Momentum predictor
|
||||||
|
//~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
MRF_.correctBoundaryVelocity(U);
|
||||||
|
|
||||||
|
tmp<fvVectorMatrix> tUEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(U) + fvm::div(phi, U)
|
||||||
|
+ MRF_.DDt(U)
|
||||||
|
+ turbulence->divDevReff(U)
|
||||||
|
==
|
||||||
|
fvOptions(U)
|
||||||
|
);
|
||||||
|
fvVectorMatrix& UEqn = tUEqn.ref();
|
||||||
|
|
||||||
|
UEqn.relax();
|
||||||
|
|
||||||
|
fvOptions.constrain(UEqn);
|
||||||
|
|
||||||
|
if (solverControl_().momentumPredictor())
|
||||||
|
{
|
||||||
|
Foam::solve(UEqn == -fvc::grad(p));
|
||||||
|
|
||||||
|
fvOptions.correct(U);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pressure Eq
|
||||||
|
//~~~~~~~~~~~~
|
||||||
|
while (solverControl_().correct())
|
||||||
|
{
|
||||||
|
volScalarField rAU(1.0/UEqn.A());
|
||||||
|
volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));
|
||||||
|
surfaceScalarField phiHbyA
|
||||||
|
(
|
||||||
|
"phiHbyA",
|
||||||
|
fvc::flux(HbyA)
|
||||||
|
+ MRF_.zeroFilter(fvc::interpolate(rAU)*fvc::ddtCorr(U, phi))
|
||||||
|
);
|
||||||
|
|
||||||
|
MRF_.makeRelative(phiHbyA);
|
||||||
|
|
||||||
|
adjustPhi(phiHbyA, U, p);
|
||||||
|
|
||||||
|
// Update the pressure BCs to ensure flux consistency
|
||||||
|
constrainPressure(p, U, phiHbyA, rAU, MRF_);
|
||||||
|
|
||||||
|
// Non-orthogonal pressure corrector loop
|
||||||
|
while (solverControl_().correctNonOrthogonal())
|
||||||
|
{
|
||||||
|
fvScalarMatrix pEqn
|
||||||
|
(
|
||||||
|
fvm::laplacian(rAU, p) == fvc::div(phiHbyA)
|
||||||
|
);
|
||||||
|
|
||||||
|
pEqn.setReference(pRefCell, pRefValue);
|
||||||
|
|
||||||
|
fvOptions.constrain(pEqn);
|
||||||
|
|
||||||
|
pEqn.solve
|
||||||
|
(
|
||||||
|
mesh_.solver(p.select(solverControl_().finalInnerIter()))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (solverControl_().finalNonOrthogonalIter())
|
||||||
|
{
|
||||||
|
phi = phiHbyA - pEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuityErrors();
|
||||||
|
|
||||||
|
U = HbyA - rAU*fvc::grad(p);
|
||||||
|
U.correctBoundaryConditions();
|
||||||
|
fvOptions.correct(U);
|
||||||
|
}
|
||||||
|
// An extra correction of the BC of p would be necessary to have
|
||||||
|
// consistency for p upon reconstruction during the adjoint run.
|
||||||
|
// However, this would slightly affect the primal solution, which is
|
||||||
|
// something we want to avoid. A small inconsistency between the field
|
||||||
|
// computed by the primal solver and the reconstructed one may occur, when
|
||||||
|
// BCs depending on the flux value (e.g. outletInlet) are used. To avoid
|
||||||
|
// this inconsistency activate 'storeAllBoundaries' in the storade
|
||||||
|
// subdictionary, although this means that all field boundaries will be
|
||||||
|
// stored and the correctBCs will not be called upon reconstruction.
|
||||||
|
// p.correctBoundaryConditions();
|
||||||
|
|
||||||
|
incoVars_.laminarTransport().correct();
|
||||||
|
turbulence->correct();
|
||||||
|
|
||||||
|
// Print objective values to screen and compute mean value
|
||||||
|
Info<< endl;
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
Info<< obj->objectiveName() << " : " << obj->J() << endl;
|
||||||
|
obj->accumulateJMean();
|
||||||
|
obj->writeInstantaneousValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average fields if necessary
|
||||||
|
incoVars_.computeMeanUnsteadyFields();
|
||||||
|
|
||||||
|
// Calls time.write()
|
||||||
|
solverControl_().writeFields();
|
||||||
|
|
||||||
|
// Print execution time
|
||||||
|
time.printExecutionTime(Info);
|
||||||
|
|
||||||
|
printFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::solve()
|
||||||
|
{
|
||||||
|
// Iterate
|
||||||
|
if (active_)
|
||||||
|
{
|
||||||
|
preLoop();
|
||||||
|
while (loop())
|
||||||
|
{
|
||||||
|
this->solveIter();
|
||||||
|
}
|
||||||
|
postLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::piso::loop()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
return time.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::restoreInitValues()
|
||||||
|
{
|
||||||
|
incoVars_.restoreInitValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::preLoop()
|
||||||
|
{
|
||||||
|
// Move to the correct time, if changed by a previous primal solver
|
||||||
|
timeManip_.moveToPrimalStartTime();
|
||||||
|
|
||||||
|
// Get the objectives for this solver
|
||||||
|
if (objectives_.empty())
|
||||||
|
{
|
||||||
|
objectives_ = getObjectiveFunctions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset initial and mean fields before solving
|
||||||
|
restoreInitValues();
|
||||||
|
if (shouldResetMeanFields_)
|
||||||
|
{
|
||||||
|
incoVars_.resetMeanFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate turbulence model fields
|
||||||
|
incoVars_.turbulence()->validate();
|
||||||
|
|
||||||
|
// nullify JMean for all objectives
|
||||||
|
// Note: we should cover the same of continuing avegaring the objective
|
||||||
|
// after a primal restart
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
obj->resetJMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset primal storage
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
primalStorage_().scratch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print out
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Solving primal equations for solver " << solverName() << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
|
||||||
|
printFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::postLoop()
|
||||||
|
{
|
||||||
|
addProfiling(piso, "piso::postLoop()");
|
||||||
|
// Store last time instance. Redundant if a single adjoint solver is used,
|
||||||
|
// but necessary for more than one adjoint solvers
|
||||||
|
if (primalStorage_.valid())
|
||||||
|
{
|
||||||
|
// Advance time to avoid implications with the checkpointing
|
||||||
|
// implementation and store variables
|
||||||
|
timeManip_.storeTime();
|
||||||
|
const_cast<Time&>(mesh_.time())++;
|
||||||
|
primalStorage_().storeVariables();
|
||||||
|
|
||||||
|
// Restore time
|
||||||
|
timeManip_.restoreTime();
|
||||||
|
|
||||||
|
primalStorage_().storageMetrics();
|
||||||
|
}
|
||||||
|
// Write separators in objective files
|
||||||
|
for (objective* obj : objectives_)
|
||||||
|
{
|
||||||
|
obj->writeInstantaneousSeparator();
|
||||||
|
}
|
||||||
|
// Safety
|
||||||
|
objectives_.clear();
|
||||||
|
|
||||||
|
// Avoid writting fields if already in an outputTime iter
|
||||||
|
// since results will be written by the solver class either way
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
if (!time.writeTime())
|
||||||
|
{
|
||||||
|
// Write all fields
|
||||||
|
time.writeNow();
|
||||||
|
// Write dummy turbulence fields if multiple primal solvers exist,
|
||||||
|
// to support seamless restarts
|
||||||
|
this->writeNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow mean fields to be zeroed at the next call of preLoop
|
||||||
|
shouldResetMeanFields_ = true;
|
||||||
|
|
||||||
|
// Store endTimeIndex, to be retrieved later by the adjoint
|
||||||
|
timeManip_.storeEndTimeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::piso::postLineSearch()
|
||||||
|
{
|
||||||
|
// Update averaging window for the next optimisation cycle
|
||||||
|
solverControl_().updateAverageStartTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::piso::writeData(Ostream& os) const
|
||||||
|
{
|
||||||
|
os.writeEntry("averageIter", solverControl_().averageIter());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::piso
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for solution control classes
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef piso_H
|
||||||
|
#define piso_H
|
||||||
|
|
||||||
|
#include "incompressiblePrimalSolver.H"
|
||||||
|
#include "PISOControl.H"
|
||||||
|
#include "IOMRFZoneList.H"
|
||||||
|
#include "objective.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class piso Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class piso
|
||||||
|
:
|
||||||
|
public incompressiblePrimalSolver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
piso(const piso&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const piso&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Solver control
|
||||||
|
autoPtr<PISOControl> solverControl_;
|
||||||
|
|
||||||
|
//- Boolean defining if primal fields will be initialized from
|
||||||
|
// the current or a costum time-step provided by the user
|
||||||
|
Switch shouldResetMeanFields_;
|
||||||
|
|
||||||
|
//- Reference to incompressibleVars
|
||||||
|
// Used for convenience and to avoid repetitive dynamic_casts
|
||||||
|
// Same as getIncoVars()
|
||||||
|
incompressibleVars& incoVars_;
|
||||||
|
|
||||||
|
//- MRF zones
|
||||||
|
IOMRFZoneList MRF_;
|
||||||
|
|
||||||
|
//- Cumulative continuity error
|
||||||
|
scalar cumulativeContErr_;
|
||||||
|
|
||||||
|
//- List of objectives related to this primal solver
|
||||||
|
List<objective*> objectives_;
|
||||||
|
|
||||||
|
//- Time manipulation, common for all primal and adjoint solvers
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Protected Member Functions
|
||||||
|
|
||||||
|
//- Print flow fields if in debug mode
|
||||||
|
void printFields();
|
||||||
|
|
||||||
|
//- Allocate incompressibleVars and return reference to be used for
|
||||||
|
//- convenience in the rest of the class.
|
||||||
|
incompressibleVars& allocateVars(scalar readTime);
|
||||||
|
|
||||||
|
//- Compute Courant No
|
||||||
|
void CourantNo() const;
|
||||||
|
|
||||||
|
//- Compute continuity errors
|
||||||
|
void continuityErrors();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("piso");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh and dictionary
|
||||||
|
piso
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~piso() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool readDict(const dictionary& dict);
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Execute one iteration of the solution algorithm
|
||||||
|
virtual void solveIter() override;
|
||||||
|
|
||||||
|
//- Main control loop
|
||||||
|
virtual void solve() override;
|
||||||
|
|
||||||
|
//- Looper (advances iters, time step)
|
||||||
|
virtual bool loop() override;
|
||||||
|
|
||||||
|
//- Restore initial field values if necessary
|
||||||
|
virtual void restoreInitValues() override;
|
||||||
|
|
||||||
|
//- Functions to be called before loop
|
||||||
|
virtual void preLoop() override;
|
||||||
|
|
||||||
|
//- Functions to be called after loop
|
||||||
|
virtual void postLoop() override;
|
||||||
|
|
||||||
|
//- Functions to be called after lineSearch has converged
|
||||||
|
virtual void postLineSearch() override;
|
||||||
|
|
||||||
|
//- Write average iteration
|
||||||
|
virtual bool writeData(Ostream& os) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -53,20 +53,6 @@ Foam::incompressibleVars& Foam::simple::allocateVars()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::simple::addExtraSchemes()
|
|
||||||
{
|
|
||||||
if (incoVars_.useSolverNameForFields())
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "useSolverNameForFields is set to true for primalSolver "
|
|
||||||
<< solverName() << nl << tab
|
|
||||||
<< "Appending variable names with the solver name" << nl << tab
|
|
||||||
<< "Please adjust the necessary entries in fvSchemes and fvSolution"
|
|
||||||
<< nl << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::simple::continuityErrors()
|
void Foam::simple::continuityErrors()
|
||||||
{
|
{
|
||||||
surfaceScalarField& phi = incoVars_.phiInst();
|
surfaceScalarField& phi = incoVars_.phiInst();
|
||||||
@ -92,10 +78,11 @@ Foam::simple::simple
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
incompressiblePrimalSolver(mesh, managerType, dict),
|
incompressiblePrimalSolver(mesh, managerType, dict, useCustomReadTime),
|
||||||
solverControl_(SIMPLEControl::New(mesh, managerType, *this)),
|
solverControl_(SIMPLEControl::New(mesh, managerType, *this)),
|
||||||
incoVars_(allocateVars()),
|
incoVars_(allocateVars()),
|
||||||
MRF_(mesh, word(useSolverNameForFields() ? solverName() : word::null)),
|
MRF_(mesh, word(useSolverNameForFields() ? solverName() : word::null)),
|
||||||
|
|||||||
@ -93,11 +93,6 @@ protected:
|
|||||||
//- convenience in the rest of the class.
|
//- convenience in the rest of the class.
|
||||||
incompressibleVars& allocateVars();
|
incompressibleVars& allocateVars();
|
||||||
|
|
||||||
//- In case variable names are different than the base ones,
|
|
||||||
//- add extra schemes and relaxation factors to the appropriate dicts
|
|
||||||
// Note: Not supported for now
|
|
||||||
void addExtraSchemes();
|
|
||||||
|
|
||||||
//- Compute continuity errors
|
//- Compute continuity errors
|
||||||
void continuityErrors();
|
void continuityErrors();
|
||||||
|
|
||||||
@ -117,7 +112,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -46,10 +46,12 @@ Foam::primalSolver::primalSolver
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
solver(mesh, managerType, dict)
|
solver(mesh, managerType, dict),
|
||||||
|
primalStorage_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +61,8 @@ Foam::autoPtr<Foam::primalSolver> Foam::primalSolver::New
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const word solverType(dict.get<word>("type"));
|
const word solverType(dict.get<word>("type"));
|
||||||
@ -77,7 +80,11 @@ Foam::autoPtr<Foam::primalSolver> Foam::primalSolver::New
|
|||||||
) << exit(FatalIOError);
|
) << exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return autoPtr<primalSolver>(ctorPtr(mesh, managerType, dict));
|
return
|
||||||
|
autoPtr<primalSolver>
|
||||||
|
(
|
||||||
|
ctorPtr(mesh, managerType, dict, useCustomReadTime)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -94,6 +101,12 @@ bool Foam::primalSolver::readDict(const dictionary& dict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::primalStorage>& Foam::primalSolver::getPrimalStorage()
|
||||||
|
{
|
||||||
|
return primalStorage_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::primalSolver::correctBoundaryConditions()
|
void Foam::primalSolver::correctBoundaryConditions()
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -40,6 +40,7 @@ Description
|
|||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "solver.H"
|
#include "solver.H"
|
||||||
#include "runTimeSelectionTables.H"
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "primalStorage.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -65,6 +66,16 @@ private:
|
|||||||
void operator=(const primalSolver&) = delete;
|
void operator=(const primalSolver&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Variables
|
||||||
|
|
||||||
|
//- Primal storage strategy
|
||||||
|
// For stroring the primal history, to be later used by the
|
||||||
|
// unsteady adjoint solvers
|
||||||
|
autoPtr<primalStorage> primalStorage_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
@ -84,9 +95,10 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime
|
||||||
),
|
),
|
||||||
(mesh, managerType, dict)
|
(mesh, managerType, dict, useCustomReadTime)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -97,7 +109,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +121,8 @@ public:
|
|||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const word& managerType,
|
const word& managerType,
|
||||||
const dictionary& dict
|
const dictionary& dict,
|
||||||
|
Switch useCustomReadTime = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -120,6 +134,9 @@ public:
|
|||||||
|
|
||||||
virtual bool readDict(const dictionary& dict);
|
virtual bool readDict(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Reference to the primal storage method
|
||||||
|
autoPtr<primalStorage>& getPrimalStorage();
|
||||||
|
|
||||||
|
|
||||||
// Evolution
|
// Evolution
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -146,6 +146,12 @@ void Foam::solver::postLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::solver::postLineSearch()
|
||||||
|
{
|
||||||
|
// Does nothing in the base class
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::solver::updateOptTypeSource
|
void Foam::solver::updateOptTypeSource
|
||||||
(
|
(
|
||||||
const autoPtr<volScalarField>& optSourcePtr
|
const autoPtr<volScalarField>& optSourcePtr
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -165,6 +165,9 @@ public:
|
|||||||
//- Functions to be called after loop
|
//- Functions to be called after loop
|
||||||
virtual void postLoop();
|
virtual void postLoop();
|
||||||
|
|
||||||
|
//- Functions to be called after lineSearch has converged
|
||||||
|
virtual void postLineSearch();
|
||||||
|
|
||||||
//- Update source term related to optimisationType
|
//- Update source term related to optimisationType
|
||||||
void updateOptTypeSource
|
void updateOptTypeSource
|
||||||
(
|
(
|
||||||
|
|||||||
@ -0,0 +1,143 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PIMPLEControl.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(PIMPLEControl, 0);
|
||||||
|
defineRunTimeSelectionTable(PIMPLEControl, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::PIMPLEControl::PIMPLEControl
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
:
|
||||||
|
solverControl(solver),
|
||||||
|
pimpleControl(mesh, "PIMPLE", false),
|
||||||
|
managerType_(managerType),
|
||||||
|
pRefCell_(Zero),
|
||||||
|
pRefValue_(Zero),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::PIMPLEControl> Foam::PIMPLEControl::New
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto* ctorPtr = dictionaryConstructorTable(managerType);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalErrorInLookup
|
||||||
|
(
|
||||||
|
"control",
|
||||||
|
managerType,
|
||||||
|
*dictionaryConstructorTablePtr_
|
||||||
|
) << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<PIMPLEControl>(ctorPtr(mesh, managerType, solver));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PIMPLEControl::read()
|
||||||
|
{
|
||||||
|
pimpleControl::read();
|
||||||
|
solverControl::read();
|
||||||
|
|
||||||
|
// Always store initial field values in unsteady runs
|
||||||
|
storeInitValues_ = true;
|
||||||
|
|
||||||
|
/*Info<< nl << algorithmName_;
|
||||||
|
|
||||||
|
if (nCorrPIMPLE_ > 1)
|
||||||
|
{
|
||||||
|
if (residualControl_.empty())
|
||||||
|
{
|
||||||
|
Info<< ": no residual control data found. "
|
||||||
|
<< "Calculations will employ " << nCorrPIMPLE_
|
||||||
|
<< " corrector loops" << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< ": max iterations = " << nCorrPIMPLE_ << nl;
|
||||||
|
|
||||||
|
for (const fieldData& ctrl : residualControl_)
|
||||||
|
{
|
||||||
|
Info<< " field " << ctrl.name << token::TAB
|
||||||
|
<< ": relTol " << ctrl.relTol
|
||||||
|
<< ", tolerance " << ctrl.absTol
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< ": Operating solver in PISO mode" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< endl;*/
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::PIMPLEControl::updateAverageStartTime()
|
||||||
|
{
|
||||||
|
averageStartTime_ += timeManip_.span();
|
||||||
|
DebugInfo
|
||||||
|
<< "Set averageStartTime to " << averageStartTime_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,185 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PIMPLEControl
|
||||||
|
|
||||||
|
Description
|
||||||
|
PIMPLE control class to supply convergence information/checks for
|
||||||
|
the PIMPLE loop.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PIMPLEControl_H
|
||||||
|
#define PIMPLEControl_H
|
||||||
|
|
||||||
|
#include "solverControl.H"
|
||||||
|
#include "pimpleControl.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PIMPLEControl Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class PIMPLEControl
|
||||||
|
:
|
||||||
|
public solverControl,
|
||||||
|
public pimpleControl
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Optimisation type
|
||||||
|
const word& managerType_;
|
||||||
|
|
||||||
|
//- Pressure reference cell
|
||||||
|
label pRefCell_;
|
||||||
|
//
|
||||||
|
//- Pressure reference value
|
||||||
|
scalar pRefValue_;
|
||||||
|
|
||||||
|
//- Time manipulation during unsteady optimisation
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
PIMPLEControl(const PIMPLEControl&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const PIMPLEControl&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("PIMPLEControl");
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
PIMPLEControl,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
),
|
||||||
|
(mesh, managerType, solver)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
PIMPLEControl
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PIMPLEControl() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<PIMPLEControl> New
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool read();
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return the solution dictionary
|
||||||
|
inline virtual const dictionary dict() const;
|
||||||
|
|
||||||
|
//- Return pressure reference cell
|
||||||
|
inline label& pRefCell();
|
||||||
|
|
||||||
|
//- Return pressure reference value
|
||||||
|
inline scalar& pRefValue();
|
||||||
|
|
||||||
|
//- Return the time span of each optimisation cycle
|
||||||
|
inline scalar timeSpan() const;
|
||||||
|
|
||||||
|
//- Update the start time of averaging for the next opt. cycle
|
||||||
|
void updateAverageStartTime();
|
||||||
|
|
||||||
|
|
||||||
|
// Solution control
|
||||||
|
|
||||||
|
//- Whether to call time.write() or not
|
||||||
|
virtual void writeFields() = 0;
|
||||||
|
|
||||||
|
//- Use averaged fields?
|
||||||
|
// For solving the adjoint equations or computing sensitivities
|
||||||
|
// based on averaged fields
|
||||||
|
inline bool useAveragedFields() const;
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Loop
|
||||||
|
virtual bool loop() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
#include "PIMPLEControlI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline const Foam::dictionary Foam::PIMPLEControl::dict() const
|
||||||
|
{
|
||||||
|
return solutionDict();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label& Foam::PIMPLEControl::pRefCell()
|
||||||
|
{
|
||||||
|
return pRefCell_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar& Foam::PIMPLEControl::pRefValue()
|
||||||
|
{
|
||||||
|
return pRefValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar Foam::PIMPLEControl::timeSpan() const
|
||||||
|
{
|
||||||
|
return timeManip_.span();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::PIMPLEControl::useAveragedFields() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PIMPLEControlOpt.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(PIMPLEControlOpt, 0);
|
||||||
|
addToRunTimeSelectionTable(PIMPLEControl, PIMPLEControlOpt, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::PIMPLEControlOpt::PIMPLEControlOpt
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PIMPLEControl(mesh, managerType, solver)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::PIMPLEControlOpt::writeFields()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
time.write();
|
||||||
|
solver_.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PIMPLEControlOpt::loop()
|
||||||
|
{
|
||||||
|
return pimpleControl::loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PIMPLEControlOpt
|
||||||
|
|
||||||
|
Description
|
||||||
|
PIMPLE control class for single runs (i.e. not optimisation).
|
||||||
|
Time acts as in simpleFoam, with all solver control read through
|
||||||
|
optimisationDict
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PIMPLEControlOpt_H
|
||||||
|
#define PIMPLEControlOpt_H
|
||||||
|
|
||||||
|
#include "PIMPLEControl.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PIMPLEControlOpt Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class PIMPLEControlOpt
|
||||||
|
:
|
||||||
|
public PIMPLEControl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
PIMPLEControlOpt(const PIMPLEControlOpt&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const PIMPLEControlOpt&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("unsteadyOptimisation");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
PIMPLEControlOpt
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PIMPLEControlOpt() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Solution control
|
||||||
|
|
||||||
|
//- Whether to call time.write() or not
|
||||||
|
virtual void writeFields();
|
||||||
|
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Loop
|
||||||
|
virtual bool loop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PISOControl.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(PISOControl, 0);
|
||||||
|
defineRunTimeSelectionTable(PISOControl, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::PISOControl::PISOControl
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
:
|
||||||
|
solverControl(solver),
|
||||||
|
pisoControl(mesh, "PISO"),
|
||||||
|
managerType_(managerType),
|
||||||
|
pRefCell_(Zero),
|
||||||
|
pRefValue_(Zero),
|
||||||
|
timeManip_
|
||||||
|
(
|
||||||
|
const_cast<unsteadyTimeManipulation&>
|
||||||
|
(
|
||||||
|
unsteadyTimeManipulation::New(mesh)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::PISOControl> Foam::PISOControl::New
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto* ctorPtr = dictionaryConstructorTable(managerType);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalErrorInLookup
|
||||||
|
(
|
||||||
|
"control",
|
||||||
|
managerType,
|
||||||
|
*dictionaryConstructorTablePtr_
|
||||||
|
) << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<PISOControl>(ctorPtr(mesh, managerType, solver));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::PISOControl::read()
|
||||||
|
{
|
||||||
|
pisoControl::read();
|
||||||
|
solverControl::read();
|
||||||
|
|
||||||
|
// Always store initial field values in unsteady runs
|
||||||
|
storeInitValues_ = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::PISOControl::updateAverageStartTime()
|
||||||
|
{
|
||||||
|
averageStartTime_ += timeManip_.span();
|
||||||
|
DebugInfo
|
||||||
|
<< "Set averageStartTime to " << averageStartTime_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,186 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PISOControl
|
||||||
|
|
||||||
|
Description
|
||||||
|
PISO control class to supply convergence information/checks for
|
||||||
|
the PISO loop.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PISOControl_H
|
||||||
|
#define PISOControl_H
|
||||||
|
|
||||||
|
#include "solverControl.H"
|
||||||
|
#include "pisoControl.H"
|
||||||
|
#include "unsteadyTimeManipulation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PISOControl Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class PISOControl
|
||||||
|
:
|
||||||
|
public solverControl,
|
||||||
|
public pisoControl
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Optimisation type
|
||||||
|
const word& managerType_;
|
||||||
|
|
||||||
|
//- Pressure reference cell
|
||||||
|
label pRefCell_;
|
||||||
|
//
|
||||||
|
//- Pressure reference value
|
||||||
|
scalar pRefValue_;
|
||||||
|
|
||||||
|
//- Time manipulation during unsteady optimisation
|
||||||
|
unsteadyTimeManipulation& timeManip_;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
PISOControl(const PISOControl&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const PISOControl&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("PISOControl");
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
PISOControl,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
),
|
||||||
|
(mesh, managerType, solver)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
PISOControl
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PISOControl() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<PISOControl> New
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool read();
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return the solution dictionary
|
||||||
|
inline virtual const dictionary dict() const;
|
||||||
|
|
||||||
|
//- Return pressure reference cell
|
||||||
|
inline label& pRefCell();
|
||||||
|
|
||||||
|
//- Return pressure reference value
|
||||||
|
inline scalar& pRefValue();
|
||||||
|
|
||||||
|
//- Return the time span of each optimisation cycle
|
||||||
|
inline scalar timeSpan() const;
|
||||||
|
|
||||||
|
//- Update the start time of averaging for the next opt. cycle
|
||||||
|
void updateAverageStartTime();
|
||||||
|
|
||||||
|
|
||||||
|
// Solution control
|
||||||
|
|
||||||
|
//- Whether to call time.write() or not
|
||||||
|
virtual void writeFields() = 0;
|
||||||
|
|
||||||
|
//- Use averaged fields?
|
||||||
|
// For solving the adjoint equations or computing sensitivities
|
||||||
|
// based on averaged fields
|
||||||
|
inline bool useAveragedFields() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Loop
|
||||||
|
virtual bool loop() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
#include "PISOControlI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline const Foam::dictionary Foam::PISOControl::dict() const
|
||||||
|
{
|
||||||
|
return solutionDict();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label& Foam::PISOControl::pRefCell()
|
||||||
|
{
|
||||||
|
return pRefCell_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar& Foam::PISOControl::pRefValue()
|
||||||
|
{
|
||||||
|
return pRefValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar Foam::PISOControl::timeSpan() const
|
||||||
|
{
|
||||||
|
return timeManip_.span();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::PISOControl::useAveragedFields() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PISOControlOpt.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(PISOControlOpt, 0);
|
||||||
|
addToRunTimeSelectionTable(PISOControl, PISOControlOpt, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::PISOControlOpt::PISOControlOpt
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
)
|
||||||
|
:
|
||||||
|
PISOControl(mesh, managerType, solver)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::PISOControlOpt::writeFields()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
time.write();
|
||||||
|
solver_.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PISOControlOpt::loop()
|
||||||
|
{
|
||||||
|
return pisoControl::loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PISOControlOpt
|
||||||
|
|
||||||
|
Description
|
||||||
|
PISO control class for single runs (i.e. not optimisation).
|
||||||
|
Time acts as in simpleFoam, with all solver control read through
|
||||||
|
optimisationDict
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PISOControlOpt_H
|
||||||
|
#define PISOControlOpt_H
|
||||||
|
|
||||||
|
#include "PISOControl.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PISOControlOpt Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class PISOControlOpt
|
||||||
|
:
|
||||||
|
public PISOControl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
PISOControlOpt(const PISOControlOpt&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const PISOControlOpt&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("unsteadyOptimisation");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
PISOControlOpt
|
||||||
|
(
|
||||||
|
fvMesh& mesh,
|
||||||
|
const word& managerType,
|
||||||
|
const solver& solver
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PISOControlOpt() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Solution control
|
||||||
|
|
||||||
|
//- Whether to call time.write() or not
|
||||||
|
virtual void writeFields();
|
||||||
|
|
||||||
|
|
||||||
|
// Evolution
|
||||||
|
|
||||||
|
//- Loop
|
||||||
|
virtual bool loop();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -36,7 +36,7 @@ License
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
defineTypeNameAndDebug(SIMPLEControlOpt, 1);
|
defineTypeNameAndDebug(SIMPLEControlOpt, 1);
|
||||||
addToRunTimeSelectionTable( SIMPLEControl, SIMPLEControlOpt, dictionary);
|
addToRunTimeSelectionTable(SIMPLEControl, SIMPLEControlOpt, dictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|||||||
@ -46,6 +46,7 @@ bool Foam::solverControl::read()
|
|||||||
// Manage averaging
|
// Manage averaging
|
||||||
dictionary averagingDict = solutionDict().subOrEmptyDict("averaging");
|
dictionary averagingDict = solutionDict().subOrEmptyDict("averaging");
|
||||||
averageStartIter_ = averagingDict.getOrDefault<label>("startIter", -1);
|
averageStartIter_ = averagingDict.getOrDefault<label>("startIter", -1);
|
||||||
|
averageStartTime_ = averagingDict.getOrDefault<scalar>("startTime", -1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -60,6 +61,7 @@ Foam::solverControl::solverControl(const solver& solver)
|
|||||||
iter_(0),
|
iter_(0),
|
||||||
averageIter_(solver.getOrDefault<label>("averageIter", 0)),
|
averageIter_(solver.getOrDefault<label>("averageIter", 0)),
|
||||||
averageStartIter_(-1),
|
averageStartIter_(-1),
|
||||||
|
averageStartTime_(-1),
|
||||||
// Non run-time modifiable options read in the constructor only
|
// Non run-time modifiable options read in the constructor only
|
||||||
storeInitValues_
|
storeInitValues_
|
||||||
(
|
(
|
||||||
|
|||||||
@ -76,6 +76,9 @@ protected:
|
|||||||
//- Averaging start index
|
//- Averaging start index
|
||||||
label averageStartIter_;
|
label averageStartIter_;
|
||||||
|
|
||||||
|
//- Averaging start time
|
||||||
|
scalar averageStartTime_;
|
||||||
|
|
||||||
// Non run-time modifiable entries
|
// Non run-time modifiable entries
|
||||||
|
|
||||||
//- Whether to re-initialize the solution based on the initial
|
//- Whether to re-initialize the solution based on the initial
|
||||||
@ -151,17 +154,30 @@ public:
|
|||||||
//- Return iteration index
|
//- Return iteration index
|
||||||
inline label averageStartIter() const;
|
inline label averageStartIter() const;
|
||||||
|
|
||||||
|
//- Return averaging start time reference for unsteady runs
|
||||||
|
inline scalar& averageStartTime();
|
||||||
|
|
||||||
|
//- Return const averaging start time reference for unsteady runs
|
||||||
|
inline scalar averageStartTime() const;
|
||||||
|
|
||||||
//- Whether or not to add fields of the current iteration to the
|
//- Whether or not to add fields of the current iteration to the
|
||||||
//- average fields
|
//- average fields
|
||||||
inline bool doAverageIter() const;
|
inline bool doAverageIter() const;
|
||||||
|
|
||||||
|
//- Whether or not to add fields of the current time to the
|
||||||
|
//- average fields
|
||||||
|
inline bool doAverageTime() const;
|
||||||
|
|
||||||
//- Use averaged fields?
|
//- Use averaged fields?
|
||||||
//- For solving the adjoint equations or computing sensitivities
|
//- For solving the adjoint equations or computing sensitivities
|
||||||
//- based on averaged fields
|
//- based on averaged fields
|
||||||
inline bool useAveragedFields() const;
|
virtual inline bool useAveragedFields() const;
|
||||||
|
|
||||||
//- Whether averaging is enabled or not
|
//- Whether averaging is enabled or not
|
||||||
inline bool average() const;
|
inline bool average() const;
|
||||||
|
|
||||||
|
//- Return reference to the underlaying solver
|
||||||
|
inline const solver& getSolver() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -78,6 +78,18 @@ inline Foam::label Foam::solverControl::averageStartIter() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar& Foam::solverControl::averageStartTime()
|
||||||
|
{
|
||||||
|
return averageStartTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::scalar Foam::solverControl::averageStartTime() const
|
||||||
|
{
|
||||||
|
return averageStartTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::solverControl::doAverageIter() const
|
inline bool Foam::solverControl::doAverageIter() const
|
||||||
{
|
{
|
||||||
if (average_ && iter_ >= averageStartIter_)
|
if (average_ && iter_ >= averageStartIter_)
|
||||||
@ -91,6 +103,19 @@ inline bool Foam::solverControl::doAverageIter() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::solverControl::doAverageTime() const
|
||||||
|
{
|
||||||
|
if (average_ && solver_.mesh().time().value() >= averageStartTime_)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Foam::solverControl::useAveragedFields() const
|
inline bool Foam::solverControl::useAveragedFields() const
|
||||||
{
|
{
|
||||||
if (average_ && averageIter_)
|
if (average_ && averageIter_)
|
||||||
@ -110,4 +135,10 @@ inline bool Foam::solverControl::average() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::solver& Foam::solverControl::getSolver() const
|
||||||
|
{
|
||||||
|
return solver_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "checkPoint.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(checkPoint, 0);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
checkPoint::checkPoint
|
||||||
|
(
|
||||||
|
storageParameters& storageParams
|
||||||
|
)
|
||||||
|
:
|
||||||
|
vars_(),
|
||||||
|
storageParams_(storageParams),
|
||||||
|
mesh_(storageParams.mesh()),
|
||||||
|
storageMetrics_(),
|
||||||
|
deltaT_(0.),
|
||||||
|
active_(false),
|
||||||
|
placeHolder_(true),
|
||||||
|
a_(-1),
|
||||||
|
checkPointLevel_(-1),
|
||||||
|
checkPointTimeIndex_(-1),
|
||||||
|
checkPointTime_(-1.)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void checkPoint::retrieve()
|
||||||
|
{
|
||||||
|
if (!vars_)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Trying to retrieve solution at t = "
|
||||||
|
<< storageParams_.mesh().time().value()
|
||||||
|
<< " from checkPoint with t = "
|
||||||
|
<< checkPointTime_ << nl
|
||||||
|
<< "but no storage has been allocated." << nl
|
||||||
|
<< "placeHolder checkPoint? " << placeHolder_ << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
vars_().decompress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkPoint::setPlaceHolder(Switch newLevel)
|
||||||
|
{
|
||||||
|
deltaT_ = storageParams_.mesh().time().deltaTValue();
|
||||||
|
active_ = true;
|
||||||
|
placeHolder_ = true;
|
||||||
|
a_ = 0;
|
||||||
|
checkPointTimeIndex_ = storageParams_.mesh().time().timeIndex();
|
||||||
|
checkPointTime_ = storageParams_.mesh().time().value();
|
||||||
|
if (newLevel)
|
||||||
|
{
|
||||||
|
checkPointLevel_ += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkPointLevel_ = 0;
|
||||||
|
}
|
||||||
|
// Clear the previously allocated storage
|
||||||
|
vars_.clear();
|
||||||
|
storageMetrics_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkPoint::store(incompressibleVars& vs, const label a)
|
||||||
|
{
|
||||||
|
placeHolder_ = false;
|
||||||
|
a_ = a;
|
||||||
|
vars_.reset(new fullIncompressibleVars(vs, storageParams_, a_));
|
||||||
|
vars_().compress();
|
||||||
|
storageMetrics_ = vars_().storageMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkPoint::empty()
|
||||||
|
{
|
||||||
|
active_ = false;
|
||||||
|
placeHolder_ = true;
|
||||||
|
checkPointTimeIndex_ = -1;
|
||||||
|
checkPointTime_ = -1;
|
||||||
|
checkPointLevel_ = -1;
|
||||||
|
a_ = -1;
|
||||||
|
vars_.clear();
|
||||||
|
storageMetrics_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkPoint::resetToPlaceHolder()
|
||||||
|
{
|
||||||
|
placeHolder_ = true;
|
||||||
|
a_ = 0;
|
||||||
|
vars_.clear();
|
||||||
|
storageMetrics_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const scalarList& checkPoint::storageMetrics() const
|
||||||
|
{
|
||||||
|
return storageMetrics_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,217 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
checkPoint
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
checkPoint.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef checkPoint_H
|
||||||
|
#define checkPoint_H
|
||||||
|
|
||||||
|
#include "fullIncompressibleVars.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class checkPoint Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class checkPoint
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Variables held by this checkPoint
|
||||||
|
autoPtr<fullIncompressibleVars> vars_;
|
||||||
|
|
||||||
|
storageParameters& storageParams_;
|
||||||
|
|
||||||
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
scalarList storageMetrics_;
|
||||||
|
|
||||||
|
//- deltaT corresponding to the time-step this checkPoint holds
|
||||||
|
scalar deltaT_;
|
||||||
|
|
||||||
|
//- Whether this checkPoint is active
|
||||||
|
Switch active_;
|
||||||
|
|
||||||
|
//- Whether this checkPoint is a placeHolder
|
||||||
|
Switch placeHolder_;
|
||||||
|
|
||||||
|
//- schedule with size equal to nTimeSteps containing the number of
|
||||||
|
//- time-solution that must be stored at the checkPoint:
|
||||||
|
// -1: inactive checkPoint 0: placeholder checkPoint;
|
||||||
|
// 1: single checkPoint 2: double checkPoint
|
||||||
|
label a_;
|
||||||
|
|
||||||
|
label checkPointLevel_;
|
||||||
|
|
||||||
|
label checkPointTimeIndex_;
|
||||||
|
|
||||||
|
scalar checkPointTime_;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
checkPoint(const checkPoint&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const checkPoint&) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("checkPoint");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
checkPoint(storageParameters& storageParams);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~checkPoint() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Access functions
|
||||||
|
|
||||||
|
inline scalar deltaT() const
|
||||||
|
{
|
||||||
|
return deltaT_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar& deltaT()
|
||||||
|
{
|
||||||
|
return deltaT_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Switch active() const
|
||||||
|
{
|
||||||
|
return active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Switch& active()
|
||||||
|
{
|
||||||
|
return active_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Switch& placeHolder() const
|
||||||
|
{
|
||||||
|
return placeHolder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Switch& placeHolder()
|
||||||
|
{
|
||||||
|
return placeHolder_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label a() const
|
||||||
|
{
|
||||||
|
return a_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label& a()
|
||||||
|
{
|
||||||
|
return a_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label level() const
|
||||||
|
{
|
||||||
|
return checkPointLevel_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label& level()
|
||||||
|
{
|
||||||
|
return checkPointLevel_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label timeIndex() const
|
||||||
|
{
|
||||||
|
return checkPointTimeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label& timeIndex()
|
||||||
|
{
|
||||||
|
return checkPointTimeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar timeValue() const
|
||||||
|
{
|
||||||
|
return checkPointTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar& timeValue()
|
||||||
|
{
|
||||||
|
return checkPointTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Function to decompress the incompressible vars and update the
|
||||||
|
//- solver fields with the decompressed ones
|
||||||
|
void retrieve();
|
||||||
|
|
||||||
|
void setPlaceHolder(Switch newLevel);
|
||||||
|
|
||||||
|
//- store function must be called after setPlaceHolder.
|
||||||
|
void store(incompressibleVars& vs, const label a = 2);
|
||||||
|
|
||||||
|
//- Clear the chekpoint memory and reset its properties
|
||||||
|
void empty();
|
||||||
|
|
||||||
|
//- Clear the storage of the checkpoint and make it a placeHolder
|
||||||
|
//- checkpoint
|
||||||
|
void resetToPlaceHolder();
|
||||||
|
|
||||||
|
const scalarList& storageMetrics() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,371 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "compressedIncompressibleVars.H"
|
||||||
|
#include "createZeroField.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(compressedIncompressibleVars, 0);
|
||||||
|
defineRunTimeSelectionTable(compressedIncompressibleVars, dictionary);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::writeLog
|
||||||
|
(
|
||||||
|
const word& name
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const scalar& initialSize = storageMetrics_[0];
|
||||||
|
const scalar& uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
const scalar& uncompressedSize = storageMetrics_[2];
|
||||||
|
const scalar& compressedSize = storageMetrics_[3];
|
||||||
|
if (!initialSize || !uncompressedSize || !uncompressedRoughSize)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "initialSize, uncompressedRoughSize or uncompressedSize is Zero"
|
||||||
|
<< endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
if (!compressedSize)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "compressedSize is Zero" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
unsigned int width = 6;//IOstream::defaultPrecision();
|
||||||
|
Info<< setprecision(width);
|
||||||
|
Info<< name << tab << "pure algorithm's CR = "
|
||||||
|
<< uncompressedSize/compressedSize << endl;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< name << ": Initial Size = "
|
||||||
|
<< initialSize*1.e-6 << " Mb" << nl
|
||||||
|
<< name << ": Initial Size saved = "
|
||||||
|
<< uncompressedRoughSize*1.e-6 << " Mb" << nl
|
||||||
|
<< name << ": Uncompressed Size = "
|
||||||
|
<< uncompressedSize*1.e-6 << " Mb" << nl
|
||||||
|
<< name << ": Compressed Size = "
|
||||||
|
<< compressedSize*1.e-6 << " Mb" << endl;
|
||||||
|
if (name == "All")
|
||||||
|
{
|
||||||
|
Info<< name
|
||||||
|
<< ": Data Increase due to data manipulation before compression = "
|
||||||
|
<< (uncompressedSize-uncompressedRoughSize)/uncompressedRoughSize*100. << "%"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
Info<< name << ": (%) Data Reduction = "
|
||||||
|
<< (uncompressedSize-compressedSize)/uncompressedSize*100. << "%"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
Info<< setprecision(IOstream::defaultPrecision());
|
||||||
|
if (name == "All")
|
||||||
|
{
|
||||||
|
Info << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::write(const label i)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
if (storageFilePtr_.empty())
|
||||||
|
{
|
||||||
|
setStorageFilesPtr();
|
||||||
|
}
|
||||||
|
const scalar initialSize = storageMetrics_[0];
|
||||||
|
const scalar uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
const scalar uncompressedSize = storageMetrics_[2];
|
||||||
|
const scalar compressedSize = storageMetrics_[3];
|
||||||
|
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
storageFilePtr_[i]
|
||||||
|
<< setprecision(6) << setw(8) << mesh_.time().value() << tab
|
||||||
|
<< setprecision(IOstream::defaultPrecision())
|
||||||
|
<< setw(width) << uncompressedSize/compressedSize << tab
|
||||||
|
<< setw(width) << (uncompressedSize-compressedSize)/uncompressedSize*100. << tab
|
||||||
|
<< setw(width) << initialSize*1.e-6 << tab
|
||||||
|
<< setw(width) << uncompressedRoughSize*1.e-6 << tab
|
||||||
|
<< setw(width) << compressedSize*1.e-6 << endl;
|
||||||
|
storageFilePtr_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::setFields()
|
||||||
|
{
|
||||||
|
incompressibleVars& v = incoVars_;
|
||||||
|
p_.reset(compressedVolScalarField::New(v.pInst(), storageParams_, 0, k_));
|
||||||
|
phi_.reset
|
||||||
|
(
|
||||||
|
compressedSurfaceScalarField::New(v.phiInst(), storageParams_, 1, k_)
|
||||||
|
);
|
||||||
|
U_.reset(compressedVolVectorField::New(v.UInst(), storageParams_, 2, k_));
|
||||||
|
incompressible::RASModelVariables& rasVars = v.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
RASModelVars_.append
|
||||||
|
(
|
||||||
|
compressedVolScalarField::New
|
||||||
|
(rasVars.TMVar1Inst(), storageParams_, 3, k_)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
RASModelVars_.append
|
||||||
|
(
|
||||||
|
compressedVolScalarField::New
|
||||||
|
(rasVars.TMVar2Inst(), storageParams_, 4, k_)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::makeFolder()
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
storageFolder_ = mesh_.time().globalPath()/"optimisation"/"storage";
|
||||||
|
if (!isDir(storageFolder_))
|
||||||
|
{
|
||||||
|
mkDir(storageFolder_);
|
||||||
|
WarningInFunction
|
||||||
|
<< "The folder storing the compression metrics should have "
|
||||||
|
<< "been already set."
|
||||||
|
<< nl
|
||||||
|
<< "Possible error in: compressedFullStorage::makeFolder()."
|
||||||
|
<< "Setting folder anyway." << nl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::setStorageFilesPtr()
|
||||||
|
{
|
||||||
|
storageFilePtr_.setSize(7);
|
||||||
|
label Ic = -1;
|
||||||
|
names_.setSize(7, "undefined");
|
||||||
|
names_[++Ic] = "AllFields" + solverName();
|
||||||
|
names_[++Ic] = incoVars_.pInst().name();
|
||||||
|
names_[++Ic] = incoVars_.phiInst().name();
|
||||||
|
names_[++Ic] = incoVars_.UInst().name();
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
forAll(RASModelVars_, iPtr)
|
||||||
|
{
|
||||||
|
if (iPtr == 0)
|
||||||
|
{
|
||||||
|
names_[++Ic] = rasVars.TMVar1Inst().name();
|
||||||
|
}
|
||||||
|
else if (iPtr == 1)
|
||||||
|
{
|
||||||
|
names_[++Ic] = rasVars.TMVar2Inst().name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (label i = 0; i <= Ic; i++)
|
||||||
|
{
|
||||||
|
fileName filePath = storageFolder_/names_[i];
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
storageFilePtr_.set
|
||||||
|
(
|
||||||
|
i, new OFstream(filePath)
|
||||||
|
);
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
storageFilePtr_[i]
|
||||||
|
<< setw(8) << "# Time" << tab
|
||||||
|
<< setw(width) << "algorithm's CR" << tab
|
||||||
|
<< setw(width) << "(%) Reduction" << tab
|
||||||
|
<< setw(width) << "Initial Size (Mb)" << tab
|
||||||
|
<< setw(width) << "Uncompressed Size (Mb)" << tab
|
||||||
|
<< setw(width) << "Compressed Size (Mb)" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
storageFilePtr_.set
|
||||||
|
(
|
||||||
|
i,
|
||||||
|
new OFstream
|
||||||
|
(
|
||||||
|
filePath,
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::currentVersion,
|
||||||
|
IOstream::UNCOMPRESSED,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
compressedIncompressibleVars::compressedIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
)
|
||||||
|
:
|
||||||
|
variablesSet
|
||||||
|
(
|
||||||
|
vs.mesh(),
|
||||||
|
vs.solverControlReference().solverDict()
|
||||||
|
),
|
||||||
|
incoVars_(vs),
|
||||||
|
solverControl_(vs.solverControlReference()),
|
||||||
|
storageParams_(storageParams),
|
||||||
|
k_(0),
|
||||||
|
kCopy_(k_),
|
||||||
|
p_(nullptr),
|
||||||
|
phi_(nullptr),
|
||||||
|
U_(nullptr),
|
||||||
|
RASModelVars_(),
|
||||||
|
timeIndex_(mesh_.time().timeIndex()),
|
||||||
|
timeValue_(mesh_.time().value()),
|
||||||
|
storageMetrics_(),
|
||||||
|
names_(7, "undefined"),
|
||||||
|
storageFilePtr_()
|
||||||
|
{
|
||||||
|
setFields();
|
||||||
|
makeFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
autoPtr<compressedIncompressibleVars> compressedIncompressibleVars::New
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word type = storageParams.algorithm() + "IncompressibleVars";
|
||||||
|
DebugInfo
|
||||||
|
<< "compressedIncompressibleVars type for the primal fields: " << type
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
auto cstrIter = dictionaryConstructorTablePtr_->cfind(type);
|
||||||
|
|
||||||
|
if (!cstrIter.found())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unknown compressedIncompressibleVars type " << type << nl << nl
|
||||||
|
<< "Valid compressedIncompressibleVars types are :" << nl
|
||||||
|
<< dictionaryConstructorTablePtr_->sortedToc()
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<compressedIncompressibleVars>
|
||||||
|
(cstrIter()(vs, storageParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::calculateStorageMetrics()
|
||||||
|
{
|
||||||
|
storageMetrics_.setSize(p_().storageMetrics().size());
|
||||||
|
label i = 0;
|
||||||
|
if (!storageParams_.timing())
|
||||||
|
{
|
||||||
|
calculateAndWrite(p_(), incoVars_.pInst().name(), i);
|
||||||
|
calculateAndWrite(phi_(), incoVars_.phiInst().name(), i);
|
||||||
|
calculateAndWrite(U_(), incoVars_.UInst().name(), i);
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
calculateAndWrite(RASModelVars_[0], rasVars.TMVar1Inst().name(), i);
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
calculateAndWrite(RASModelVars_[1], rasVars.TMVar2Inst().name(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storageMetrics_ =
|
||||||
|
p_().storageMetrics()
|
||||||
|
+ phi_().storageMetrics()
|
||||||
|
+ U_().storageMetrics();
|
||||||
|
|
||||||
|
forAll(RASModelVars_, iPtr)
|
||||||
|
{
|
||||||
|
storageMetrics_ =
|
||||||
|
storageMetrics_ + RASModelVars_[iPtr].storageMetrics();
|
||||||
|
}
|
||||||
|
if (!storageParams_.timing())
|
||||||
|
{
|
||||||
|
write(0);
|
||||||
|
writeLog("All");
|
||||||
|
}
|
||||||
|
storageFilePtr_.clear();
|
||||||
|
names_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::compress()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void compressedIncompressibleVars::decompress()
|
||||||
|
{
|
||||||
|
this->decompress(incoVars_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const scalarList& compressedIncompressibleVars::storageMetrics() const
|
||||||
|
{
|
||||||
|
return storageMetrics_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,228 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::compressedIncompressibleVars
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class for solution control classes
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef compressedIncompressibleVars_H
|
||||||
|
#define compressedIncompressibleVars_H
|
||||||
|
|
||||||
|
#include "incompressibleVars.H"
|
||||||
|
#include "compressedGeometricFields.H"
|
||||||
|
#include "storageParameters.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class compressedIncompressibleVars Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class compressedIncompressibleVars
|
||||||
|
:
|
||||||
|
public variablesSet
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Vars seen by the solver
|
||||||
|
incompressibleVars& incoVars_;
|
||||||
|
|
||||||
|
//- Solver control related to the base variables
|
||||||
|
const solverControl& solverControl_;
|
||||||
|
|
||||||
|
storageParameters& storageParams_;
|
||||||
|
|
||||||
|
//- Current S/N of the time-step that is compressed in the present
|
||||||
|
//- object.
|
||||||
|
// Useful when more than one time-steps are compressed
|
||||||
|
// in the same compressedIncompressibleVars (e.g. iPGD algorithm)
|
||||||
|
label k_;
|
||||||
|
|
||||||
|
label kCopy_;
|
||||||
|
|
||||||
|
//- Compressed fields including turbulence
|
||||||
|
autoPtr<compressedVolScalarField> p_;
|
||||||
|
autoPtr<compressedSurfaceScalarField> phi_;
|
||||||
|
autoPtr<compressedVolVectorField> U_;
|
||||||
|
PtrList<compressedVolScalarField> RASModelVars_;
|
||||||
|
|
||||||
|
//- Time value and index
|
||||||
|
label timeIndex_;
|
||||||
|
|
||||||
|
scalar timeValue_;
|
||||||
|
|
||||||
|
//- List that holds the compression metrics (initial size, compressed
|
||||||
|
//- size if compression is applied, etc) for all fields of the current
|
||||||
|
//- time step.
|
||||||
|
scalarList storageMetrics_;
|
||||||
|
|
||||||
|
//- Variables used for writing the compression metrics
|
||||||
|
fileName storageFolder_;
|
||||||
|
wordList names_;
|
||||||
|
mutable PtrList<OFstream> storageFilePtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Set compressed fields including turbulence
|
||||||
|
void setFields();
|
||||||
|
|
||||||
|
//- Calculate and write compression metrics for a
|
||||||
|
//- compressedGeometricField
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void calculateAndWrite
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>& compField,
|
||||||
|
const word& name,
|
||||||
|
label& i
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Function to write the compressed size, the compression ratio, etc.
|
||||||
|
virtual void writeLog(const word&) const;
|
||||||
|
|
||||||
|
//- Function to write compression metrics to file
|
||||||
|
virtual void write(const label);
|
||||||
|
|
||||||
|
//- Set folder
|
||||||
|
void makeFolder();
|
||||||
|
|
||||||
|
//- Set File to store compression metrics
|
||||||
|
virtual void setStorageFilesPtr();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("compressedIncompressibleVars");
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
compressedIncompressibleVars,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
),
|
||||||
|
(vs, storageParams)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
compressedIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<compressedIncompressibleVars> New
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~compressedIncompressibleVars() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
inline label timeIndex() const
|
||||||
|
{
|
||||||
|
return timeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label& timeIndex()
|
||||||
|
{
|
||||||
|
return timeIndex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar timeValue() const
|
||||||
|
{
|
||||||
|
return timeValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar& timeValue()
|
||||||
|
{
|
||||||
|
return timeValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Function to calculate and write the compression metrics
|
||||||
|
virtual void calculateStorageMetrics();
|
||||||
|
|
||||||
|
virtual void compress();
|
||||||
|
|
||||||
|
virtual void decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
);
|
||||||
|
|
||||||
|
void decompress();
|
||||||
|
|
||||||
|
//- Function to return the compression metrics (initial size,
|
||||||
|
//- compressed size if compression is applied, etc)
|
||||||
|
virtual const scalarList& storageMetrics() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "compressedIncompressibleVarsTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2019 FOSS GP
|
||||||
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::compressedIncompressibleVars::calculateAndWrite
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>& compField,
|
||||||
|
const word& name,
|
||||||
|
label& i
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll(storageMetrics_, Ic)
|
||||||
|
{
|
||||||
|
storageMetrics_[Ic] = compField.storageMetrics()[Ic];
|
||||||
|
}
|
||||||
|
write(++i);
|
||||||
|
writeLog(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,215 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fullIncompressibleVars.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(fullIncompressibleVars, 0);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void fullIncompressibleVars::calculateStorageMetrics()
|
||||||
|
{
|
||||||
|
storageMetrics_.setSize(p_().storageMetrics().size(), Zero);
|
||||||
|
label i = 0;
|
||||||
|
if ( !storageParams_.timing() )
|
||||||
|
{
|
||||||
|
this->calculateAndWrite(p_(), pOld_, incoVars_.pInst().name(), i);
|
||||||
|
this->calculateAndWrite(phi_(), phiOld_, incoVars_.phiInst().name(), i);
|
||||||
|
this->calculateAndWrite(U_(), UOld_, incoVars_.UInst().name(), i);
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
this->calculateAndWrite
|
||||||
|
(RASModelVars_[0], TMVar1Old_, rasVars.TMVar1Inst().name(), i);
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
this->calculateAndWrite
|
||||||
|
(RASModelVars_[1], TMVar2Old_, rasVars.TMVar2Inst().name(), i);
|
||||||
|
}
|
||||||
|
storageMetrics_ = Zero;
|
||||||
|
}
|
||||||
|
addStorageMetricsContribution(p_(), pOld_);
|
||||||
|
addStorageMetricsContribution(phi_(), phiOld_);
|
||||||
|
addStorageMetricsContribution(U_(), UOld_);
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
addStorageMetricsContribution(RASModelVars_[0], TMVar1Old_);
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
addStorageMetricsContribution(RASModelVars_[1], TMVar2Old_);
|
||||||
|
}
|
||||||
|
if (!storageParams_.timing())
|
||||||
|
{
|
||||||
|
write(0);
|
||||||
|
writeLog("All");
|
||||||
|
}
|
||||||
|
names_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
fullIncompressibleVars::fullIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
label a
|
||||||
|
)
|
||||||
|
:
|
||||||
|
compressedIncompressibleVars(vs, storageParams),
|
||||||
|
a_(a),
|
||||||
|
pOld_(),
|
||||||
|
phiOld_(),
|
||||||
|
UOld_(),
|
||||||
|
TMVar1Old_(),
|
||||||
|
TMVar2Old_()
|
||||||
|
{
|
||||||
|
if (a_ < 1)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Total number 'a' of time-solutions to be stored must be >= 1."
|
||||||
|
<< nl
|
||||||
|
<< "Object constructed with (a = " << a_ << ")"
|
||||||
|
<< endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
storeOldTimes(incoVars_.pInst(), pOld_, 0);
|
||||||
|
storeOldTimes(incoVars_.phiInst(), phiOld_, 1);
|
||||||
|
storeOldTimes(incoVars_.UInst(), UOld_, 2);
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
storeOldTimes(rasVars.TMVar1Inst(), TMVar1Old_, 3);
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
storeOldTimes(rasVars.TMVar2Inst(), TMVar2Old_, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void fullIncompressibleVars::compress()
|
||||||
|
{
|
||||||
|
//scalar startTime = mesh_.time().elapsedCpuTime();
|
||||||
|
p_().compress();
|
||||||
|
forAll(pOld_, iPtr)
|
||||||
|
{
|
||||||
|
pOld_[iPtr].compress();
|
||||||
|
}
|
||||||
|
phi_().compress();
|
||||||
|
forAll(phiOld_, iPtr)
|
||||||
|
{
|
||||||
|
phiOld_[iPtr].compress();
|
||||||
|
}
|
||||||
|
U_().compress();
|
||||||
|
forAll(UOld_, iPtr)
|
||||||
|
{
|
||||||
|
UOld_[iPtr].compress();
|
||||||
|
}
|
||||||
|
incompressible::RASModelVariables& rasVars =
|
||||||
|
incoVars_.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
RASModelVars_[0].compress();
|
||||||
|
forAll(TMVar1Old_, iPtr)
|
||||||
|
{
|
||||||
|
TMVar1Old_[iPtr].compress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
RASModelVars_[1].compress();
|
||||||
|
forAll(TMVar2Old_, iPtr)
|
||||||
|
{
|
||||||
|
TMVar2Old_[iPtr].compress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//scalar endTime = mesh_.time().elapsedCpuTime();
|
||||||
|
calculateStorageMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fullIncompressibleVars::decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Phi must be retrieved first, since the BCs of p and U might depend on
|
||||||
|
// flux
|
||||||
|
decompressAll(vars.phiInst(), phi_(), phiOld_);
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: phi field retrieved" << endl;
|
||||||
|
decompressAll(vars.pInst(), p_(), pOld_);
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: p field retrieved" << endl;
|
||||||
|
decompressAll(vars.UInst(), U_(), UOld_);
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: U field retrieved" << endl;
|
||||||
|
incompressible::RASModelVariables& rasVars = vars.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
decompressAll(rasVars.TMVar1Inst(), RASModelVars_[0], TMVar1Old_);
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: 1st turbulence model field retrieved" << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
decompressAll(rasVars.TMVar2Inst(), RASModelVars_[1], TMVar2Old_);
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: 2nd turbulence model field retrieved" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fullIncompressibleVars::decompress()
|
||||||
|
{
|
||||||
|
this->decompress(incoVars_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fullIncompressibleVars
|
||||||
|
|
||||||
|
Description
|
||||||
|
Base class storing the current and the oldTime primal variables instances
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fullIncompressibleVars_H
|
||||||
|
#define fullIncompressibleVars_H
|
||||||
|
|
||||||
|
#include "compressedIncompressibleVars.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class fullIncompressibleVars Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class fullIncompressibleVars
|
||||||
|
:
|
||||||
|
public compressedIncompressibleVars
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Total number of time solutions to be stored for each time instance.
|
||||||
|
// E.g. for (a=1) only the solution at the current time-step will be
|
||||||
|
// stored, for (a=2) the solution at the current and the previous
|
||||||
|
// tim-step will be stored.
|
||||||
|
label a_;
|
||||||
|
|
||||||
|
//- PtrLists containing the oldTimes of all primal fields.
|
||||||
|
// The fields of the current time-step are stored upon construction of
|
||||||
|
// the compressedGeometricField class.
|
||||||
|
PtrList<compressedVolScalarField> pOld_;
|
||||||
|
PtrList<compressedSurfaceScalarField> phiOld_;
|
||||||
|
PtrList<compressedVolVectorField> UOld_;
|
||||||
|
PtrList<compressedVolScalarField> TMVar1Old_;
|
||||||
|
PtrList<compressedVolScalarField> TMVar2Old_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Store oldTimes (if any) of a
|
||||||
|
//- GeometricField<Type, PatchField, GeoMesh>
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void storeOldTimes
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compressedField,
|
||||||
|
const label pos
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Decompress field and its old times into a GeometricField
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void decompressAll
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>& current,
|
||||||
|
PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
oldFields
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate and write compression metrics for a
|
||||||
|
//- compressedGeometricField
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void addStorageMetricsContribution
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>&
|
||||||
|
compField,
|
||||||
|
const PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compOldField
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate and write compression metrics for a
|
||||||
|
//- compressedGeometricField
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void calculateAndWrite
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>&
|
||||||
|
compField,
|
||||||
|
const PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compOldField,
|
||||||
|
const word& name,
|
||||||
|
label& i
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Function to calculate and write the storage metrics of the
|
||||||
|
//- checkpoint
|
||||||
|
virtual void calculateStorageMetrics() override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
fullIncompressibleVars(const fullIncompressibleVars&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const fullIncompressibleVars&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("fullIncompressibleVars");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
fullIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams,
|
||||||
|
label a = 2
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~fullIncompressibleVars() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Function to compress the incompressibleVars
|
||||||
|
void compress() override;
|
||||||
|
|
||||||
|
//- Function to decompress the incompressible vars and
|
||||||
|
// update the incompressibleVars with the decompressed fields
|
||||||
|
void decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
) override;
|
||||||
|
|
||||||
|
void decompress();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "fullIncompressibleVarsTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||||
|
Copyright (C) 2013-2019 FOSS GP
|
||||||
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::fullIncompressibleVars::storeOldTimes
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compressedField,
|
||||||
|
const label pos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// This object is constructed to store the primal solution of time-step i.
|
||||||
|
// The implication is that this happens exactly before solving for i+1,
|
||||||
|
// meaning that the time has shifted and so have the instanteneous primal
|
||||||
|
// fields. So by the time the function is called, UInst() contains the
|
||||||
|
// solution of ith time-step, as an initialization to the solution that it
|
||||||
|
// will be computed at the (i+1)th time-step, UInst().oldTime() contains
|
||||||
|
// also the solution of the ith time-step and UInst().oldTime().oldTime(),
|
||||||
|
// if set, the solution of the (i-1)th time-step. The solution of the
|
||||||
|
// (i-2)th time-step is not necessary to be stored for the continuation of
|
||||||
|
// the run. So, UInst() and UInst().oldTime().oldTime(), if set, are
|
||||||
|
// stored.
|
||||||
|
label nOldTimes = min(field.nOldTimes(), a_);
|
||||||
|
if (nOldTimes > 1)
|
||||||
|
{
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>* oldField = &field.oldTime();
|
||||||
|
compressedField.setSize(nOldTimes-1);
|
||||||
|
for (label i=0; i<nOldTimes-1; i++)
|
||||||
|
{
|
||||||
|
oldField = &oldField->oldTime();
|
||||||
|
compressedField.set
|
||||||
|
(
|
||||||
|
i,
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>::New
|
||||||
|
(
|
||||||
|
*oldField,
|
||||||
|
storageParams_,
|
||||||
|
pos,
|
||||||
|
k_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::fullIncompressibleVars::decompressAll
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& GeomField,
|
||||||
|
compressedGeometricField<Type, PatchField, GeoMesh>& current,
|
||||||
|
PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>& oldFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Due to the implication described in storeOldTimes(...) function, the
|
||||||
|
// reference to the GeometricField of the solver that each element of the
|
||||||
|
// oldFields_ is not correct. For example, for a second order time-scheme,
|
||||||
|
// oldFields_ has only one elememt which holds a reference to the
|
||||||
|
// oldTime().oldTime() of the GeometricField known to the solver.
|
||||||
|
// Nevertheless, its stored values must be appended to the oldTime() of the
|
||||||
|
// GeometricField known to the solver.
|
||||||
|
current.decompress();
|
||||||
|
if ( GeomField.nOldTimes() > 1 )
|
||||||
|
{
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>* oldGeomField = &GeomField;
|
||||||
|
//- Scanning only what it has been stored:
|
||||||
|
// i) At the first time-step, nOldTimes() may be zero, but upon
|
||||||
|
// reconstruction the noldTimes of the variablesSet of the solver
|
||||||
|
// will be 1 or 2.
|
||||||
|
// ii) if (a=1) the oldTimes are not stored and as a result can not
|
||||||
|
// be retrieved.
|
||||||
|
forAll(oldFields, iPtr)
|
||||||
|
{
|
||||||
|
oldGeomField = &oldGeomField->oldTime();
|
||||||
|
oldFields[iPtr].decompress(*oldGeomField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::fullIncompressibleVars::addStorageMetricsContribution
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>& compField,
|
||||||
|
const PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compOldField
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll (storageMetrics_, Ic)
|
||||||
|
{
|
||||||
|
storageMetrics_[Ic] += compField.storageMetrics()[Ic];
|
||||||
|
forAll(compOldField, iPtr)
|
||||||
|
{
|
||||||
|
storageMetrics_[Ic] += compOldField[iPtr].storageMetrics()[Ic];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void Foam::fullIncompressibleVars::calculateAndWrite
|
||||||
|
(
|
||||||
|
const compressedGeometricField<Type, PatchField, GeoMesh>& compField,
|
||||||
|
const PtrList<compressedGeometricField<Type, PatchField, GeoMesh>>&
|
||||||
|
compOldField,
|
||||||
|
const word& name,
|
||||||
|
label& i
|
||||||
|
)
|
||||||
|
{
|
||||||
|
addStorageMetricsContribution(compField, compOldField);
|
||||||
|
write(++i);
|
||||||
|
writeLog(name);
|
||||||
|
storageMetrics_ = Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "shortIncompressibleVars.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "profiling.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(shortIncompressibleVars, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
compressedIncompressibleVars,
|
||||||
|
shortIncompressibleVars,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
shortIncompressibleVars::shortIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
)
|
||||||
|
:
|
||||||
|
compressedIncompressibleVars(vs, storageParams)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void shortIncompressibleVars::compress()
|
||||||
|
{
|
||||||
|
addProfiling(shortIncompressibleVars, "shortIncompressibleVars::compress");
|
||||||
|
//scalar startTime = mesh_.time().elapsedCpuTime();
|
||||||
|
p_().compress();
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: p field stored" << endl;
|
||||||
|
phi_().compress();
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: phi field stored" << endl;
|
||||||
|
U_().compress();
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: U field stored" << endl;
|
||||||
|
forAll (RASModelVars_, iPtr)
|
||||||
|
{
|
||||||
|
RASModelVars_[iPtr].compress();
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: " << iPtr + 1 << "th turbulence model field stored"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
//scalar endTime = mesh_.time().elapsedCpuTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shortIncompressibleVars::decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
)
|
||||||
|
{
|
||||||
|
addProfiling
|
||||||
|
(shortIncompressibleVars, "shortIncompressibleVars::decompress");
|
||||||
|
// Phi must be retrieved first, since the BCs of p and U might depend on
|
||||||
|
// flux
|
||||||
|
phi_().decompress(vars.phiInst());
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: phi field retrieved" << endl;
|
||||||
|
p_().decompress(vars.pInst());
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: p field retrieved" << endl;
|
||||||
|
U_().decompress(vars.UInst());
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: U field retrieved" << endl;
|
||||||
|
incompressible::RASModelVariables& rasVars = vars.RASModelVariables()();
|
||||||
|
if (rasVars.hasTMVar1())
|
||||||
|
{
|
||||||
|
RASModelVars_[0].decompress(rasVars.TMVar1Inst());
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: 1st turbulence model field retrieved" << endl;
|
||||||
|
}
|
||||||
|
if (rasVars.hasTMVar2())
|
||||||
|
{
|
||||||
|
RASModelVars_[1].decompress(rasVars.TMVar2Inst());
|
||||||
|
DebugInfo
|
||||||
|
<< "DEBUG: 2nd turbulence model field retrieved" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::shortIncompressibleVars
|
||||||
|
|
||||||
|
Description
|
||||||
|
Compresses the current time-instance known by the primal solvers.
|
||||||
|
Does not include oldTimes
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef shortIncompressibleVars_H
|
||||||
|
#define shortIncompressibleVars_H
|
||||||
|
|
||||||
|
#include "compressedIncompressibleVars.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class shortIncompressibleVars Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class shortIncompressibleVars
|
||||||
|
:
|
||||||
|
public compressedIncompressibleVars
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// Static Data Members
|
||||||
|
|
||||||
|
//- Run-time type information
|
||||||
|
TypeName("shortIncompressibleVars");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
shortIncompressibleVars
|
||||||
|
(
|
||||||
|
incompressibleVars& vs,
|
||||||
|
storageParameters& storageParams
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~shortIncompressibleVars() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Compress the incompressibleVars
|
||||||
|
void compress() override;
|
||||||
|
|
||||||
|
//- Function to return the compression metrics (initial size,
|
||||||
|
//- compressed size if compression is applied, etc)
|
||||||
|
void decompress
|
||||||
|
(
|
||||||
|
incompressibleVars& vars
|
||||||
|
) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -103,12 +103,11 @@ void incompressibleVars::setInitFields()
|
|||||||
// are allocated automatically in RASModelVariables
|
// are allocated automatically in RASModelVariables
|
||||||
if (solverControl_.storeInitValues())
|
if (solverControl_.storeInitValues())
|
||||||
{
|
{
|
||||||
pInitPtr_.reset(new volScalarField(pInst().name() + "Init", pInst()));
|
DebugInfo
|
||||||
UInitPtr_.reset(new volVectorField(UInst().name() + "Init", UInst()));
|
<< "Allocating Initial Primal Fields" << endl;
|
||||||
phiInitPtr_.reset
|
setInitField(pInitPtr_, pInst());
|
||||||
(
|
setInitField(UInitPtr_, UInst());
|
||||||
new surfaceScalarField(phiInst().name() + "Init", phiInst())
|
setInitField(phiInitPtr_, phiInst());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,52 +120,9 @@ void incompressibleVars::setMeanFields()
|
|||||||
if (solverControl_.average())
|
if (solverControl_.average())
|
||||||
{
|
{
|
||||||
Info<< "Allocating Mean Primal Fields" << endl;
|
Info<< "Allocating Mean Primal Fields" << endl;
|
||||||
pMeanPtr_.reset
|
setMeanField(pMeanPtr_, pInst(), mesh_);
|
||||||
(
|
setMeanField(UMeanPtr_, UInst(), mesh_);
|
||||||
new volScalarField
|
setMeanField(phiMeanPtr_, phiInst(), mesh_);
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
pInst().name()+"Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
pInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
UMeanPtr_.reset
|
|
||||||
(
|
|
||||||
new volVectorField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
UInst().name()+"Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
UInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
phiMeanPtr_.reset
|
|
||||||
(
|
|
||||||
new surfaceScalarField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
phiInst().name()+"Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
phiInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Correct boundary conditions if necessary
|
// Correct boundary conditions if necessary
|
||||||
if (correctBoundaryConditions_)
|
if (correctBoundaryConditions_)
|
||||||
{
|
{
|
||||||
@ -230,7 +186,8 @@ void incompressibleVars::correctTurbulentBoundaryConditions()
|
|||||||
incompressibleVars::incompressibleVars
|
incompressibleVars::incompressibleVars
|
||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
solverControl& SolverControl
|
solverControl& SolverControl,
|
||||||
|
scalar readTime
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
variablesSet(mesh, SolverControl.solverDict()),
|
variablesSet(mesh, SolverControl.solverDict()),
|
||||||
@ -242,9 +199,9 @@ incompressibleVars::incompressibleVars
|
|||||||
turbulence_(nullptr),
|
turbulence_(nullptr),
|
||||||
RASModelVariables_(nullptr),
|
RASModelVariables_(nullptr),
|
||||||
|
|
||||||
pInitPtr_(nullptr),
|
pInitPtr_(),
|
||||||
UInitPtr_(nullptr),
|
UInitPtr_(),
|
||||||
phiInitPtr_(nullptr),
|
phiInitPtr_(),
|
||||||
|
|
||||||
pMeanPtr_(nullptr),
|
pMeanPtr_(nullptr),
|
||||||
UMeanPtr_(nullptr),
|
UMeanPtr_(nullptr),
|
||||||
@ -254,11 +211,43 @@ incompressibleVars::incompressibleVars
|
|||||||
(
|
(
|
||||||
SolverControl.solverDict().subOrEmptyDict("fieldReconstruction").
|
SolverControl.solverDict().subOrEmptyDict("fieldReconstruction").
|
||||||
getOrDefault<bool>("reconstruct", false)
|
getOrDefault<bool>("reconstruct", false)
|
||||||
|
),
|
||||||
|
solDirs_((mesh.solutionD() + Vector<label>::one)/2),
|
||||||
|
writeFields_
|
||||||
|
(
|
||||||
|
SolverControl.solverDict().getOrDefault<bool>("writeFields", true)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Necessary for continuation of unsteady solvers. For steady solvers
|
||||||
|
// should have no effect
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
const dimensionedScalar startTime = mesh_.time();
|
||||||
|
const label startTimeIndex = mesh_.time().timeIndex();
|
||||||
|
if (readTime != -1)
|
||||||
|
{
|
||||||
|
// Set time to readTime. Time-index remains unchanged, since
|
||||||
|
// it does not influence fields reading
|
||||||
|
DebugInfo
|
||||||
|
<< "Initializing primal fields begin: time changes to "
|
||||||
|
<< ::Foam::name(readTime) << endl;
|
||||||
|
time.setTime(readTime, startTimeIndex);
|
||||||
|
}
|
||||||
setFields();
|
setFields();
|
||||||
setInitFields();
|
setInitFields();
|
||||||
setMeanFields();
|
setMeanFields();
|
||||||
|
storeAllocatedFieldNames();
|
||||||
|
if (readTime != -1)
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Initializing primal fields end: time changes to "
|
||||||
|
<< ::Foam::name(startTime.value()) << endl;
|
||||||
|
// Restore time
|
||||||
|
time.setTime(startTime, startTimeIndex);
|
||||||
|
}
|
||||||
|
if (!writeFields_)
|
||||||
|
{
|
||||||
|
setWriteOption(IOobject::NO_WRITE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -276,18 +265,32 @@ incompressibleVars::incompressibleVars
|
|||||||
turbulence_(nullptr),
|
turbulence_(nullptr),
|
||||||
RASModelVariables_(vs.RASModelVariables_.clone()),
|
RASModelVariables_(vs.RASModelVariables_.clone()),
|
||||||
|
|
||||||
pInitPtr_(allocateRenamedField(vs.pInitPtr_)),
|
pInitPtr_(vs.pInitPtr_.size()),
|
||||||
UInitPtr_(allocateRenamedField(vs.UInitPtr_)),
|
UInitPtr_(vs.UInitPtr_.size()),
|
||||||
phiInitPtr_(allocateRenamedField(vs.phiInitPtr_)),
|
phiInitPtr_(vs.phiInitPtr_.size()),
|
||||||
|
|
||||||
pMeanPtr_(allocateRenamedField(vs.pMeanPtr_)),
|
pMeanPtr_(allocateRenamedField(vs.pMeanPtr_)),
|
||||||
UMeanPtr_(allocateRenamedField(UMeanPtr_)),
|
UMeanPtr_(allocateRenamedField(vs.UMeanPtr_)),
|
||||||
phiMeanPtr_(allocateRenamedField(vs.phiMeanPtr_)),
|
phiMeanPtr_(allocateRenamedField(vs.phiMeanPtr_)),
|
||||||
|
|
||||||
correctBoundaryConditions_(vs.correctBoundaryConditions_)
|
correctBoundaryConditions_(vs.correctBoundaryConditions_),
|
||||||
|
allocatedFieldNames_(vs.allocatedFieldNames_),
|
||||||
|
solDirs_(vs.solDirs_)
|
||||||
{
|
{
|
||||||
DebugInfo
|
DebugInfo
|
||||||
<< "Calling incompressibleVars copy constructor" << endl;
|
<< "Calling incompressibleVars copy constructor" << endl;
|
||||||
|
forAll(pInitPtr_, i)
|
||||||
|
{
|
||||||
|
pInitPtr_.set(i, allocateRenamedField(vs.pInitPtr_[i]));
|
||||||
|
}
|
||||||
|
forAll(UInitPtr_, i)
|
||||||
|
{
|
||||||
|
UInitPtr_.set(i, allocateRenamedField(vs.UInitPtr_[i]));
|
||||||
|
}
|
||||||
|
forAll(phiInitPtr_, i)
|
||||||
|
{
|
||||||
|
phiInitPtr_.set(i, allocateRenamedField(vs.phiInitPtr_[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -302,6 +305,23 @@ autoPtr<variablesSet> incompressibleVars::clone() const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void incompressibleVars::storeAllocatedFieldNames()
|
||||||
|
{
|
||||||
|
allocatedFieldNames_.setSize(3);
|
||||||
|
allocatedFieldNames_[0] = pInst().name();
|
||||||
|
allocatedFieldNames_[1] = phiInst().name();
|
||||||
|
allocatedFieldNames_[2] = UInst().name();
|
||||||
|
if (RASModelVariables_().hasTMVar1())
|
||||||
|
{
|
||||||
|
allocatedFieldNames_.append(RASModelVariables_().TMVar1Inst().name());
|
||||||
|
}
|
||||||
|
if (RASModelVariables_().hasTMVar2())
|
||||||
|
{
|
||||||
|
allocatedFieldNames_.append(RASModelVariables_().TMVar2Inst().name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const volScalarField& incompressibleVars::p() const
|
const volScalarField& incompressibleVars::p() const
|
||||||
{
|
{
|
||||||
if (solverControl_.useAveragedFields())
|
if (solverControl_.useAveragedFields())
|
||||||
@ -366,6 +386,7 @@ const surfaceScalarField& incompressibleVars::phi() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
surfaceScalarField& incompressibleVars::phi()
|
surfaceScalarField& incompressibleVars::phi()
|
||||||
{
|
{
|
||||||
if (solverControl_.useAveragedFields())
|
if (solverControl_.useAveragedFields())
|
||||||
@ -384,9 +405,9 @@ void incompressibleVars::restoreInitValues()
|
|||||||
if (solverControl_.storeInitValues())
|
if (solverControl_.storeInitValues())
|
||||||
{
|
{
|
||||||
Info<< "Restoring field values to initial ones" << endl;
|
Info<< "Restoring field values to initial ones" << endl;
|
||||||
pInst() == pInitPtr_();
|
variablesSet::restoreFieldInitialization(pInitPtr_, pInst());
|
||||||
UInst() == UInitPtr_();
|
variablesSet::restoreFieldInitialization(phiInitPtr_, phiInst());
|
||||||
phiInst() == phiInitPtr_();
|
variablesSet::restoreFieldInitialization(UInitPtr_, UInst());
|
||||||
RASModelVariables_().restoreInitValues();
|
RASModelVariables_().restoreInitValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,10 +449,28 @@ void incompressibleVars::computeMeanFields()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleVars::computeMeanUnsteadyFields()
|
||||||
|
{
|
||||||
|
if (solverControl_.doAverageTime())
|
||||||
|
{
|
||||||
|
Info<< "Averaging fields" << endl;
|
||||||
|
const scalar dt = mesh_.time().deltaTValue();
|
||||||
|
const scalar elapsedTime
|
||||||
|
= mesh_.time().value() - solverControl_.averageStartTime();
|
||||||
|
scalar oneOverItP1 = dt/(elapsedTime + dt);
|
||||||
|
scalar mult = elapsedTime/(elapsedTime + dt);
|
||||||
|
pMeanPtr_() == pMeanPtr_()*mult + pInst()*oneOverItP1;
|
||||||
|
UMeanPtr_() == UMeanPtr_()*mult + UInst()*oneOverItP1;
|
||||||
|
phiMeanPtr_() == phiMeanPtr_()*mult + phiInst()*oneOverItP1;
|
||||||
|
RASModelVariables_().computeMeanUnsteadyFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void incompressibleVars::correctBoundaryConditions()
|
void incompressibleVars::correctBoundaryConditions()
|
||||||
{
|
{
|
||||||
correctNonTurbulentBoundaryConditions();
|
correctNonTurbulentBoundaryConditions();
|
||||||
RASModelVariables_().correctBoundaryConditions(turbulence_());
|
correctTurbulentBoundaryConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -461,6 +500,16 @@ void incompressibleVars::transfer(variablesSet& vars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleVars::validateTurbulence()
|
||||||
|
{
|
||||||
|
// Update nut
|
||||||
|
if (RASModelVariables_().hasNut())
|
||||||
|
{
|
||||||
|
turbulence()->validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool incompressibleVars::write() const
|
bool incompressibleVars::write() const
|
||||||
{
|
{
|
||||||
// Write dummy fields, for continuation only
|
// Write dummy fields, for continuation only
|
||||||
@ -501,6 +550,56 @@ bool incompressibleVars::write() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fvMesh& incompressibleVars::mesh() const
|
||||||
|
{
|
||||||
|
return mesh_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const solverControl& incompressibleVars::solverControlReference() const
|
||||||
|
{
|
||||||
|
return solverControl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wordList& incompressibleVars::allocatedFieldNames() const
|
||||||
|
{
|
||||||
|
return allocatedFieldNames_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Vector<label>& incompressibleVars::solDirs() const
|
||||||
|
{
|
||||||
|
return solDirs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleVars::adjustAverageStartTime(const scalar& offset)
|
||||||
|
{
|
||||||
|
solverControl_.averageStartTime() += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleVars::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
if (!writeFields_)
|
||||||
|
{
|
||||||
|
w = IOobject::NO_WRITE;
|
||||||
|
}
|
||||||
|
pInst().writeOpt() = w;
|
||||||
|
phiInst().writeOpt() = w;
|
||||||
|
UInst().writeOpt() = w;
|
||||||
|
if (solverControl_.doAverageTime())
|
||||||
|
{
|
||||||
|
pMeanPtr_->writeOpt() = w;
|
||||||
|
phiMeanPtr_->writeOpt() = w;
|
||||||
|
UMeanPtr_->writeOpt() = w;
|
||||||
|
}
|
||||||
|
incompressible::RASModelVariables& rasVars = RASModelVariables_();
|
||||||
|
rasVars.setWriteOption(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -72,10 +72,12 @@ protected:
|
|||||||
autoPtr<incompressible::RASModelVariables> RASModelVariables_;
|
autoPtr<incompressible::RASModelVariables> RASModelVariables_;
|
||||||
//autoPtr<volScalarField> TPtr_;
|
//autoPtr<volScalarField> TPtr_;
|
||||||
|
|
||||||
//- Keep a copy of the initial field values if necessary
|
//- Keep a copy of the initial values if necessary.
|
||||||
autoPtr<volScalarField> pInitPtr_;
|
// If oldTimes are present, keep them in separate GeometricFields to
|
||||||
autoPtr<volVectorField> UInitPtr_;
|
// avoid been overwritten upon calling GeometricField::storeOldTimes
|
||||||
autoPtr<surfaceScalarField> phiInitPtr_;
|
PtrList<volScalarField> pInitPtr_;
|
||||||
|
PtrList<volVectorField> UInitPtr_;
|
||||||
|
PtrList<surfaceScalarField> phiInitPtr_;
|
||||||
|
|
||||||
//- Manage mean fields. Turbulent mean fields are managed
|
//- Manage mean fields. Turbulent mean fields are managed
|
||||||
//- in RASModelVariables
|
//- in RASModelVariables
|
||||||
@ -88,6 +90,17 @@ protected:
|
|||||||
// (e.g. averaging, redistribution)
|
// (e.g. averaging, redistribution)
|
||||||
bool correctBoundaryConditions_;
|
bool correctBoundaryConditions_;
|
||||||
|
|
||||||
|
//- Names of the primal fields that are allocated.
|
||||||
|
// The size of the list is properly adjusted
|
||||||
|
wordList allocatedFieldNames_;
|
||||||
|
|
||||||
|
//- Return the vector of solved-for directions in mesh.
|
||||||
|
// 1 indicates valid direction and 0 an invalid direction.
|
||||||
|
const Vector<label> solDirs_;
|
||||||
|
|
||||||
|
//- Should the solver fields be written
|
||||||
|
bool writeFields_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
@ -112,6 +125,10 @@ protected:
|
|||||||
//- No copy assignment
|
//- No copy assignment
|
||||||
void operator=(const incompressibleVars&);
|
void operator=(const incompressibleVars&);
|
||||||
|
|
||||||
|
//- Function to fill the wordList containing the names of the primal
|
||||||
|
//- fields that are allocated.
|
||||||
|
void storeAllocatedFieldNames();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -127,7 +144,8 @@ public:
|
|||||||
incompressibleVars
|
incompressibleVars
|
||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
solverControl& SolverControl
|
solverControl& SolverControl,
|
||||||
|
scalar readTime = -1
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Copy constructor
|
//- Copy constructor
|
||||||
@ -230,6 +248,9 @@ public:
|
|||||||
//- Compute mean fields on the fly
|
//- Compute mean fields on the fly
|
||||||
void computeMeanFields();
|
void computeMeanFields();
|
||||||
|
|
||||||
|
//- Compute mean fields on the fly: unsteady runs
|
||||||
|
void computeMeanUnsteadyFields();
|
||||||
|
|
||||||
//- correct boundaryconditions for all volFields
|
//- correct boundaryconditions for all volFields
|
||||||
void correctBoundaryConditions();
|
void correctBoundaryConditions();
|
||||||
|
|
||||||
@ -250,9 +271,33 @@ public:
|
|||||||
//- Transfer the fields of another variablesSet to this
|
//- Transfer the fields of another variablesSet to this
|
||||||
virtual void transfer(variablesSet& vars);
|
virtual void transfer(variablesSet& vars);
|
||||||
|
|
||||||
|
//- Update nut
|
||||||
|
virtual void validateTurbulence();
|
||||||
|
|
||||||
//- Write dummy turbulent fields to allow for continuation in
|
//- Write dummy turbulent fields to allow for continuation in
|
||||||
//- multi-point, turbulent runs
|
//- multi-point, turbulent runs
|
||||||
bool write() const;
|
bool write() const;
|
||||||
|
|
||||||
|
//- Return const reference to the fvMesh
|
||||||
|
fvMesh& mesh() const;
|
||||||
|
|
||||||
|
//- Return const reference to the solverDict
|
||||||
|
const solverControl& solverControlReference() const;
|
||||||
|
|
||||||
|
//- const reference to the wordList containing the names of
|
||||||
|
//- the primal fields that are allocated.
|
||||||
|
const wordList& allocatedFieldNames() const override;
|
||||||
|
|
||||||
|
//- const reference to the solution directions
|
||||||
|
//- of the solver.
|
||||||
|
const Vector<label>& solDirs() const;
|
||||||
|
|
||||||
|
//- Set averaging start time in solverControl.
|
||||||
|
// Required by unsteady runs
|
||||||
|
void adjustAverageStartTime(const scalar& offset) override;
|
||||||
|
|
||||||
|
//- Set writeOption of all primal fields
|
||||||
|
void setWriteOption(IOobject::writeOption w);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -61,12 +61,34 @@ incompressibleAdjointVars::incompressibleAdjointVars
|
|||||||
*this,
|
*this,
|
||||||
objManager
|
objManager
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
writeFields_
|
||||||
|
(
|
||||||
|
SolverControl.solverDict().getOrDefault<bool>("writeFields", true)
|
||||||
)
|
)
|
||||||
{}
|
{
|
||||||
|
if (!writeFields_)
|
||||||
|
{
|
||||||
|
setWriteOption(IOobject::NO_WRITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void incompressibleAdjointVars::restoreInitValues()
|
||||||
|
{
|
||||||
|
if (solverControl_.storeInitValues())
|
||||||
|
{
|
||||||
|
Info<< "Restoring field values to initial ones" << endl;
|
||||||
|
variablesSet::resetAdjointField(paInst());
|
||||||
|
variablesSet::resetAdjointField(UaInst());
|
||||||
|
variablesSet::resetAdjointField(phiaInst());
|
||||||
|
adjointTurbulence_().restoreInitValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void incompressibleAdjointVars::resetMeanFields()
|
void incompressibleAdjointVars::resetMeanFields()
|
||||||
{
|
{
|
||||||
if (solverControl_.average())
|
if (solverControl_.average())
|
||||||
@ -103,6 +125,26 @@ void incompressibleAdjointVars::computeMeanFields()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleAdjointVars::computeMeanUnsteadyFields
|
||||||
|
(
|
||||||
|
const scalar endTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (solverControl_.doAverageTime())
|
||||||
|
{
|
||||||
|
Info<< "Averaging fields" << endl;
|
||||||
|
const scalar dt = mesh_.time().deltaTValue();
|
||||||
|
const scalar elapsedTime = endTime - mesh_.time().value();
|
||||||
|
scalar oneOverItP1 = dt/(elapsedTime + dt);
|
||||||
|
scalar mult = elapsedTime/(elapsedTime + dt);
|
||||||
|
paMeanPtr_() == paMeanPtr_()*mult + paInst()*oneOverItP1;
|
||||||
|
UaMeanPtr_() == UaMeanPtr_()*mult + UaInst()*oneOverItP1;
|
||||||
|
phiaMeanPtr_() == phiaMeanPtr_()*mult + phiaInst()*oneOverItP1;
|
||||||
|
adjointTurbulence_().computeMeanUnsteadyFields(endTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void incompressibleAdjointVars::nullify()
|
void incompressibleAdjointVars::nullify()
|
||||||
{
|
{
|
||||||
incompressibleAdjointMeanFlowVars::nullify();
|
incompressibleAdjointMeanFlowVars::nullify();
|
||||||
@ -137,6 +179,28 @@ void incompressibleAdjointVars::updatePrimalBasedQuantities()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleAdjointVars::write()
|
||||||
|
{
|
||||||
|
if (writeFields_)
|
||||||
|
{
|
||||||
|
incompressibleAdjointMeanFlowVars::write();
|
||||||
|
adjointTurbulence_->writeFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleAdjointVars::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
if (!writeFields_)
|
||||||
|
{
|
||||||
|
w = IOobject::NO_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
incompressibleAdjointMeanFlowVars::setWriteOption(w);
|
||||||
|
adjointTurbulence_->setWriteOption(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -64,6 +64,9 @@ protected:
|
|||||||
//- Adjoint to the turbulence model
|
//- Adjoint to the turbulence model
|
||||||
autoPtr<incompressibleAdjoint::adjointRASModel> adjointTurbulence_;
|
autoPtr<incompressibleAdjoint::adjointRASModel> adjointTurbulence_;
|
||||||
|
|
||||||
|
//- Should the solver fields be written
|
||||||
|
bool writeFields_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
@ -111,18 +114,30 @@ public:
|
|||||||
inline autoPtr<incompressibleAdjoint::adjointRASModel>&
|
inline autoPtr<incompressibleAdjoint::adjointRASModel>&
|
||||||
adjointTurbulence();
|
adjointTurbulence();
|
||||||
|
|
||||||
|
//- Restore field values to the initial ones
|
||||||
|
void restoreInitValues();
|
||||||
|
|
||||||
//- Reset mean fields to zero
|
//- Reset mean fields to zero
|
||||||
void resetMeanFields();
|
void resetMeanFields();
|
||||||
|
|
||||||
//- Compute mean fields on the fly
|
//- Compute mean fields on the fly: steady runs
|
||||||
void computeMeanFields();
|
void computeMeanFields();
|
||||||
|
|
||||||
|
//- Compute mean fields on the fly: unsteady runs
|
||||||
|
void computeMeanUnsteadyFields(const scalar endTime);
|
||||||
|
|
||||||
//- Nullify all adjoint fields
|
//- Nullify all adjoint fields
|
||||||
virtual void nullify();
|
virtual void nullify();
|
||||||
|
|
||||||
//- Update primal based quantities of the adjoint boundary
|
//- Update primal based quantities of the adjoint boundary
|
||||||
// conditions
|
// conditions
|
||||||
virtual void updatePrimalBasedQuantities();
|
virtual void updatePrimalBasedQuantities();
|
||||||
|
|
||||||
|
//- Write all adjoint fields
|
||||||
|
virtual void write();
|
||||||
|
|
||||||
|
//- Set writeOption of all adjoint fields
|
||||||
|
void setWriteOption(IOobject::writeOption w);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2021 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2021 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -57,6 +57,7 @@ void incompressibleAdjointMeanFlowVars::setFields()
|
|||||||
mesh_.setFluxRequired(paPtr_->name());
|
mesh_.setFluxRequired(paPtr_->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void incompressibleAdjointMeanFlowVars::setMeanFields()
|
void incompressibleAdjointMeanFlowVars::setMeanFields()
|
||||||
{
|
{
|
||||||
// Allocate mean fields
|
// Allocate mean fields
|
||||||
@ -65,51 +66,9 @@ void incompressibleAdjointMeanFlowVars::setMeanFields()
|
|||||||
if (solverControl_.average())
|
if (solverControl_.average())
|
||||||
{
|
{
|
||||||
Info<< "Allocating Mean Adjoint Fields" << endl;
|
Info<< "Allocating Mean Adjoint Fields" << endl;
|
||||||
paMeanPtr_.reset
|
variablesSet::setMeanField(paMeanPtr_, paInst(), mesh_);
|
||||||
(
|
variablesSet::setMeanField(UaMeanPtr_, UaInst(), mesh_);
|
||||||
new volScalarField
|
variablesSet::setMeanField(phiaMeanPtr_, phiaInst(), mesh_);
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
paInst().name() + "Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
paInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
UaMeanPtr_.reset
|
|
||||||
(
|
|
||||||
new volVectorField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
UaInst().name() + "Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
UaInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
phiaMeanPtr_.reset
|
|
||||||
(
|
|
||||||
new surfaceScalarField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
phiaInst().name() + "Mean",
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
phiaInst()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,12 +195,43 @@ const solverControl& incompressibleAdjointMeanFlowVars::getSolverControl() const
|
|||||||
|
|
||||||
void incompressibleAdjointMeanFlowVars::nullify()
|
void incompressibleAdjointMeanFlowVars::nullify()
|
||||||
{
|
{
|
||||||
|
// Nullify instantaneous fields
|
||||||
variablesSet::nullifyField(paPtr_());
|
variablesSet::nullifyField(paPtr_());
|
||||||
variablesSet::nullifyField(UaPtr_());
|
variablesSet::nullifyField(UaPtr_());
|
||||||
variablesSet::nullifyField(phiaPtr_());
|
variablesSet::nullifyField(phiaPtr_());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleAdjointMeanFlowVars::write()
|
||||||
|
{
|
||||||
|
// Write instantaneous fields
|
||||||
|
variablesSet::writeField(paPtr_());
|
||||||
|
variablesSet::writeField(UaPtr_());
|
||||||
|
variablesSet::writeField(phiaPtr_());
|
||||||
|
// Write mean fields
|
||||||
|
if (solverControl_.average())
|
||||||
|
{
|
||||||
|
variablesSet::writeField(paMeanPtr_());
|
||||||
|
variablesSet::writeField(UaMeanPtr_());
|
||||||
|
variablesSet::writeField(phiaMeanPtr_());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void incompressibleAdjointMeanFlowVars::setWriteOption(IOobject::writeOption w)
|
||||||
|
{
|
||||||
|
paPtr_().writeOpt() = w;
|
||||||
|
UaPtr_().writeOpt() = w;
|
||||||
|
phiaPtr_().writeOpt() = w;
|
||||||
|
if (solverControl_.doAverageTime())
|
||||||
|
{
|
||||||
|
paMeanPtr_->writeOpt() = w;
|
||||||
|
UaMeanPtr_->writeOpt() = w;
|
||||||
|
phiaMeanPtr_->writeOpt() = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -183,6 +183,12 @@ public:
|
|||||||
|
|
||||||
//- Nullify all adjoint fields
|
//- Nullify all adjoint fields
|
||||||
virtual void nullify();
|
virtual void nullify();
|
||||||
|
|
||||||
|
//- Write all adjoint fields
|
||||||
|
virtual void write();
|
||||||
|
|
||||||
|
//- Set writeOption of all adjoint fields
|
||||||
|
void setWriteOption(IOobject::writeOption w);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -199,6 +199,32 @@ void variablesSet::transfer(variablesSet& vars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void variablesSet::validateTurbulence()
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const scalarList& variablesSet::storageMetrics() const
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
return demoScalarList_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wordList& variablesSet::allocatedFieldNames() const
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
return demoWordList_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void variablesSet::adjustAverageStartTime(const scalar& offset)
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -84,6 +84,10 @@ private:
|
|||||||
const bool useSolverNameForFields
|
const bool useSolverNameForFields
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Demo scalarList for virtual function storageMetrics()
|
||||||
|
scalarList demoScalarList_;
|
||||||
|
wordList demoWordList_;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -101,12 +105,6 @@ protected:
|
|||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
|
||||||
autoPtr<GeometricField<Type, PatchField, GeoMesh>> allocateRenamedField
|
|
||||||
(
|
|
||||||
const autoPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Swap autoPtrs and rename managed fields
|
//- Swap autoPtrs and rename managed fields
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void swapAndRename
|
void swapAndRename
|
||||||
@ -155,6 +153,27 @@ public:
|
|||||||
|
|
||||||
// Set functions. Static in order to be used by other classes as well
|
// Set functions. Static in order to be used by other classes as well
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
allocateRenamedField
|
||||||
|
(
|
||||||
|
const refPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
allocateRenamedField
|
||||||
|
(
|
||||||
|
const autoPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
allocateRenamedField
|
||||||
|
(
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& bf
|
||||||
|
);
|
||||||
|
|
||||||
//- Read vol fields
|
//- Read vol fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
static void setField
|
static void setField
|
||||||
@ -221,8 +240,70 @@ public:
|
|||||||
GeometricField<Type, PatchField, GeoMesh>& fieldPtr
|
GeometricField<Type, PatchField, GeoMesh>& fieldPtr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Write field and old times, if present
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void writeField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& fieldPtr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Set initial field
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void setInitField
|
||||||
|
(
|
||||||
|
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fieldInit,
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reset field to its initial state
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void restoreFieldInitialization
|
||||||
|
(
|
||||||
|
PtrList<GeometricField<Type, PatchField, GeoMesh>>& exact,
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reset field and old values to zero
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void resetAdjointField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Set mean field
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void setMeanField
|
||||||
|
(
|
||||||
|
refPtr<GeometricField<Type, PatchField, GeoMesh>>& meanFieldPtr,
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
const fvMesh& mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Set mean field
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
static void setMeanField
|
||||||
|
(
|
||||||
|
autoPtr<GeometricField<Type, PatchField, GeoMesh>>& meanFieldPtr,
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
const fvMesh& mesh
|
||||||
|
);
|
||||||
|
|
||||||
//- Transfer the fields of another variablesSet to this
|
//- Transfer the fields of another variablesSet to this
|
||||||
virtual void transfer(variablesSet& vars);
|
virtual void transfer(variablesSet& vars);
|
||||||
|
|
||||||
|
//- Update nut
|
||||||
|
virtual void validateTurbulence();
|
||||||
|
|
||||||
|
//- Function to return the compression metrics (initial size,
|
||||||
|
//- compressed size, etc)
|
||||||
|
virtual const scalarList& storageMetrics() const;
|
||||||
|
|
||||||
|
//- Function to return the names of all the primal fields that are
|
||||||
|
//- allocated
|
||||||
|
virtual const wordList& allocatedFieldNames() const;
|
||||||
|
|
||||||
|
//- Does nothing in base
|
||||||
|
virtual void adjustAverageStartTime(const scalar& offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
Copyright (C) 2007-2022 PCOpt/NTUA
|
||||||
Copyright (C) 2013-2019 FOSS GP
|
Copyright (C) 2013-2022 FOSS GP
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -76,7 +76,7 @@ GeometricField<Type, PatchField, GeoMesh>* variablesSet::allocateNamedField
|
|||||||
DebugInfo
|
DebugInfo
|
||||||
<< bField << endl;
|
<< bField << endl;
|
||||||
|
|
||||||
return (new fieldType(io, mesh, dict));
|
return (new fieldType(io, mesh, dict, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -161,31 +161,6 @@ bool variablesSet::readFieldOK
|
|||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
|
||||||
autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
|
||||||
variablesSet::allocateRenamedField
|
|
||||||
(
|
|
||||||
const autoPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, PatchField, GeoMesh> fieldType;
|
|
||||||
autoPtr<fieldType> returnField(nullptr);
|
|
||||||
if (bf.valid())
|
|
||||||
{
|
|
||||||
const word timeName = bf().mesh().time().timeName();
|
|
||||||
returnField.reset
|
|
||||||
(
|
|
||||||
new fieldType
|
|
||||||
(
|
|
||||||
bf().name() + timeName,
|
|
||||||
bf()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return returnField;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
void variablesSet::swapAndRename
|
void variablesSet::swapAndRename
|
||||||
(
|
(
|
||||||
@ -217,6 +192,53 @@ void variablesSet::swapAndRename
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
variablesSet::allocateRenamedField
|
||||||
|
(
|
||||||
|
const refPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, PatchField, GeoMesh> fieldType;
|
||||||
|
autoPtr<fieldType> returnField(nullptr);
|
||||||
|
if (bf.valid())
|
||||||
|
{
|
||||||
|
returnField = allocateRenamedField(bf());
|
||||||
|
}
|
||||||
|
return returnField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
variablesSet::allocateRenamedField
|
||||||
|
(
|
||||||
|
const autoPtr<GeometricField<Type, PatchField, GeoMesh>>& bf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, PatchField, GeoMesh> fieldType;
|
||||||
|
autoPtr<fieldType> returnField(nullptr);
|
||||||
|
if (bf.valid())
|
||||||
|
{
|
||||||
|
returnField = allocateRenamedField(bf());
|
||||||
|
}
|
||||||
|
return returnField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
autoPtr<GeometricField<Type, PatchField, GeoMesh>>
|
||||||
|
variablesSet::allocateRenamedField
|
||||||
|
(
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& bf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, PatchField, GeoMesh> fieldType;
|
||||||
|
const word timeName = bf.mesh().time().timeName();
|
||||||
|
return autoPtr<fieldType>::New(bf.name() + timeName, bf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void variablesSet::setField
|
void variablesSet::setField
|
||||||
(
|
(
|
||||||
@ -358,6 +380,155 @@ void variablesSet::nullifyField
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::writeField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
field.write();
|
||||||
|
for (label i = 0; i<field.nOldTimes() - 1; ++i)
|
||||||
|
{
|
||||||
|
writeField(field.oldTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::setInitField
|
||||||
|
(
|
||||||
|
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fieldInit,
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Store fields at the current and (nOldTimes - 1) time-steps
|
||||||
|
// since the last oldTime value is not for restarts
|
||||||
|
// Avoiding the storage to a new GeometricField with its oldTimes set
|
||||||
|
// due to the overwriting of the latter when time advances
|
||||||
|
typedef GeometricField<Type, PatchField, GeoMesh> fieldType;
|
||||||
|
fieldInit.setSize(max(field.nOldTimes(), 1));
|
||||||
|
fieldInit.set(0, new fieldType(field.name() + "Init" + name(0), field));
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>* oldField = &field;
|
||||||
|
for (label i = 1; i < fieldInit.size(); ++i)
|
||||||
|
{
|
||||||
|
oldField = &oldField->oldTime();
|
||||||
|
fieldInit.set
|
||||||
|
(
|
||||||
|
i,
|
||||||
|
new fieldType(field.name() + "Init" + name(i), *oldField)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::restoreFieldInitialization
|
||||||
|
(
|
||||||
|
PtrList<GeometricField<Type, PatchField, GeoMesh>>& exact,
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!exact.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "DataList to be used for restoring primal "
|
||||||
|
<< "fields is not set" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
// Restore GeometricField together with its oldTimes
|
||||||
|
field == exact[0];
|
||||||
|
label nI(1);
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>* oldField = &field;
|
||||||
|
// Restore old times stored in exact
|
||||||
|
while (nI < exact.size())
|
||||||
|
{
|
||||||
|
oldField = &oldField->oldTime();
|
||||||
|
*oldField == exact[nI];
|
||||||
|
++nI;
|
||||||
|
}
|
||||||
|
// Covers the rare case of not having read the _0 fields (to be stored in
|
||||||
|
// exact) but there is the need of re-setting the oldTimes
|
||||||
|
while (nI < field.nOldTimes())
|
||||||
|
{
|
||||||
|
oldField = &oldField->oldTime();
|
||||||
|
*oldField == exact[0];
|
||||||
|
nI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::resetAdjointField
|
||||||
|
(
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
dimensioned<Type> zero(field.dimensions(), Zero);
|
||||||
|
field == zero;
|
||||||
|
// Restore oldTimes to zero too
|
||||||
|
GeometricField<Type, PatchField, GeoMesh>* oldField = &field;
|
||||||
|
for (label i = 0; i < field.nOldTimes(); ++i)
|
||||||
|
{
|
||||||
|
oldField = &oldField->oldTime();
|
||||||
|
*oldField == zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::setMeanField
|
||||||
|
(
|
||||||
|
refPtr<GeometricField<Type, PatchField, GeoMesh>>& meanFieldPtr,
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
const fvMesh& mesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
meanFieldPtr.reset
|
||||||
|
(
|
||||||
|
new GeometricField<Type, PatchField, GeoMesh>
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
field.name() + "Mean",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
field,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
void variablesSet::setMeanField
|
||||||
|
(
|
||||||
|
autoPtr<GeometricField<Type, PatchField, GeoMesh>>& meanFieldPtr,
|
||||||
|
const GeometricField<Type, PatchField, GeoMesh>& field,
|
||||||
|
const fvMesh& mesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
meanFieldPtr.reset
|
||||||
|
(
|
||||||
|
new GeometricField<Type, PatchField, GeoMesh>
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
field.name()+"Mean",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
field,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -0,0 +1,748 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Ostream.H"
|
||||||
|
#include "binomialCheckPointing.H"
|
||||||
|
#include "memInfo.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "messageStream.H"
|
||||||
|
#include "primalSolver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(binomialCheckPointing, 0);
|
||||||
|
defineRunTimeSelectionTable(binomialCheckPointing, dictionary);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
primalStorage,
|
||||||
|
binomialCheckPointing,
|
||||||
|
primalStorage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::binomialCheckPointing::hostStartProcess
|
||||||
|
(
|
||||||
|
wordList& hostNames
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Gather host names for all processors
|
||||||
|
wordList machineName(Pstream::nProcs());
|
||||||
|
machineName[Pstream::myProcNo()] = hostName();
|
||||||
|
Pstream::gatherList(machineName);
|
||||||
|
Pstream::scatterList(machineName);
|
||||||
|
hostNames = machineName;
|
||||||
|
|
||||||
|
// Start processor ID for each host; to be resized
|
||||||
|
const label nProcs(Pstream::nProcs());
|
||||||
|
labelList hostStartProcess(nProcs + 1, 0);
|
||||||
|
|
||||||
|
label iHost(0);
|
||||||
|
word prev(word::null);
|
||||||
|
for (label procI = 0; procI < nProcs; ++procI)
|
||||||
|
{
|
||||||
|
if (machineName[procI] != prev)
|
||||||
|
{
|
||||||
|
hostStartProcess[iHost] = procI;
|
||||||
|
prev = machineName[procI];
|
||||||
|
iHost++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Allocate an additional entry for easy looping over start
|
||||||
|
// of this host and the next one
|
||||||
|
hostStartProcess.setSize(iHost + 1);
|
||||||
|
hostStartProcess[iHost] = nProcs;
|
||||||
|
return hostStartProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::binomialCheckPointing::checkPointSize()
|
||||||
|
{
|
||||||
|
Time& time = const_cast<Time&>(mesh_.time());
|
||||||
|
label startTimeIndex = mesh_.time().timeIndex();
|
||||||
|
dimensionedScalar startTime = mesh_.time();
|
||||||
|
|
||||||
|
Info<< "CheckPoint size computation:: Time = "
|
||||||
|
<< time.timeName() << nl << endl;
|
||||||
|
primalSolver_.solveIter();
|
||||||
|
checkPoint temp(storageParams_());
|
||||||
|
incompressibleVars& incoVars = refCast<incompressibleVars>(variablesSet_);
|
||||||
|
temp.setPlaceHolder(false);
|
||||||
|
temp.store(incoVars);
|
||||||
|
|
||||||
|
time.setTime(startTime, startTimeIndex);
|
||||||
|
|
||||||
|
return temp.storageMetrics()[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long long Foam::binomialCheckPointing::maxNumberOfCheckPoints()
|
||||||
|
{
|
||||||
|
// Find checkpoint size per processor (in MB)
|
||||||
|
scalarList size(Pstream::nProcs());
|
||||||
|
size[Pstream::myProcNo()] = checkPointSize()*1.e-6;
|
||||||
|
Pstream::gatherList(size);
|
||||||
|
Pstream::scatterList(size);
|
||||||
|
if (!memInfo().valid())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "memInfo is invalid" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
// Available memory in MB. Is stored on a per-processor base but actually
|
||||||
|
// refers to the host. Use with caution
|
||||||
|
scalarList free(Pstream::nProcs());
|
||||||
|
free[Pstream::myProcNo()] = memInfo().update().free()*1.e-3;
|
||||||
|
Pstream::gatherList(free);
|
||||||
|
Pstream::scatterList(free);
|
||||||
|
|
||||||
|
// Host name, per process
|
||||||
|
wordList hostNames(0);
|
||||||
|
// Start processor ID per host
|
||||||
|
labelList hostStartProcessID(hostStartProcess(hostNames));
|
||||||
|
label nHosts(hostStartProcessID.size() - 1);
|
||||||
|
|
||||||
|
// Determine the number of checkpoints that can be allocated as the
|
||||||
|
// minimum from all hosts
|
||||||
|
labelList hostCheckPointSize(nHosts, 0);
|
||||||
|
label nCheckPoints(pTraits<label>::max);
|
||||||
|
label limitingHostID(-1);
|
||||||
|
for (label iHost = 0; iHost < nHosts; ++iHost)
|
||||||
|
{
|
||||||
|
const label start(hostStartProcessID[iHost]);
|
||||||
|
const label end(hostStartProcessID[iHost + 1]);
|
||||||
|
label& hostSize = hostCheckPointSize[iHost];
|
||||||
|
for (label procI = start; procI < end; ++procI)
|
||||||
|
{
|
||||||
|
hostSize += size[procI];
|
||||||
|
}
|
||||||
|
if (hostSize == 0)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "hostSize = 0!!" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
scalar val = free[start]/hostSize;
|
||||||
|
label nHostCheckPoints(pTraits<label>::max);
|
||||||
|
if (val <= 0)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "free[start], hostSize = " << free[start]
|
||||||
|
<< " " << hostSize << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
else if (val < pTraits<label>::max)
|
||||||
|
{
|
||||||
|
nHostCheckPoints = val;
|
||||||
|
}
|
||||||
|
if (nHostCheckPoints < nCheckPoints)
|
||||||
|
{
|
||||||
|
nCheckPoints = nHostCheckPoints;
|
||||||
|
limitingHostID = iHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print global check point size
|
||||||
|
Info<< nl << "Global size of a checkpoint is "
|
||||||
|
<< sum(size) << " MBs" << nl
|
||||||
|
<< "Total free memory in all hosts: "
|
||||||
|
<< sum(free)*1.e-3 << " GBs" << endl;
|
||||||
|
|
||||||
|
// Print max number of check points that fit in the most limiting host
|
||||||
|
Info<< "Approximately " << nCheckPoints
|
||||||
|
<< " checkpoints can be stored, "
|
||||||
|
<< "without accounting for cashed memory " << endl;
|
||||||
|
|
||||||
|
// Print information on a per host basis
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< setw(23) << "Host" << " | "
|
||||||
|
<< setw(23) << "Checkpoint size (kBs)" << " | "
|
||||||
|
<< setw(23) << "Available memory (kBs)" << " | "
|
||||||
|
<< setw(23) << "Max checkpoints (local)"
|
||||||
|
<< nl;
|
||||||
|
for (label iHost = 0; iHost < nHosts; ++iHost)
|
||||||
|
{
|
||||||
|
const label start(hostStartProcessID[iHost]);
|
||||||
|
Info<< setw(23) << hostNames[start] << " "
|
||||||
|
<< setw(23) << hostCheckPointSize[iHost] << " "
|
||||||
|
<< setw(23) << free[start] << " "
|
||||||
|
<< setw(23) << free[start]/hostCheckPointSize[iHost]
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
string limitingHost;
|
||||||
|
if (Pstream::myProcNo() == hostStartProcessID[limitingHostID])
|
||||||
|
{
|
||||||
|
limitingHost = hostName();
|
||||||
|
}
|
||||||
|
reduce(limitingHost, sumOp<word>());
|
||||||
|
Info<< "Limiting factor is host " << limitingHost << nl << endl;
|
||||||
|
|
||||||
|
return nCheckPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::initialize()
|
||||||
|
{
|
||||||
|
nCheckPoints_ = storageDict_.subDict("storageParameters").
|
||||||
|
get<label>("nCheckPoints") + 1;
|
||||||
|
if (nCheckPoints_ < 1)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "nCheckPoints = " << nCheckPoints_ << ". Please provide a "
|
||||||
|
<< "value >=1" << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
/*if (storageDict_.subDict("storageParameters").found("nCheckPoints"))
|
||||||
|
{
|
||||||
|
nCheckPoints_ = storageDict_.subDict("storageParameters").
|
||||||
|
get<label>("nCheckPoints");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCheckPoints_ = maxNumberOfCheckPoints();
|
||||||
|
}*/
|
||||||
|
checkPoints_.setSize(nCheckPoints_);
|
||||||
|
indirectAddressing_ = identity(nCheckPoints_);
|
||||||
|
Info<< nl << "Total number of checkpoints = "
|
||||||
|
<< nCheckPoints_ << nl << endl;
|
||||||
|
for (label fI = 0; fI < nCheckPoints_; ++fI)
|
||||||
|
{
|
||||||
|
checkPoints_.set(fI, new checkPoint(storageParams_()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::gatherMetrics()
|
||||||
|
{
|
||||||
|
if (storageParams_().timing())
|
||||||
|
{
|
||||||
|
for (scalar& smI : storageMetrics_)
|
||||||
|
{
|
||||||
|
reduce(smI, sumOp<scalar>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::setMetricsFilesPtr()
|
||||||
|
{
|
||||||
|
fileName filePath =
|
||||||
|
storageFolder_/"AllOptCycles" + primalSolver_.solverName();
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Creating file: " << filePath << endl;
|
||||||
|
metricsFilePtr_.reset(new OFstream(filePath));
|
||||||
|
if (!metricsFilePtr_()())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Stream has failed." << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Error while creating file: " << filePath << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
metricsFilePtr_()
|
||||||
|
<< setw(width) << "nCheckPoints" << tab
|
||||||
|
<< setw(width) << "Overall CR (CR_0)" << tab
|
||||||
|
<< setw(width) << "ZFP CR (CR_ZFP)" << tab
|
||||||
|
<< setw(width) << "Initial Size (Mb)" << tab
|
||||||
|
<< setw(width) << "Initial Size Saved (Mb)" << tab
|
||||||
|
<< setw(width) << "Compressed Size (Mb)"<< endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
metricsFilePtr_.reset
|
||||||
|
(
|
||||||
|
new OFstream
|
||||||
|
(
|
||||||
|
filePath,
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::currentVersion,
|
||||||
|
IOstream::UNCOMPRESSED,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::setCheckPointsFilesPtr()
|
||||||
|
{
|
||||||
|
fileName filePath =
|
||||||
|
storageFolder_/"checkPoints" + primalSolver_.solverName();
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Creating file: " << filePath << endl;
|
||||||
|
checkPointsFilePtr_.reset(new OFstream(filePath));
|
||||||
|
if (!checkPointsFilePtr_()())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Stream has failed." << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Error while creating file: " << filePath << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
checkPointsFilePtr_()
|
||||||
|
<< setw(width) << "S/N" << tab
|
||||||
|
<< setw(width) << "TimeIndex" << tab
|
||||||
|
<< setw(width) << "Level" << tab
|
||||||
|
<< setw(width) << "Time" << tab
|
||||||
|
<< setw(width) << "Placeholder" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkPointsFilePtr_.reset
|
||||||
|
(
|
||||||
|
new OFstream
|
||||||
|
(
|
||||||
|
filePath,
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::currentVersion,
|
||||||
|
IOstream::UNCOMPRESSED,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::binomialCheckPointing::writeToFile()
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
if (!metricsFilePtr_)
|
||||||
|
{
|
||||||
|
setMetricsFilesPtr();
|
||||||
|
}
|
||||||
|
const scalar& initialSize = storageMetrics_[0];
|
||||||
|
const scalar& uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
const scalar& uncompressedSize = storageMetrics_[2];
|
||||||
|
const scalar& compressedSize = storageMetrics_[3];
|
||||||
|
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
metricsFilePtr_()
|
||||||
|
<< setprecision(IOstream::defaultPrecision());
|
||||||
|
metricsFilePtr_()
|
||||||
|
<< setw(width) << activeCheckPoints_ << tab
|
||||||
|
<< setw(width) << uncompressedRoughSize/compressedSize << tab
|
||||||
|
<< setw(width) << uncompressedSize/compressedSize << tab
|
||||||
|
<< setw(width) << initialSize*1.e-6 << tab
|
||||||
|
<< setw(width) << uncompressedRoughSize*1.e-6 << tab
|
||||||
|
<< setw(width) << compressedSize*1e-6 << endl;
|
||||||
|
if (!checkPointsFilePtr_)
|
||||||
|
{
|
||||||
|
setCheckPointsFilesPtr();
|
||||||
|
}
|
||||||
|
checkPointsFilePtr_()
|
||||||
|
<< setprecision(IOstream::defaultPrecision());
|
||||||
|
for (label fI = 0; fI < nCheckPoints_; ++fI)
|
||||||
|
{
|
||||||
|
const label pos = indirectAddressing_[fI];
|
||||||
|
if (checkPoints_[pos].active())
|
||||||
|
{
|
||||||
|
checkPointsFilePtr_()
|
||||||
|
<< setw(width) << fI << tab
|
||||||
|
<< setw(width) << checkPoints_[pos].timeIndex() << tab
|
||||||
|
<< setw(width) << checkPoints_[pos].level() << tab
|
||||||
|
<< setw(width) << name(checkPoints_[pos].timeValue())
|
||||||
|
<< setw(width) << checkPoints_[pos].placeHolder()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkPointsFilePtr_() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::calcStorageMetrics()
|
||||||
|
{
|
||||||
|
storageMetrics_ = checkPoints_[0].storageMetrics();
|
||||||
|
for (label fI = 1; fI < nCheckPoints_; ++fI)
|
||||||
|
{
|
||||||
|
if (checkPoints_[fI].active() && !checkPoints_[fI].placeHolder())
|
||||||
|
{
|
||||||
|
storageMetrics_ =
|
||||||
|
storageMetrics_
|
||||||
|
+ checkPoints_[fI].storageMetrics();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::binomialCheckPointing::binomialCheckPointing
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
primalStorage(primalSolverObj, storageDict),
|
||||||
|
totalSteps_(0),
|
||||||
|
recomputationSteps_(0),
|
||||||
|
storageParams_
|
||||||
|
(
|
||||||
|
storageParameters::New
|
||||||
|
(mesh_, storageDict_, variablesSet_.allocatedFieldNames())
|
||||||
|
),
|
||||||
|
adjustTimeStep_(storageParams_->adjustTimeStep()),
|
||||||
|
checkPoints_(),
|
||||||
|
startingTime_(mesh_.time().startTime()),
|
||||||
|
activeCheckPoints_(0),
|
||||||
|
iPtr_(storagePtrs_[0])
|
||||||
|
{
|
||||||
|
makeFolder();
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::binomialCheckPointing> Foam::binomialCheckPointing::New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return autoPtr<binomialCheckPointing>
|
||||||
|
(
|
||||||
|
new binomialCheckPointing(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::scratch()
|
||||||
|
{
|
||||||
|
indirectAddressing_ = identity(nCheckPoints_);
|
||||||
|
for (checkPoint& cp : checkPoints_)
|
||||||
|
{
|
||||||
|
cp.empty();
|
||||||
|
}
|
||||||
|
totalSteps_ = 0;
|
||||||
|
recomputationSteps_ = 0;
|
||||||
|
activeCheckPoints_ = 0;
|
||||||
|
storageMetrics_.clear();
|
||||||
|
iPtr_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::storeVariables()
|
||||||
|
{
|
||||||
|
label jPtr(0);
|
||||||
|
// Add current to placeholder
|
||||||
|
|
||||||
|
// Find the dispensable checkpoint with the largest time index
|
||||||
|
// idis holds the index of the checkpoint that will be removed.
|
||||||
|
label maxlevel = 0;
|
||||||
|
// Despensable checkpoint index
|
||||||
|
label idis = 0;
|
||||||
|
for (label i = nCheckPoints_ - 1; i >= 1; --i)
|
||||||
|
{
|
||||||
|
if (maxlevel > checkPoints_[indirectAddressing_[i]].level())
|
||||||
|
{
|
||||||
|
// Keep the index only the first time it enters, since it
|
||||||
|
// will have the greater index
|
||||||
|
idis = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxlevel = checkPoints_[indirectAddressing_[i]].level();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (activeCheckPoints_ < nCheckPoints_)
|
||||||
|
{
|
||||||
|
// Scenario 1: not all checkpoints allocated yet.
|
||||||
|
DebugInfo
|
||||||
|
<< "Scenario 1" << endl;
|
||||||
|
const label pos = indirectAddressing_[activeCheckPoints_];
|
||||||
|
checkPoints_[pos].setPlaceHolder(false);
|
||||||
|
jPtr = activeCheckPoints_;
|
||||||
|
activeCheckPoints_++;
|
||||||
|
}
|
||||||
|
else if (idis > 0)
|
||||||
|
{
|
||||||
|
// Scenario 2:
|
||||||
|
// at least one checkpoint is despensable. Create a new checkPoint
|
||||||
|
// at the end of the indirect addressing list of level 0.
|
||||||
|
DebugInfo
|
||||||
|
<< "Scenario 2" << endl;
|
||||||
|
const label pos = indirectAddressing_[idis];
|
||||||
|
for (label i = idis; i < nCheckPoints_ - 1; ++i)
|
||||||
|
{
|
||||||
|
indirectAddressing_[i] = indirectAddressing_[i + 1];
|
||||||
|
}
|
||||||
|
indirectAddressing_[nCheckPoints_ - 1] = pos;
|
||||||
|
checkPoints_[pos].setPlaceHolder(false);
|
||||||
|
jPtr = nCheckPoints_ - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Scenario 3:
|
||||||
|
// no checkpoint is despensable. Overwrite last checkpoint
|
||||||
|
// and increase its level
|
||||||
|
DebugInfo
|
||||||
|
<< "Scenario 3" << endl;
|
||||||
|
const label pos = indirectAddressing_[nCheckPoints_ - 1];
|
||||||
|
checkPoints_[pos].setPlaceHolder(true);
|
||||||
|
jPtr = nCheckPoints_ - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the previous time-step is in the current set of check-points and
|
||||||
|
// checkpoint is not a placeholder checkpoint store the solution. When
|
||||||
|
// retrieving the solution at scenario 2, the checkpoint is not set as a
|
||||||
|
// placeholder as Wang proposes, so there is no need to store again the
|
||||||
|
// solution in that case.
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(
|
||||||
|
time_.timeIndex() - 1
|
||||||
|
== checkPoints_[indirectAddressing_[jPtr - 1]].timeIndex()
|
||||||
|
)
|
||||||
|
&& checkPoints_[indirectAddressing_[jPtr - 1]].placeHolder()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Storing time-step with time, timeIndex = "
|
||||||
|
<< name(checkPoints_[indirectAddressing_[jPtr - 1]].timeValue())
|
||||||
|
<< " "
|
||||||
|
<< checkPoints_[indirectAddressing_[jPtr - 1]].timeIndex()
|
||||||
|
<< endl;
|
||||||
|
incompressibleVars& incoVars =
|
||||||
|
refCast<incompressibleVars>(variablesSet_);
|
||||||
|
checkPoints_[indirectAddressing_[jPtr - 1]].store(incoVars);
|
||||||
|
}
|
||||||
|
calcStorageMetrics();
|
||||||
|
++iPtr_;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< "checkPoint time values -->Start<--" << endl;
|
||||||
|
for (label fI = 0; fI < nCheckPoints_; ++fI)
|
||||||
|
{
|
||||||
|
const label pos = indirectAddressing_[fI];
|
||||||
|
Info<< "Checkpoint-ID, indirectAddressing, timeIndex, "
|
||||||
|
<< "level, time, placeHolder = "
|
||||||
|
<< fI << " "
|
||||||
|
<< pos << " "
|
||||||
|
<< checkPoints_[pos].timeIndex() << " "
|
||||||
|
<< checkPoints_[pos].level() << " "
|
||||||
|
<< name(checkPoints_[pos].timeValue()) << " "
|
||||||
|
<< checkPoints_[pos].placeHolder() << endl;
|
||||||
|
}
|
||||||
|
Info<< "checkPoint time values --> End <--" << endl;
|
||||||
|
}
|
||||||
|
// Accumulate the primal step to counter
|
||||||
|
totalSteps_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::storeInitialVariables()
|
||||||
|
{
|
||||||
|
// Store initial time-step as a placeholder checkPoint of level oo
|
||||||
|
checkPoints_[0].setPlaceHolder(false);
|
||||||
|
checkPoints_[0].level() = pTraits<label>::max;
|
||||||
|
activeCheckPoints_++;
|
||||||
|
++iPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::retrieveVariables()
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Retrieving checkPoint for time " << time_.timeIndex() << endl;
|
||||||
|
dimensionedScalar adjEndingTime = time_.endTime();
|
||||||
|
label timeIndex = time_.timeIndex();
|
||||||
|
|
||||||
|
// Remove the checkpoint if it is at a greater time-step than the current
|
||||||
|
// one, or if it is at the same time-step as the current one, but it is a
|
||||||
|
// placeHolder checkPoint.
|
||||||
|
const label lastPos = indirectAddressing_[activeCheckPoints_ - 1];
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(checkPoints_[lastPos].timeIndex() > timeIndex)
|
||||||
|
|| (
|
||||||
|
checkPoints_[lastPos].timeIndex() == timeIndex &&
|
||||||
|
checkPoints_[lastPos].placeHolder()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label pos = indirectAddressing_[activeCheckPoints_ - 1];
|
||||||
|
DebugInfo
|
||||||
|
<< "Removing checkPoint: ID, timeIndex, time = " << pos << " "
|
||||||
|
<< checkPoints_[pos].timeIndex() << " "
|
||||||
|
<< name(checkPoints_[pos].timeValue()) << endl;
|
||||||
|
checkPoints_[pos].empty();
|
||||||
|
activeCheckPoints_--;
|
||||||
|
}
|
||||||
|
Time& time = const_cast<Time&>(time_);
|
||||||
|
if
|
||||||
|
(
|
||||||
|
checkPoints_[indirectAddressing_[activeCheckPoints_ - 1]].timeIndex()
|
||||||
|
== timeIndex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Scenario 1:
|
||||||
|
// there is a checkpoint at the current time-step. Retrieve the
|
||||||
|
// solution and make it a placeholder checkpoint
|
||||||
|
DebugInfo
|
||||||
|
<< "Scenario 1" << endl;
|
||||||
|
const label pos = indirectAddressing_[activeCheckPoints_ - 1];
|
||||||
|
checkPoints_[pos].retrieve();
|
||||||
|
variablesSet_.validateTurbulence();
|
||||||
|
if (adjustTimeStep_)
|
||||||
|
{
|
||||||
|
time.setDeltaT(checkPoints_[pos].deltaT());
|
||||||
|
}
|
||||||
|
checkPoints_[pos].resetToPlaceHolder();
|
||||||
|
activeCheckPoints_--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Scenario 2:
|
||||||
|
// there is no checkpoint at the current time-step. Retrieve the
|
||||||
|
// solution at the last checkpoint
|
||||||
|
DebugInfo
|
||||||
|
<< "Scenario 2" << endl;
|
||||||
|
const label pos = indirectAddressing_[activeCheckPoints_ - 1];
|
||||||
|
|
||||||
|
scalar nowTime(time.value());
|
||||||
|
if (adjustTimeStep_)
|
||||||
|
{
|
||||||
|
time.setDeltaT(checkPoints_[pos].deltaT());
|
||||||
|
}
|
||||||
|
time.setTime
|
||||||
|
(checkPoints_[pos].timeValue(), checkPoints_[pos].timeIndex());
|
||||||
|
time.setEndTime(nowTime);
|
||||||
|
|
||||||
|
checkPoints_[pos].retrieve();
|
||||||
|
variablesSet_.validateTurbulence();
|
||||||
|
|
||||||
|
while (primalSolver_.loop())
|
||||||
|
{
|
||||||
|
Info<< "Primal-CheckPointing::";
|
||||||
|
primalSolver_.solveIter();
|
||||||
|
recomputationSteps_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
time.setEndTime(adjEndingTime);
|
||||||
|
--iPtr_;
|
||||||
|
// Accumulate the adjoint step to counter
|
||||||
|
totalSteps_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::postAdjointLoop()
|
||||||
|
{
|
||||||
|
// Output re-computation info
|
||||||
|
scalar recomputationLoad =
|
||||||
|
scalar((2.*recomputationSteps_))/
|
||||||
|
scalar((totalSteps_-recomputationSteps_));
|
||||||
|
Info<<"\n/* * * * * * * * * * * * * * * * * * * * * * * */" << nl
|
||||||
|
<<"Total number of steps "<<totalSteps_ << nl
|
||||||
|
<<"Recomputations "<<recomputationSteps_ << nl
|
||||||
|
<<"Recomputation load "<<recomputationLoad << nl
|
||||||
|
<<"/* * * * * * * * * * * * * * * * * * * * * * * */" << nl << endl;
|
||||||
|
|
||||||
|
// Rewind storage pointers with a Warning
|
||||||
|
WarningInFunction
|
||||||
|
<< "Rewinding storage pointers, "
|
||||||
|
<< "even though check-points have been re-arranged." << nl
|
||||||
|
<< "Use binomialCheckPointing with caution in the presence of multiple"
|
||||||
|
<< " adjoint solvers"
|
||||||
|
<< endl;
|
||||||
|
primalStorage::postAdjointLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::binomialCheckPointing::storageMetrics()
|
||||||
|
{
|
||||||
|
gatherMetrics();
|
||||||
|
writeToFile();
|
||||||
|
|
||||||
|
const scalar initialSize = storageMetrics_[0];
|
||||||
|
const scalar uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
const scalar uncompressedSize = storageMetrics_[2];
|
||||||
|
const scalar compressedSize = storageMetrics_[3];
|
||||||
|
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Primal Storage Statistics" << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
|
||||||
|
unsigned int width = 6;//IOstream::defaultPrecision();
|
||||||
|
Info<< setprecision(width);
|
||||||
|
Info<< "nCheckPoints = "
|
||||||
|
<< activeCheckPoints_ << nl
|
||||||
|
<< "Compression Ratio CR_0 = "
|
||||||
|
<< uncompressedRoughSize/compressedSize << nl
|
||||||
|
<< "ZFP Compression ratio CR_ZFP = "
|
||||||
|
<< uncompressedSize/compressedSize << nl
|
||||||
|
<< "Initial Size = "
|
||||||
|
<< initialSize*1.e-6 << " Mb" << nl
|
||||||
|
<< "Initial Size Saved = "
|
||||||
|
<< uncompressedRoughSize*1.e-6 << " Mb" << nl
|
||||||
|
<< "Compressed Size = "
|
||||||
|
<< compressedSize*1.e-6 << " Mb" << endl;
|
||||||
|
Info<< setprecision(IOstream::defaultPrecision()) << endl;
|
||||||
|
/*
|
||||||
|
Info << "checkPoint time values -->Start<--" << endl;
|
||||||
|
for (label fI=0; fI<nCheckPoints_; fI++)
|
||||||
|
{
|
||||||
|
const label& pos = indirectAddressing_[fI];
|
||||||
|
Info << "Checkpoint-ID, timeIndex, level, time, placeholder = " << fI << " "
|
||||||
|
<< checkPoints_[pos].timeIndex() << " " << checkPoints_[pos].level()
|
||||||
|
<< " " << ::Foam::name(checkPoints_[pos].timeValue()) << " "
|
||||||
|
<< checkPoints_[pos].placeHolder() << endl;
|
||||||
|
}
|
||||||
|
Info << "checkPoint time values --> End <--" << endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,224 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::binomialCheckPointing
|
||||||
|
|
||||||
|
Description
|
||||||
|
Class implementing the binomial check-pointing technique for the unsteady
|
||||||
|
adjoint optimisation
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
binomialCheckPointing.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef binomialCheckPointing_H
|
||||||
|
#define binomialCheckPointing_H
|
||||||
|
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "storageParameters.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "checkPoint.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class binomialCheckPointing Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class binomialCheckPointing
|
||||||
|
:
|
||||||
|
public primalStorage
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Counter of the total number of time-steps performed to
|
||||||
|
//- complete the optimization cycle
|
||||||
|
// primal + adjoint + primal recomputations due to checkPointing
|
||||||
|
label totalSteps_;
|
||||||
|
|
||||||
|
//- Counter of the number of recomputation time-steps
|
||||||
|
//- performed to complete the optimization cycle
|
||||||
|
label recomputationSteps_;
|
||||||
|
|
||||||
|
//- Storage parameters
|
||||||
|
autoPtr<storageParameters> storageParams_;
|
||||||
|
|
||||||
|
//- Reseting deltaT causes slight disrepancies in comparison to the
|
||||||
|
//- solution of shortFullStorage.
|
||||||
|
// Reseting applied only with non-constant time-step. Entry taken from
|
||||||
|
// storageParameters to avoid the possibility of the user changing
|
||||||
|
// runTime the adjustTimeStep of controlDict
|
||||||
|
const Switch& adjustTimeStep_;
|
||||||
|
|
||||||
|
//- Number of chechPoints to be stored
|
||||||
|
label nCheckPoints_;
|
||||||
|
|
||||||
|
//- Accumulated storage metrics
|
||||||
|
scalarList storageMetrics_;
|
||||||
|
|
||||||
|
//- All stored checkPoints
|
||||||
|
PtrList<checkPoint> checkPoints_;
|
||||||
|
|
||||||
|
//- Position of each checkPoint, as stored in chronological order,
|
||||||
|
//- in the checkPoints list
|
||||||
|
List<label> indirectAddressing_;
|
||||||
|
|
||||||
|
dimensionedScalar startingTime_;
|
||||||
|
|
||||||
|
label activeCheckPoints_;
|
||||||
|
|
||||||
|
label& iPtr_;
|
||||||
|
|
||||||
|
mutable autoPtr<OFstream> metricsFilePtr_;
|
||||||
|
|
||||||
|
mutable autoPtr<OFstream> checkPointsFilePtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Gather metrics from all processors if timing == true.
|
||||||
|
// If timing == false, the reduce operation has already been deployed.
|
||||||
|
void gatherMetrics();
|
||||||
|
|
||||||
|
//- Set file to write metrics - one line for each optimisation cycle
|
||||||
|
void setMetricsFilesPtr();
|
||||||
|
|
||||||
|
//- Set file to write checkPoints
|
||||||
|
void setCheckPointsFilesPtr();
|
||||||
|
|
||||||
|
inline void writeToFile();
|
||||||
|
|
||||||
|
//- Calculates the compression metrics of the whole primal solution
|
||||||
|
virtual void calcStorageMetrics();
|
||||||
|
|
||||||
|
//- Start process for each host
|
||||||
|
labelList hostStartProcess(wordList& hostNames) const;
|
||||||
|
|
||||||
|
//- Get checkpoint size. The size of the first checkpoint size is not
|
||||||
|
//- dependable, since it may include only the fields of the current
|
||||||
|
//- time-step and not the oldTimes. Instead, we solve for one
|
||||||
|
//- time-step and use its size as a reference
|
||||||
|
scalar checkPointSize();
|
||||||
|
|
||||||
|
//- Print checkpoint size and estimate number of checkpoints that
|
||||||
|
//- can be allocated based on the available memory at run time
|
||||||
|
unsigned long long maxNumberOfCheckPoints();
|
||||||
|
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
binomialCheckPointing(const binomialCheckPointing&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const binomialCheckPointing&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("binomialCheckPointing");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
binomialCheckPointing,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
),
|
||||||
|
(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
binomialCheckPointing
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Allocate new binomialCheckPointing
|
||||||
|
static autoPtr<binomialCheckPointing> New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~binomialCheckPointing() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Release all checkpoints
|
||||||
|
virtual void scratch() override;
|
||||||
|
|
||||||
|
//- Store current variable set as a checkpoint if needed
|
||||||
|
virtual void storeVariables() override;
|
||||||
|
|
||||||
|
virtual void storeInitialVariables() override;
|
||||||
|
|
||||||
|
virtual void retrieveVariables() override;
|
||||||
|
|
||||||
|
//- Operations performed after the end of the adjoint loop
|
||||||
|
virtual void postAdjointLoop() override;
|
||||||
|
|
||||||
|
//- Function to write the storage metrics of the whole primal solution
|
||||||
|
virtual void storageMetrics() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,150 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "compressedFullStorage.H"
|
||||||
|
#include "compressedIncompressibleVars.H"
|
||||||
|
#include "memInfo.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(compressedFullStorage, 0);
|
||||||
|
defineRunTimeSelectionTable(compressedFullStorage, dictionary);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
primalStorage,
|
||||||
|
compressedFullStorage,
|
||||||
|
primalStorage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::compressedFullStorage::compressedFullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
primalStorage(primalSolverObj, storageDict),
|
||||||
|
allPrimalVars_(0),
|
||||||
|
storageMetrics_(),
|
||||||
|
totalSteps_(0),
|
||||||
|
recomputationSteps_(0),
|
||||||
|
metricsFilePtr_()
|
||||||
|
{
|
||||||
|
makeFolder();
|
||||||
|
storageParams_.reset
|
||||||
|
(
|
||||||
|
storageParameters::New
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
storageDict_,
|
||||||
|
variablesSet_.allocatedFieldNames()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::compressedFullStorage> Foam::compressedFullStorage::New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const dictionary& dict = storageDict.subDict("storageParameters");
|
||||||
|
const word type(dict.get<word>("algorithm") + "FullStorage");
|
||||||
|
Info<< "CompressedFullStorage type" << tab << type << endl;
|
||||||
|
|
||||||
|
auto* ctorPtr = dictionaryConstructorTable(type);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalIOErrorInLookup
|
||||||
|
(
|
||||||
|
storageDict,
|
||||||
|
"compressedFullStorage",
|
||||||
|
type,
|
||||||
|
*dictionaryConstructorTablePtr_
|
||||||
|
) << exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<compressedFullStorage>
|
||||||
|
(ctorPtr(primalSolverObj, storageDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::compressedFullStorage::scratch()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::compressedFullStorage::storeVariables()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::compressedFullStorage::retrieveVariables()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::compressedFullStorage::postAdjointLoop()
|
||||||
|
{
|
||||||
|
scalar recomputationLoad =
|
||||||
|
scalar((2.*recomputationSteps_))/
|
||||||
|
scalar((totalSteps_-recomputationSteps_));
|
||||||
|
Info<<"\n/* * * * * * * * * * * * * * * * * * * * * * * */\n"
|
||||||
|
<<"Total number of steps "<<totalSteps_ << nl
|
||||||
|
<<"Recomputations "<<recomputationSteps_ << nl
|
||||||
|
<<"Recomputation load "<<recomputationLoad << nl
|
||||||
|
<<"/* * * * * * * * * * * * * * * * * * * * * * * */\n" << endl;
|
||||||
|
|
||||||
|
// Rewind storage ptrs
|
||||||
|
primalStorage::postAdjointLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::compressedFullStorage::storageMetrics()
|
||||||
|
{
|
||||||
|
NotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::compressedFullStorage
|
||||||
|
|
||||||
|
Description
|
||||||
|
Compresses and stores all instances of the primal flow fields
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
compressedFullStorage.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef compressedFullStorage_H
|
||||||
|
#define compressedFullStorage_H
|
||||||
|
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "compressedIncompressibleVars.H"
|
||||||
|
#include "storageParameters.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class compressedFullStorage Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class compressedFullStorage
|
||||||
|
:
|
||||||
|
public primalStorage
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
PtrList<compressedIncompressibleVars> allPrimalVars_;
|
||||||
|
|
||||||
|
scalarList storageMetrics_;
|
||||||
|
|
||||||
|
//- Counter of the total number of time-steps performed to
|
||||||
|
//- complete the optimization cycle.
|
||||||
|
// Equal to primal + adjoint + primal recomputations
|
||||||
|
// in case of checkPointing strategies
|
||||||
|
label totalSteps_;
|
||||||
|
|
||||||
|
//- Counter of the number of recomputation time-steps
|
||||||
|
//- performed to complete the optimization cycle
|
||||||
|
label recomputationSteps_;
|
||||||
|
|
||||||
|
//- Storage parameters
|
||||||
|
autoPtr<storageParameters> storageParams_;
|
||||||
|
|
||||||
|
mutable autoPtr<OFstream> metricsFilePtr_;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
compressedFullStorage(const compressedFullStorage&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const compressedFullStorage&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("compressedFullStorage");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
compressedFullStorage,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
),
|
||||||
|
(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
compressedFullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<compressedFullStorage> New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~compressedFullStorage() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Free memory used to store the primal time-series
|
||||||
|
virtual void scratch() override;
|
||||||
|
|
||||||
|
//- Store current copy of the variablesSet (could be lossy)
|
||||||
|
virtual void storeVariables() override;
|
||||||
|
|
||||||
|
//- Retrieve primal-based quantities into the active variablesSet
|
||||||
|
virtual void retrieveVariables() override;
|
||||||
|
|
||||||
|
//- Operations performed after the end of the adjoint loop
|
||||||
|
virtual void postAdjointLoop() override;
|
||||||
|
|
||||||
|
//- Function to write the storage metrics of the whole primal solution
|
||||||
|
virtual void storageMetrics() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,236 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "primalSolver.H"
|
||||||
|
#include "shortFullStorage.H"
|
||||||
|
#include "memInfo.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(shortFullStorage, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
compressedFullStorage,
|
||||||
|
shortFullStorage,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::gatherMetrics()
|
||||||
|
{
|
||||||
|
if (storageParams_().timing())
|
||||||
|
{
|
||||||
|
for (scalar& storageMetric : storageMetrics_)
|
||||||
|
{
|
||||||
|
reduce(storageMetric, sumOp<scalar>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::setMetricsFilesPtr()
|
||||||
|
{
|
||||||
|
fileName filePath =
|
||||||
|
storageFolder_/"AllOptCycles" + primalSolver_.solverName();
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "Creating file: " << filePath << endl;
|
||||||
|
metricsFilePtr_.reset(new OFstream(filePath));
|
||||||
|
if (!metricsFilePtr_()())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Stream has failed." << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
if (!isFile(filePath))
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Error while creating file: " << filePath << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
metricsFilePtr_()
|
||||||
|
<< setw(width) << "Initial Size (Mb)" << tab
|
||||||
|
<< setw(width) << "Initial Size Saved (Mb)" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
metricsFilePtr_.reset
|
||||||
|
(
|
||||||
|
new OFstream
|
||||||
|
(
|
||||||
|
filePath,
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::currentVersion,
|
||||||
|
IOstream::UNCOMPRESSED,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::shortFullStorage::writeToFile()
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
if (!metricsFilePtr_)
|
||||||
|
{
|
||||||
|
setMetricsFilesPtr();
|
||||||
|
}
|
||||||
|
const scalar initialSize = storageMetrics_[0];
|
||||||
|
const scalar uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
unsigned int width = IOstream::defaultPrecision() + 6;
|
||||||
|
metricsFilePtr_()
|
||||||
|
<< setprecision(IOstream::defaultPrecision());
|
||||||
|
metricsFilePtr_() << setw(width) << initialSize*1.e-6 << tab
|
||||||
|
<< setw(width) << uncompressedRoughSize*1.e-6 << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::calcStorageMetrics()
|
||||||
|
{
|
||||||
|
const scalarList& metrics = allPrimalVars_[iPtr_].storageMetrics();
|
||||||
|
if (allPrimalVars_.size() == 1)
|
||||||
|
{
|
||||||
|
storageMetrics_ = metrics;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
storageMetrics_ = storageMetrics_ + metrics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::shortFullStorage::shortFullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
compressedFullStorage(primalSolverObj, storageDict),
|
||||||
|
iPtr_(storagePtrs_[0])
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::scratch()
|
||||||
|
{
|
||||||
|
totalSteps_ = 0;
|
||||||
|
iPtr_ = -1;
|
||||||
|
allPrimalVars_.clear();
|
||||||
|
storageMetrics_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::storeVariables()
|
||||||
|
{
|
||||||
|
if (allPrimalVars_.size() > iPtr_ + 1)
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
WarningInFunction
|
||||||
|
<< tab
|
||||||
|
<< "allPrimalVars.size(), iPtr = "
|
||||||
|
<< allPrimalVars_.size() << " " << iPtr_
|
||||||
|
<< nl << tab
|
||||||
|
<< "Normally, allPrimalVars.size() = iPtr + 1 in each time step"
|
||||||
|
<< nl << tab
|
||||||
|
<< "Possible cause: Multiple compressions/decompressions "
|
||||||
|
<< "of the same time step"
|
||||||
|
<< nl << tab
|
||||||
|
<< "allPrimalVars.size() manually set to "
|
||||||
|
<< iPtr_ + 1 << nl << endl;
|
||||||
|
allPrimalVars_.resize(iPtr_ + 1);
|
||||||
|
}
|
||||||
|
incompressibleVars& incoVars = refCast<incompressibleVars>(variablesSet_);
|
||||||
|
autoPtr<compressedIncompressibleVars> varsPtr
|
||||||
|
(
|
||||||
|
compressedIncompressibleVars::New
|
||||||
|
(
|
||||||
|
incoVars,
|
||||||
|
storageParams_()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
varsPtr->compress();
|
||||||
|
varsPtr->calculateStorageMetrics();
|
||||||
|
allPrimalVars_.append(varsPtr);
|
||||||
|
++iPtr_;
|
||||||
|
calcStorageMetrics();
|
||||||
|
// Accumulate the primal step to counter
|
||||||
|
totalSteps_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::retrieveVariables()
|
||||||
|
{
|
||||||
|
if (allPrimalVars_.empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "allPrimalVars_ list is empty." << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
allPrimalVars_[iPtr_].decompress();
|
||||||
|
variablesSet_.validateTurbulence();
|
||||||
|
--iPtr_;
|
||||||
|
// Accumulate the adjoint step to counter
|
||||||
|
totalSteps_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::shortFullStorage::storageMetrics()
|
||||||
|
{
|
||||||
|
gatherMetrics();
|
||||||
|
writeToFile();
|
||||||
|
|
||||||
|
const scalar initialSize = storageMetrics_[0];
|
||||||
|
const scalar uncompressedRoughSize = storageMetrics_[1];
|
||||||
|
|
||||||
|
Info<< nl << "- - - - - - - - - - - - - - - - - - - - -" << endl;
|
||||||
|
Info<< "Primal Storage Statistics" << endl;
|
||||||
|
Info<< "- - - - - - - - - - - - - - - - - - - - -" << nl << endl;
|
||||||
|
|
||||||
|
Info<< setprecision(6);
|
||||||
|
Info<< "Initial Size = " << initialSize*1.e-6 << " Mb" << endl;
|
||||||
|
Info<< "Stored Size = " << uncompressedRoughSize*1.e-6 << " Mb" << endl;
|
||||||
|
Info<< setprecision(IOstream::defaultPrecision()) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::shortFullStorage
|
||||||
|
|
||||||
|
Description
|
||||||
|
Stores all instances of the primal flow fields.
|
||||||
|
In constrast to full storage, parts of the fields that can be recomputed
|
||||||
|
(fixedValue boundary conditions, processor values etc) are not stored,
|
||||||
|
reducing slightly the memory footprint
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
shortFullStorage.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef shortFullStorage_H
|
||||||
|
#define shortFullStorage_H
|
||||||
|
|
||||||
|
#include "compressedFullStorage.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class shortFullStorage Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class shortFullStorage
|
||||||
|
:
|
||||||
|
public compressedFullStorage
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
label& iPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Gather metrics from all processors if timing == true.
|
||||||
|
// If timing == false, the reduce operation has already been deployed.
|
||||||
|
void gatherMetrics();
|
||||||
|
|
||||||
|
//- Set file to write metrics - one line per optimisation cycle
|
||||||
|
void setMetricsFilesPtr();
|
||||||
|
|
||||||
|
inline void writeToFile();
|
||||||
|
|
||||||
|
//- Function to calculate the compression metrics of the whole primal
|
||||||
|
//- solution
|
||||||
|
void calcStorageMetrics();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
shortFullStorage(const shortFullStorage&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const shortFullStorage&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("shortFullStorage");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
shortFullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~shortFullStorage() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Free memory used to store the primal time-series
|
||||||
|
virtual void scratch() override;
|
||||||
|
|
||||||
|
//- Store current copy of the variablesSet (could be lossy)
|
||||||
|
virtual void storeVariables() override;
|
||||||
|
|
||||||
|
//- Retrieve primal-based quantities into the active variablesSet
|
||||||
|
virtual void retrieveVariables() override;
|
||||||
|
|
||||||
|
//- Function to write the storage metrics of the whole primal solution
|
||||||
|
void storageMetrics() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,235 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fullStorage.H"
|
||||||
|
#include "memInfo.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(fullStorage, 0);
|
||||||
|
defineRunTimeSelectionTable(fullStorage, dictionary);
|
||||||
|
addToRunTimeSelectionTable(primalStorage, fullStorage, primalStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::fullStorage::hostStartProcess(wordList& hostNames) const
|
||||||
|
{
|
||||||
|
// Gather host names for all processors
|
||||||
|
wordList machineName(Pstream::nProcs());
|
||||||
|
machineName[Pstream::myProcNo()] = hostName();
|
||||||
|
Pstream::gatherList(machineName);
|
||||||
|
Pstream::scatterList(machineName);
|
||||||
|
hostNames = machineName;
|
||||||
|
|
||||||
|
// Start process ID for each host; to be resized
|
||||||
|
const label nProcs(Pstream::nProcs());
|
||||||
|
labelList hostStartProcess(nProcs + 1, 0);
|
||||||
|
|
||||||
|
label iHost(0);
|
||||||
|
word prev(word::null);
|
||||||
|
for (label procI = 0; procI < nProcs; ++procI)
|
||||||
|
{
|
||||||
|
if (machineName[procI] != prev)
|
||||||
|
{
|
||||||
|
hostStartProcess[iHost] = procI;
|
||||||
|
prev = machineName[procI];
|
||||||
|
++iHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Allocate an additional entry for easy looping over start
|
||||||
|
// of this host and the next one
|
||||||
|
hostStartProcess.setSize(iHost + 1);
|
||||||
|
hostStartProcess[iHost] = nProcs;
|
||||||
|
return hostStartProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::fullStorage::maxNumberOfInstances() const
|
||||||
|
{
|
||||||
|
// Find instance size per processor
|
||||||
|
labelList sizeBef(Pstream::nProcs());
|
||||||
|
sizeBef[Pstream::myProcNo()] = memInfo().size();
|
||||||
|
Pstream::gatherList(sizeBef);
|
||||||
|
Pstream::scatterList(sizeBef);
|
||||||
|
|
||||||
|
autoPtr<variablesSet> temp(variablesSet_.clone());
|
||||||
|
|
||||||
|
labelList sizeAft(Pstream::nProcs());
|
||||||
|
sizeAft[Pstream::myProcNo()] = memInfo().size();
|
||||||
|
Pstream::gatherList(sizeAft);
|
||||||
|
Pstream::scatterList(sizeAft);
|
||||||
|
|
||||||
|
// Available memory. Is stored on a per-processor base but actually
|
||||||
|
// refers to the host. Use with caution
|
||||||
|
labelList free(Pstream::nProcs());
|
||||||
|
free[Pstream::myProcNo()] = memInfo().free();
|
||||||
|
Pstream::gatherList(free);
|
||||||
|
Pstream::scatterList(free);
|
||||||
|
|
||||||
|
// Host name, per processor basis
|
||||||
|
wordList hostNames(0);
|
||||||
|
// Start process ID per host
|
||||||
|
labelList hostStartProcessID(hostStartProcess(hostNames));
|
||||||
|
label nHosts(hostStartProcessID.size() - 1);
|
||||||
|
|
||||||
|
// Determine the number of instances that can be allocated as the
|
||||||
|
// minimum from all hosts
|
||||||
|
labelList hostInstanceSize(nHosts, 0);
|
||||||
|
label nInstances(pTraits<label>::max);
|
||||||
|
label limitingHostID(-1);
|
||||||
|
for (label iHost = 0; iHost < nHosts; ++iHost)
|
||||||
|
{
|
||||||
|
const label start(hostStartProcessID[iHost]);
|
||||||
|
const label end(hostStartProcessID[iHost + 1]);
|
||||||
|
label& hostSize = hostInstanceSize[iHost];
|
||||||
|
for (label procI = start; procI < end; ++procI)
|
||||||
|
{
|
||||||
|
hostSize += sizeAft[procI] - sizeBef[procI];
|
||||||
|
}
|
||||||
|
label nHostCheckPoints(free[start]/hostSize);
|
||||||
|
if (nHostCheckPoints < nInstances)
|
||||||
|
{
|
||||||
|
nInstances = nHostCheckPoints;
|
||||||
|
limitingHostID = iHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print global instance size
|
||||||
|
const label checkPointSize(sum(sizeAft) - sum(sizeBef));
|
||||||
|
Info<< nl << "Global size of an instance is "
|
||||||
|
<< checkPointSize << " KBs" << endl;
|
||||||
|
|
||||||
|
// Print max number of check points that fit in the most limiting host
|
||||||
|
Info<< "Approximately " << nInstances
|
||||||
|
<< " instances can be stored, "
|
||||||
|
<< "without accounting for cached memory " << endl;
|
||||||
|
|
||||||
|
// Print information on a per host basis
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< setw(23) << "Host" << " | "
|
||||||
|
<< setw(23) << "Instance size (kBs)" << " | "
|
||||||
|
<< setw(23) << "Available memory (kBs)" << " | "
|
||||||
|
<< setw(23) << "Max checkpoints (local)"
|
||||||
|
<< nl;
|
||||||
|
for (label iHost = 0; iHost < nHosts; ++iHost)
|
||||||
|
{
|
||||||
|
const label start(hostStartProcessID[iHost]);
|
||||||
|
Info<< setw(23) << hostNames[start] << " "
|
||||||
|
<< setw(23) << hostInstanceSize[iHost] << " "
|
||||||
|
<< setw(23) << free[start] << " "
|
||||||
|
<< setw(23) << free[start]/hostInstanceSize[iHost]
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
string limitingHost;
|
||||||
|
if (Pstream::myProcNo() == hostStartProcessID[limitingHostID])
|
||||||
|
{
|
||||||
|
limitingHost = hostName();
|
||||||
|
}
|
||||||
|
reduce(limitingHost, sumOp<word>());
|
||||||
|
Info<< "Limiting factor is host " << limitingHost << nl << endl;
|
||||||
|
|
||||||
|
return nInstances;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fullStorage::fullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
primalStorage(primalSolverObj, storageDict),
|
||||||
|
allPrimalVars_(0),
|
||||||
|
iPtr_(storagePtrs_[0])
|
||||||
|
{
|
||||||
|
/*if (debug)
|
||||||
|
{
|
||||||
|
maxNumberOfCheckPoints();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::fullStorage> Foam::fullStorage::New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return autoPtr<fullStorage>
|
||||||
|
(
|
||||||
|
new fullStorage(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::fullStorage::scratch()
|
||||||
|
{
|
||||||
|
allPrimalVars_.clear();
|
||||||
|
iPtr_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fullStorage::storeVariables()
|
||||||
|
{
|
||||||
|
allPrimalVars_.append(variablesSet_.clone());
|
||||||
|
++iPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fullStorage::retrieveVariables()
|
||||||
|
{
|
||||||
|
if (allPrimalVars_.empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "allPrimalVars list is empty." << endl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
variablesSet_.transfer(allPrimalVars_[iPtr_]);
|
||||||
|
//allPrimalVars_.release(iPtr_);
|
||||||
|
--iPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,150 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fullStorage
|
||||||
|
|
||||||
|
Description
|
||||||
|
Stores all instances of the primal flow fields.
|
||||||
|
Can lead to huge memory requirements if used with large meshes and many
|
||||||
|
time-steps
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
fullStorage.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fullStorage_H
|
||||||
|
#define fullStorage_H
|
||||||
|
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class fullStorage Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class fullStorage
|
||||||
|
:
|
||||||
|
public primalStorage
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
PtrList<variablesSet> allPrimalVars_;
|
||||||
|
|
||||||
|
label& iPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Start process for each host
|
||||||
|
labelList hostStartProcess(wordList& hostNames) const;
|
||||||
|
|
||||||
|
//- Print time instance size and estimate number of instances that
|
||||||
|
//- can be allocated based on the available memory at run time
|
||||||
|
label maxNumberOfInstances() const;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
fullStorage(const fullStorage&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const fullStorage&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("fullStorage");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
fullStorage,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
),
|
||||||
|
(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
fullStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<fullStorage> New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~fullStorage() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
virtual void scratch() override;
|
||||||
|
|
||||||
|
virtual void storeVariables() override;
|
||||||
|
|
||||||
|
virtual void retrieveVariables() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "noneStorage.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(noneStorage, 0);
|
||||||
|
defineRunTimeSelectionTable(noneStorage, dictionary);
|
||||||
|
addToRunTimeSelectionTable(primalStorage, noneStorage, primalStorage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::noneStorage::noneStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
primalStorage(primalSolverObj, storageDict)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::noneStorage> Foam::noneStorage::New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return autoPtr<noneStorage>
|
||||||
|
(
|
||||||
|
new noneStorage(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::noneStorage::scratch()
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::noneStorage::storeVariables()
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::noneStorage::retrieveVariables()
|
||||||
|
{
|
||||||
|
// Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,130 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::noneStorage
|
||||||
|
|
||||||
|
Description
|
||||||
|
A primalStorage instance doing nothing. Used, for instance, with steady
|
||||||
|
state simulations
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
noneStorage.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef noneStorage_H
|
||||||
|
#define noneStorage_H
|
||||||
|
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class noneStorage Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class noneStorage
|
||||||
|
:
|
||||||
|
public primalStorage
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
noneStorage(const noneStorage&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const noneStorage&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("none");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
noneStorage,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
),
|
||||||
|
(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
noneStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<noneStorage> New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~noneStorage() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
virtual void scratch() override;
|
||||||
|
|
||||||
|
virtual void storeVariables() override;
|
||||||
|
|
||||||
|
virtual void retrieveVariables() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "error.H"
|
||||||
|
#include "primalStorage.H"
|
||||||
|
#include "primalSolver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(primalStorage, 0);
|
||||||
|
defineRunTimeSelectionTable(primalStorage, primalStorage);
|
||||||
|
|
||||||
|
label primalStorage::counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::primalStorage::makeFolder()
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
storageFolder_ = time_.globalPath()/"optimisation"/"storage";
|
||||||
|
//- do not remove directory to allow for continuation
|
||||||
|
//if (isDir(storageFolder_)) rmDir(storageFolder_);
|
||||||
|
mkDir(storageFolder_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::primalStorage::primalStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
time_(primalSolverObj.mesh().time()),
|
||||||
|
mesh_(primalSolverObj.mesh()),
|
||||||
|
primalSolver_(primalSolverObj),
|
||||||
|
storageDict_(storageDict),
|
||||||
|
variablesSet_(primalSolver_.getVariablesSet()),
|
||||||
|
storagePtrs_(1, -1),
|
||||||
|
storagePtrsCopy_(nullptr)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::primalStorage> Foam::primalStorage::New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word type(storageDict.get<word>("type"));
|
||||||
|
Info<< "Storage type for the primal fields: " << type << endl;
|
||||||
|
|
||||||
|
auto* ctorPtr = primalStorageConstructorTable(type);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalIOErrorInLookup
|
||||||
|
(
|
||||||
|
storageDict,
|
||||||
|
"primalStorage",
|
||||||
|
type,
|
||||||
|
*primalStorageConstructorTablePtr_
|
||||||
|
) << exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<primalStorage>(ctorPtr(primalSolverObj, storageDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::labelList& Foam::primalStorage::storagePtrs() const
|
||||||
|
{
|
||||||
|
return storagePtrs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::copyStoragePtrs()
|
||||||
|
{
|
||||||
|
storagePtrsCopy_.reset(new labelList(storagePtrs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::rewindStoragePtrs()
|
||||||
|
{
|
||||||
|
if (storagePtrsCopy_)
|
||||||
|
{
|
||||||
|
storagePtrs_ = storagePtrsCopy_();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Attempted to retrieve unset storePtrs" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::storeInitialVariables()
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::preLoopRetrieveVariables()
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::preAdjointLoop()
|
||||||
|
{
|
||||||
|
// Copy pointers to storage instances to a backup variable
|
||||||
|
copyStoragePtrs();
|
||||||
|
// Retrive certain variables before the adjoint loop
|
||||||
|
// (e.g. from files, for restarted cases)
|
||||||
|
preLoopRetrieveVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::postAdjointLoop()
|
||||||
|
{
|
||||||
|
rewindStoragePtrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primalStorage::storageMetrics()
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,203 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::primalStorage
|
||||||
|
|
||||||
|
Description
|
||||||
|
Abstract base class managing the storage of primal flow fields, to be later
|
||||||
|
used for the solution of unsteady flow equations
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
primalStorage.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef primalStorage_H
|
||||||
|
#define primalStorage_H
|
||||||
|
|
||||||
|
#include "Time.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "variablesSet.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaratrions
|
||||||
|
class primalSolver;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class primalStorage Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class primalStorage
|
||||||
|
{
|
||||||
|
static label counter;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
//- Const reference to time
|
||||||
|
const Time& time_;
|
||||||
|
|
||||||
|
//- Const reference to mesh
|
||||||
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
//- Reference to the primal solver used to create the time-series
|
||||||
|
//- being stored
|
||||||
|
primalSolver& primalSolver_;
|
||||||
|
|
||||||
|
//- Input dict
|
||||||
|
dictionary storageDict_;
|
||||||
|
|
||||||
|
//- Variables set of the primal solver
|
||||||
|
variablesSet& variablesSet_;
|
||||||
|
|
||||||
|
//- List of useful pointers in the flow time-series
|
||||||
|
// For instance, time-steps holding checkpoints, etc
|
||||||
|
labelList storagePtrs_;
|
||||||
|
|
||||||
|
//- Copy of the pointer's list
|
||||||
|
// Usefull for reseting in many of many primal solvers
|
||||||
|
autoPtr<labelList> storagePtrsCopy_;
|
||||||
|
|
||||||
|
//- Output folder
|
||||||
|
fileName storageFolder_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Set Folder
|
||||||
|
virtual void makeFolder();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
primalStorage(const primalStorage&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const primalStorage&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("primalStorage");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeNewSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
primalStorage,
|
||||||
|
primalStorage,
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
),
|
||||||
|
(primalSolverObj, storageDict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
primalStorage
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected turbulence model
|
||||||
|
static autoPtr<primalStorage> New
|
||||||
|
(
|
||||||
|
primalSolver& primalSolverObj,
|
||||||
|
const dictionary storageDict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
//- Virtual destructor
|
||||||
|
virtual ~primalStorage() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Get list with pointers to storage instances
|
||||||
|
virtual const labelList& storagePtrs() const;
|
||||||
|
|
||||||
|
//- Copy pointers to storage instances to a backup variable
|
||||||
|
virtual void copyStoragePtrs();
|
||||||
|
|
||||||
|
//- Rewind pointers to storage instance to the values set after the
|
||||||
|
//- solution of the primal equations
|
||||||
|
virtual void rewindStoragePtrs();
|
||||||
|
|
||||||
|
//- Free memory used to store the primal time-series
|
||||||
|
virtual void scratch() = 0;
|
||||||
|
|
||||||
|
//- Store current copy of the variablesSet (could be lossy)
|
||||||
|
virtual void storeVariables() = 0;
|
||||||
|
|
||||||
|
virtual void storeInitialVariables();
|
||||||
|
|
||||||
|
//- Retrieve primal-based quantities into the active variablesSet
|
||||||
|
virtual void retrieveVariables() = 0;
|
||||||
|
|
||||||
|
//- Retrive certain variables before the adjoint loop
|
||||||
|
// (e.g. from files, for restarted cases)
|
||||||
|
virtual void preLoopRetrieveVariables();
|
||||||
|
|
||||||
|
//- Operations performed before the beginning of the adjoint loop
|
||||||
|
virtual void preAdjointLoop();
|
||||||
|
|
||||||
|
//- Operations performed after the end of the adjoint loop
|
||||||
|
virtual void postAdjointLoop();
|
||||||
|
|
||||||
|
virtual void storageMetrics();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "shortParameters.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(shortParameters, 0);
|
||||||
|
addToRunTimeSelectionTable(storageParameters, shortParameters, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::shortParameters::initialize()
|
||||||
|
{
|
||||||
|
compressionMethod_.setSize(allocatedFieldNames_.size());
|
||||||
|
forAll(allocatedFieldNames_, iPtr)
|
||||||
|
{
|
||||||
|
compressionMethod_[iPtr] = algorithm_ + "GeometricField";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::shortParameters::shortParameters
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
)
|
||||||
|
:
|
||||||
|
storageParameters(mesh, storageDict, allocatedFieldNames)
|
||||||
|
{
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
shortParameters
|
||||||
|
|
||||||
|
Description
|
||||||
|
Reads from dictionary and stores all parameters related to the storage
|
||||||
|
of the primal fields
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
shortParameters.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef shortParameters_H
|
||||||
|
#define shortParameters_H
|
||||||
|
|
||||||
|
#include "storageParameters.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class shortParameters Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class shortParameters
|
||||||
|
:
|
||||||
|
public storageParameters
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
shortParameters(const shortParameters&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const shortParameters&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("shortParameters");
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
shortParameters
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~shortParameters() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
virtual void initialize() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,213 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Ostream.H"
|
||||||
|
#include "storageParameters.H"
|
||||||
|
#include "wallFvPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(storageParameters, 0);
|
||||||
|
defineRunTimeSelectionTable(storageParameters, dictionary);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
label storageParameters::counter = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void storageParameters::findCellsNextToWall()
|
||||||
|
{
|
||||||
|
// Find the boundary patches that are of type wall
|
||||||
|
const fvPatchList& patches = mesh_.boundary();
|
||||||
|
DynamicList<label> patchList;
|
||||||
|
label size(0);
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||||
|
if (isA<wallFvPatch>(patch))
|
||||||
|
{
|
||||||
|
patchList.append(patchI);
|
||||||
|
size += patch.faceCells().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Build list containing the IDs of the first cell centers next to wall
|
||||||
|
// boundaries
|
||||||
|
wallList_.setSize(size, -1);
|
||||||
|
label pos(0);
|
||||||
|
forAll(patchList, patchI)
|
||||||
|
{
|
||||||
|
const fvPatch& patch = mesh_.boundary()[patchList[patchI]];
|
||||||
|
forAll(patch, faceI)
|
||||||
|
{
|
||||||
|
wallList_[pos++] = patch.faceCells()[faceI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info<< "Found " << patchList.size() << " wall boundary(ies) "
|
||||||
|
<< "with total " << returnReduce(wallList_.size(), sumOp<label>())
|
||||||
|
<< " cells next to them." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
autoPtr<storageParameters> storageParameters::New
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const dictionary& dict = storageDict.subDict("storageParameters");
|
||||||
|
const word type(dict.get<word>("algorithm") + "Parameters" );
|
||||||
|
Info<< "Compression parameters type" << tab << type << endl;
|
||||||
|
|
||||||
|
auto* ctorPtr = dictionaryConstructorTable(type);
|
||||||
|
|
||||||
|
if (!ctorPtr)
|
||||||
|
{
|
||||||
|
FatalIOErrorInLookup
|
||||||
|
(
|
||||||
|
storageDict,
|
||||||
|
"storageParameters",
|
||||||
|
type,
|
||||||
|
*dictionaryConstructorTablePtr_
|
||||||
|
) << exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<storageParameters>
|
||||||
|
(ctorPtr(mesh, storageDict, allocatedFieldNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
storageParameters::storageParameters
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mesh_(mesh),
|
||||||
|
dict_(storageDict.subDict("storageParameters")),
|
||||||
|
allocatedFieldNames_(allocatedFieldNames),
|
||||||
|
compressionMethod_(),
|
||||||
|
writeFieldTimes_(),
|
||||||
|
timing_(true),
|
||||||
|
writeAll_(false),
|
||||||
|
tiny_(1.e-18),
|
||||||
|
solDirs_((mesh_.solutionD() + Vector<label>::one)/2)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void storageParameters::initialize()
|
||||||
|
{
|
||||||
|
// Build list containing the IDs of the first cell centers next to wall
|
||||||
|
// boundaries
|
||||||
|
findCellsNextToWall();
|
||||||
|
|
||||||
|
adjustTimeStep_ =
|
||||||
|
mesh_.time().controlDict().getOrDefault<Switch>("adjustTimeStep", false);
|
||||||
|
storeAllBoundaries_ =
|
||||||
|
dict_.getOrDefault<Switch>("storeAllBoundaries", false);
|
||||||
|
storeUniformBoundaries_ =
|
||||||
|
dict_.getOrDefault<Switch>("storeUniformBoundaries", false);
|
||||||
|
algorithm_ = dict_.get<word>("algorithm");
|
||||||
|
timing_ = dict_.getOrDefault<bool>("timing", true);
|
||||||
|
Info<< nl << "General Parameters:" << nl
|
||||||
|
<< tab << "algorithm " << algorithm_ << nl
|
||||||
|
<< tab << "timing " << timing_ << nl
|
||||||
|
<< tab << "storeAllBoundaries " << storeAllBoundaries_ << endl;
|
||||||
|
if (!timing_)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Timing should be deactivated only when a reduced performance "
|
||||||
|
<< "is acceptable."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
if (!storeAllBoundaries_)
|
||||||
|
{
|
||||||
|
Info<< tab << "storeUniformBoundaries "
|
||||||
|
<< storeUniformBoundaries_ << endl;
|
||||||
|
if (storeUniformBoundaries_)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "'storeUniformBoundaries' has been activated." << nl
|
||||||
|
<< "This is redundant but useful in debugging." << nl
|
||||||
|
<< "Make sure it is intentional." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (storeAllBoundaries_)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "'storeAllBoundaries' should be activated only for debugging "
|
||||||
|
<< "purposes, since unneccessary storage is allocated" << endl;
|
||||||
|
}
|
||||||
|
writeAll_ = dict_.getOrDefault<bool>("writeAll", false);
|
||||||
|
Info << tab << "writeAll " << writeAll_ << endl;
|
||||||
|
if (!writeAll_)
|
||||||
|
{
|
||||||
|
writeFieldTimes_ =
|
||||||
|
dict_.getOrDefault<scalarList>("writeFieldTimes", scalarList());
|
||||||
|
if (writeFieldTimes_.size() > 0)
|
||||||
|
{
|
||||||
|
Info<< tab << "Time-steps to write primal fields:" << endl
|
||||||
|
<< tab << writeFieldTimes_ << nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void storageParameters::reset()
|
||||||
|
{
|
||||||
|
// Does nothing in base
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,273 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2019-2022 PCOpt/NTUA
|
||||||
|
Copyright (C) 2022 FOSS GP
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
storageParameters
|
||||||
|
|
||||||
|
Description
|
||||||
|
Reads from dictionary and stores all parameters related to the storage
|
||||||
|
of the primal fields
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
storageParameters.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef storageParameters_H
|
||||||
|
#define storageParameters_H
|
||||||
|
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class storageParameters Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class storageParameters
|
||||||
|
{
|
||||||
|
static label counter;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Data
|
||||||
|
|
||||||
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
const dictionary dict_;
|
||||||
|
|
||||||
|
const wordList& allocatedFieldNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// Entries read from dictionary
|
||||||
|
|
||||||
|
//- Entry defining if the simulation has a constant time-step or
|
||||||
|
//- not. Added here to define whether the time-step must be updated
|
||||||
|
//- when retrieving the variablesSet in checkPointing
|
||||||
|
Switch adjustTimeStep_;
|
||||||
|
|
||||||
|
//- Entry defining if all boundaries will be stored, regardless if
|
||||||
|
//- they contain values that can be reproduced upon reconstruction.
|
||||||
|
// Defaults to false.
|
||||||
|
Switch storeAllBoundaries_;
|
||||||
|
|
||||||
|
//- Switch defining if the uniform boundaries must be compressed or
|
||||||
|
//- not. If false, a single value (scalar or vector) will be kept
|
||||||
|
//- for each of these boundaries. If true, these boundaries will be
|
||||||
|
//- stored using the same algorithm with the internalField. If
|
||||||
|
//- 'storeAllBoundaries' is set to true, this switch should have no
|
||||||
|
//- effect
|
||||||
|
Switch storeUniformBoundaries_;
|
||||||
|
|
||||||
|
//- Algorithm to be used for the compression (ZFP, iPGD, etc)
|
||||||
|
word algorithm_;
|
||||||
|
|
||||||
|
//- Entry defining the algorithm variant to be used for the
|
||||||
|
//- compression of each field. Valid entries are the derived
|
||||||
|
//- classes of the compressedGeometricField class. The method is
|
||||||
|
//- defined here once for all the objects to be created during the
|
||||||
|
//- optimization (of course the method may differ for each primal
|
||||||
|
//- field).
|
||||||
|
wordList compressionMethod_;
|
||||||
|
|
||||||
|
//- scalarList containing the times on which the primal fields must
|
||||||
|
//- be written. Both before compression and after decompression.
|
||||||
|
scalarList writeFieldTimes_;
|
||||||
|
|
||||||
|
//- boolean controling if all unnecessary actions are avoided to
|
||||||
|
//- benchmark the code
|
||||||
|
bool timing_;
|
||||||
|
|
||||||
|
//- boolean activated only if timing_ is set to false. If
|
||||||
|
//- activated, the writeFieldTimes is ignored and the 'exact' and
|
||||||
|
//- the reconstructed fields are written at all time-steps
|
||||||
|
bool writeAll_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Small scalar value to be added in the denominator to avoid division
|
||||||
|
//- by zero
|
||||||
|
scalar tiny_;
|
||||||
|
|
||||||
|
//- Return the vector of solved-for directions in mesh.
|
||||||
|
// 1 indicates valid direction and 0 an invalid direction.
|
||||||
|
const Vector<label> solDirs_;
|
||||||
|
|
||||||
|
//- List containing the IDs of the first cell centers next to wall
|
||||||
|
//- boundaries
|
||||||
|
labelList wallList_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Fills in wallList_
|
||||||
|
void findCellsNextToWall();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
storageParameters(const storageParameters&) = delete;
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const storageParameters&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("storageParameters");
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
storageParameters,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
),
|
||||||
|
(mesh, storageDict, allocatedFieldNames)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
storageParameters
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected storageParameters
|
||||||
|
static autoPtr<storageParameters> New
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& storageDict,
|
||||||
|
const wordList& allocatedFieldNames
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~storageParameters() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
virtual void initialize();
|
||||||
|
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
inline const fvMesh& mesh() const
|
||||||
|
{
|
||||||
|
return mesh_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Switch& adjustTimeStep() const
|
||||||
|
{
|
||||||
|
return adjustTimeStep_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Switch& storeAllBoundaries() const
|
||||||
|
{
|
||||||
|
return storeAllBoundaries_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Switch& storeUniformBoundaries() const
|
||||||
|
{
|
||||||
|
return storeUniformBoundaries_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const word& algorithm() const
|
||||||
|
{
|
||||||
|
return algorithm_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const dictionary& dict() const
|
||||||
|
{
|
||||||
|
return dict_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const scalarList& writeFieldTimes() const
|
||||||
|
{
|
||||||
|
return writeFieldTimes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool timing() const
|
||||||
|
{
|
||||||
|
return timing_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool writeAll() const
|
||||||
|
{
|
||||||
|
return writeAll_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector<label>& solDirs() const
|
||||||
|
{
|
||||||
|
return solDirs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const wordList& compressionMethod() const
|
||||||
|
{
|
||||||
|
return compressionMethod_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar tiny() const
|
||||||
|
{
|
||||||
|
return tiny_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const labelList& wallList() const
|
||||||
|
{
|
||||||
|
return wallList_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user