diff --git a/src/optimisation/adjointOptimisation/adjoint/Make/files b/src/optimisation/adjointOptimisation/adjoint/Make/files
index 8a1b1662f6..c022ecfb14 100644
--- a/src/optimisation/adjointOptimisation/adjoint/Make/files
+++ b/src/optimisation/adjointOptimisation/adjoint/Make/files
@@ -6,6 +6,13 @@ turbulenceModels/turbulenceModelVariables/RAS/kOmegaSST/kOmegaSST.C
turbulenceModels/turbulenceModelVariables/RAS/kEpsilon/kEpsilon.C
turbulenceModels/turbulenceModelVariables/RAS/LaunderSharmaKE/LaunderSharmaKE.C
+/* FVOPTIONS */
+fvOptions/sources/TopO/topOSource/topOSource.C
+
+/* FUNCTION1 */
+OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.C
+OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.C
+
/* VARIABLES SET */
solvers/variablesSet/variablesSet/variablesSet.C
solvers/variablesSet/incompressible/incompressibleVars.C
@@ -57,6 +64,8 @@ objectives/incompressible/objectiveUniformityPatch/objectiveUniformityPatch.C
objectives/incompressible/objectiveUniformityCellZone/objectiveUniformityCellZone.C
objectives/geometric/objectiveGeometric/objectiveGeometric.C
objectives/geometric/objectivePartialVolume/objectivePartialVolume.C
+objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.C
+objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.C
/* OBJECTIVE MANAGER*/
objectiveManager/objectiveManager.C
@@ -152,6 +161,7 @@ optimisation/adjointSensitivity/adjointSensitivity/multiple/sensitivityMultiple.
/* LINE SEARCH */
optimisation/lineSearch/lineSearch/lineSearch.C
optimisation/lineSearch/ArmijoConditions/ArmijoConditions.C
+optimisation/lineSearch/GCMMA/GCMMA.C
optimisation/lineSearch/stepUpdate/stepUpdate/stepUpdate.C
optimisation/lineSearch/stepUpdate/bisection/bisection.C
optimisation/lineSearch/stepUpdate/quadratic/quadratic.C
@@ -167,6 +177,7 @@ $(updateMethod)/DBFGS/DBFGS.C
$(updateMethod)/LBFGS/LBFGS.C
$(updateMethod)/SR1/SR1.C
$(updateMethod)/conjugateGradient/conjugateGradient.C
+$(updateMethod)/MMA/MMA.C
$(updateMethod)/constraintProjection/constraintProjection.C
$(updateMethod)/SQPBase/SQPBase.C
$(updateMethod)/SQP/SQP.C
@@ -174,6 +185,33 @@ $(updateMethod)/ISQP/ISQP.C
/* DESIGN VARIABLES */
optimisation/designVariables/designVariables/designVariables.C
+topoVars=optimisation/designVariables/topODesignVariables
+$(topoVars)/topOVariablesBase/topOVariablesBase.C
+$(topoVars)/topODesignVariables.C
+$(topoVars)/dynamicTopODesignVariables/dynamicTopODesignVariables.C
+$(topoVars)/betaMax/betaMax/betaMax.C
+$(topoVars)/betaMax/value/betaMaxValue.C
+$(topoVars)/betaMax/Darcy/betaMaxDarcy.C
+$(topoVars)/betaMax/stepRamp/betaMaxStepRamp.C
+$(topoVars)/topOZones/topOZones.C
+$(topoVars)/regularisation/fieldRegularisation.C
+$(topoVars)/regularisation/regularisationRadius/regularisationRadius/regularisationRadius.C
+$(topoVars)/regularisation/regularisationRadius/isotropic/regularisationRadiusIsotropic.C
+$(topoVars)/regularisation/regularisationPDE/regularisationPDE/regularisationPDE.C
+$(topoVars)/regularisation/regularisationPDE/Helmoltz/Helmholtz.C
+$(topoVars)/marchingCells/marchingCells.C
+$(topoVars)/interpolationFunctions/interpolationFunction/topOInterpolationFunction.C
+$(topoVars)/interpolationFunctions/BorrvallPetersson/BorrvallPeterssonInterpolation.C
+$(topoVars)/interpolationFunctions/invBP/invBP.C
+$(topoVars)/interpolationFunctions/linear/linearInterpolation.C
+$(topoVars)/interpolationFunctions/SIMP/SIMPInterpolation.C
+$(topoVars)/interpolationFunctions/sinh/sinhInterpolation.C
+$(topoVars)/interpolationFunctions/tanh/tanhInterpolation.C
+$(topoVars)/interpolationFunctions/exp/expInterpolation.C
+levelSetVars=optimisation/designVariables/levelSet
+$(levelSetVars)/levelSetDesignVariables.C
+$(levelSetVars)/interpolationFunctions/sigmoidalHeaviside/sigmoidalHeaviside.C
+$(levelSetVars)/interpolationFunctions/smoothHeaviside/smoothHeaviside.C
shapeVars=optimisation/designVariables/shape
$(shapeVars)/shapeDesignVariables/shapeDesignVariables.C
$(shapeVars)/volumetricBSplines/morphingBoxConstraints/morphingBoxConstaint/morphingBoxConstraint.C
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.C b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.C
new file mode 100644
index 0000000000..6a1d9b25e0
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.C
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "reverseRamp.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function1Types
+{
+ makeScalarFunction1(reverseRamp);
+}
+}
+
+
+// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
+
+Foam::Function1Types::reverseRamp::reverseRamp
+(
+ const word& entryName,
+ const dictionary& dict,
+ const objectRegistry* obrPtr
+)
+:
+ ramp(entryName, dict),
+ minValue_(dict.getOrDefault("minValue", Zero)),
+ interval_(dict.get("interval")),
+ steps_(duration_/interval_)
+{}
+
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.H b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.H
new file mode 100644
index 0000000000..06807567cf
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRamp.H
@@ -0,0 +1,128 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+Class
+ Foam::Function1Types::reverseRamp
+
+Description
+ Reverse ramp function starting from 1 and decreasing stepRamply to a min.
+ user-specified value from \c start over the \c duration and remaining
+ constant thereafter.
+
+See also
+ Foam::Function1Types::ramp
+
+SourceFiles
+ reverseRamp.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef reverseRamp_H
+#define reverseRamp_H
+
+#include "ramp.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace Function1Types
+{
+
+/*---------------------------------------------------------------------------*\
+ Class reverseRamp Declaration
+\*---------------------------------------------------------------------------*/
+
+class reverseRamp
+:
+ public ramp
+{
+protected:
+
+ // Protected Data Members
+
+ //- The min value
+ scalar minValue_;
+
+ //- Interval for reducing the base value
+ scalar interval_;
+
+ //- Steps to reach the min. value
+ scalar steps_;
+
+
+private:
+
+ // Private Data Members
+
+ //- No copy assignment
+ void operator=(const reverseRamp&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("reverseRamp");
+
+
+ // Constructors
+
+ //- Construct from entry and dictionary
+ reverseRamp
+ (
+ const word& entryName,
+ const dictionary& dict,
+ const objectRegistry* obrPtr = nullptr
+ );
+
+
+ //- Destructor
+ virtual ~reverseRamp() = default;
+
+
+ // Member Functions
+
+ //- Return value for time t
+ inline virtual scalar value(const scalar t) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Function1Types
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "reverseRampI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRampI.H b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRampI.H
new file mode 100644
index 0000000000..09011027b0
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/reverseRamp/reverseRampI.H
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
+
+inline Foam::scalar Foam::Function1Types::reverseRamp::value
+(
+ const scalar t
+) const
+{
+ // Reverse linear ramp
+ //return min(max(scalar(1) - (t - start_)/duration_, scalar(0)), scalar(1));
+
+ // Reverse step ramp
+ return min
+ (
+ max
+ (
+ -(floor((t - start_)/interval_))/steps_
+ *(scalar(1) - minValue_) + scalar(1),
+ minValue_
+ ),
+ scalar(1)
+ );
+}
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.C b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.C
new file mode 100644
index 0000000000..1cf835b87c
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.C
@@ -0,0 +1,56 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2017 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "stepRamp.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function1Types
+{
+ makeScalarFunction1(stepRamp);
+}
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::Function1Types::stepRamp::stepRamp
+(
+ const word& entryName,
+ const dictionary& dict,
+ const objectRegistry* obrPtr
+)
+:
+ ramp(entryName, dict, obrPtr),
+ interval_(dict.get("interval")),
+ steps_(max(floor(duration_/interval_), scalar(1)))
+{}
+
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.H b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.H
new file mode 100644
index 0000000000..5c577866e5
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRamp.H
@@ -0,0 +1,118 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2017 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 .
+
+Class
+ Foam::Function1Types::stepRamp
+
+Description
+ Linear ramp function starting from 0 and increasing stepRamply to 1 from
+ \c start over the \c duration and remaining at 1 thereafter.
+
+See also
+ Foam::Function1Types::ramp
+
+SourceFiles
+ stepRamp.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef stepRamp_H
+#define stepRamp_H
+
+#include "ramp.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Function1Types
+{
+
+/*---------------------------------------------------------------------------*\
+ Class stepRamp Declaration
+\*---------------------------------------------------------------------------*/
+
+class stepRamp
+:
+ public ramp
+{
+
+ // Private data
+
+ //- Interval for increasing the base value
+ scalar interval_;
+
+ //- Steps to reach maximum value
+ scalar steps_;
+
+
+ // Private Member Functions
+
+ //- No copy assignment
+ void operator=(const stepRamp&) = delete;
+
+
+public:
+
+ // Runtime type information
+ TypeName("stepRamp");
+
+
+ // Constructors
+
+ //- Construct from entry name and dictionary
+ stepRamp
+ (
+ const word& entryName,
+ const dictionary& dict,
+ const objectRegistry* obrPtr = nullptr
+ );
+
+
+ //- Destructor
+ virtual ~stepRamp() = default;
+
+
+ // Member Functions
+
+ //- Return value for time t
+ virtual inline scalar value(const scalar t) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Function1Types
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "stepRampI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRampI.H b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRampI.H
new file mode 100644
index 0000000000..7300bfb80c
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/OpenFOAM/primitives/functions/Function1/stepRamp/stepRampI.H
@@ -0,0 +1,41 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2017 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "stepRamp.H"
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline Foam::scalar Foam::Function1Types::stepRamp::value
+(
+ const scalar t
+) const
+{
+ return max(min((floor((t -start_)/interval_) + 1)/steps_, 1), 0);
+}
+
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.C b/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.C
new file mode 100644
index 0000000000..d3813d69d6
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.C
@@ -0,0 +1,229 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2020-2023 PCOpt/NTUA
+ Copyright (C) 2020-2023 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "topOSource.H"
+#include "fvMatrices.H"
+#include "fvmSup.H"
+#include "topOVariablesBase.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ namespace fv
+ {
+ defineTypeNameAndDebug(topOSource, 1);
+ addToRunTimeSelectionTable
+ (
+ option,
+ topOSource,
+ dictionary
+ );
+ }
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
+
+Foam::tmp>
+Foam::fv::topOSource::getSource()
+{
+ auto tinterpolant
+ (
+ tmp>::New
+ (
+ IOobject
+ (
+ "source",
+ mesh_.time().timeName(),
+ mesh_,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh_,
+ dimless/dimTime,
+ scalarField(mesh_.nCells(), Zero)
+ )
+ );
+ DimensionedField& interpolant = tinterpolant.ref();
+
+ if (mesh_.foundObject("topoVars"))
+ {
+ const topOVariablesBase& vars =
+ mesh_.lookupObject("topoVars");
+ vars.sourceTerm
+ (interpolant, interpolation_(), betaMax_, interpolationFieldName_);
+
+ if (darcyFlow_)
+ {
+ interpolant.field() += betaMax_*Da_();
+ }
+ }
+
+ return tinterpolant;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::fv::topOSource::topOSource
+(
+ const word& name,
+ const word& modelType,
+ const dictionary& dict,
+ const fvMesh& mesh
+)
+:
+ option(name, modelType, dict, mesh),
+ interpolation_(topOInterpolationFunction::New(mesh, dict)),
+ interpolationFieldName_(word::null),
+ betaMax_(0),
+ darcyFlow_(false),
+ Da_(nullptr)
+{
+ read(dict);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+void Foam::fv::topOSource::addSup
+(
+ fvMatrix& eqn,
+ const label fieldi
+)
+{
+ DebugInfo
+ << "Adding Brinkman source to " << eqn.psi().name() << endl;
+
+ eqn -= fvm::Sp(getSource(), eqn.psi());
+}
+
+
+void Foam::fv::topOSource::addSup
+(
+ fvMatrix& eqn,
+ const label fieldi
+)
+{
+ DebugInfo
+ << "Adding Brinkman source to " << eqn.psi().name() << endl;
+
+ eqn -= fvm::Sp(getSource(), eqn.psi());
+}
+
+
+void Foam::fv::topOSource::addSup
+(
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+)
+{
+ DebugInfo
+ << "Adding Brinkman source to " << eqn.psi().name() << endl;
+
+ eqn -= fvm::Sp(rho*getSource(), eqn.psi());
+}
+
+
+void Foam::fv::topOSource::addSup
+(
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+)
+{
+ DebugInfo
+ << "Adding Brinkman source to " << eqn.psi().name() << endl;
+
+ eqn -= fvm::Sp(rho*getSource(), eqn.psi());
+}
+
+
+void Foam::fv::topOSource::postProcessSens
+(
+ scalarField& sens,
+ const word& fieldName,
+ const word& designVariablesName
+)
+{
+ const label fieldi = applyToField(fieldName);
+ if
+ (
+ fieldi != -1
+ && mesh_.foundObject("topoVars")
+ )
+ {
+ DebugInfo
+ << "Postprocessing Brinkman sensitivities for field "
+ << fieldName << endl;
+ const topOVariablesBase& vars =
+ mesh_.lookupObject("topoVars");
+ vars.sourceTermSensitivities
+ (
+ sens,
+ interpolation_(),
+ betaMax_,
+ designVariablesName,
+ interpolationFieldName_
+ );
+ }
+}
+
+
+bool Foam::fv::topOSource::read(const dictionary& dict)
+{
+ if (option::read(dict))
+ {
+ fieldNames_ = coeffs_.get("names");
+ interpolationFieldName_ = coeffs_.get("interpolationField");
+ applied_.setSize(fieldNames_.size(), false);
+ if (mesh_.foundObject("topoVars"))
+ {
+ const topOVariablesBase& vars =
+ mesh_.lookupObject("topoVars");
+ betaMax_ =
+ coeffs_.getOrDefault("betaMax", vars.getBetaMax());
+ }
+
+ darcyFlow_ = coeffs_.getOrDefault("darcyFlow", false);
+ if (darcyFlow_)
+ {
+ Da_.reset(new scalar(coeffs_.getOrDefault("Da", 1.e-5)));
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.H b/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.H
new file mode 100644
index 0000000000..401788b79a
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/fvOptions/sources/TopO/topOSource/topOSource.H
@@ -0,0 +1,183 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2020-2023 PCOpt/NTUA
+ Copyright (C) 2020-2023 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 .
+
+Class
+ Foam::fv::topOSource
+
+Group
+ grpFvOptionsSources
+
+Description
+ Impelements Brinkman penalisation terms for topology optimisation.
+ Looks up the indicator field (beta) from the registry, through
+ topOVariablesBase
+
+SourceFiles
+ topOSource.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef topOSource_H
+#define topOSource_H
+
+#include "cellSetOption.H"
+#include "topOInterpolationFunction.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace fv
+{
+
+
+/*---------------------------------------------------------------------------*\
+ Class topOSource Declaration
+\*---------------------------------------------------------------------------*/
+
+class topOSource
+:
+ public option
+{
+
+protected:
+
+ // Protected data
+
+ //- Interpolation function
+ autoPtr interpolation_;
+
+ //- Interpolation field name
+ word interpolationFieldName_;
+
+ //- Optional betaMax
+ // If not found, the one known by topOVariablesBase will be used.
+ scalar betaMax_;
+
+ //- Does this option apply to a Darcy flow model
+ bool darcyFlow_;
+
+ //- Dimensionless Darcy number
+ autoPtr Da_;
+
+
+ // Protected Member Functions
+
+ //- Compute the source term based on the indicator field
+ virtual tmp> getSource();
+
+
+private:
+
+ // Private Member Functions
+
+ //- No copy construct
+ topOSource(const topOSource&) = delete;
+
+ //- No copy assignment
+ void operator=(const topOSource&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("topOSource");
+
+
+ // Constructors
+
+ //- Construct from components
+ topOSource
+ (
+ const word& name,
+ const word& modelType,
+ const dictionary& dict,
+ const fvMesh& mesh
+ );
+
+
+ //- Destructor
+ virtual ~topOSource() = default;
+
+
+ // Member Functions
+
+ //- Add implicit contribution to momentum equation
+ virtual void addSup
+ (
+ fvMatrix& eqn,
+ const label fieldi
+ );
+
+ //- Add implicit contribution to scalar equations
+ //- (e.g. turbulence model)
+ virtual void addSup
+ (
+ fvMatrix& eqn,
+ const label fieldi
+ );
+
+ //- Add implicit contribution to compressible momentum equation
+ virtual void addSup
+ (
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+ );
+
+ //- Add implicit contribution to compressible scalar equation
+ virtual void addSup
+ (
+ const volScalarField& rho,
+ fvMatrix& eqn,
+ const label fieldi
+ );
+
+ //- Multiply sensitivities with the derivative of the interpolation
+ //- function
+ virtual void postProcessSens
+ (
+ scalarField& sensField,
+ const word& fieldName = word::null,
+ const word& designValue = word::null
+ );
+
+ //- Read source dictionary
+ virtual bool read(const dictionary& dict);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.C b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.C
new file mode 100644
index 0000000000..b315d85985
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.C
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2023 PCOpt/NTUA
+ Copyright (C) 2013-2023 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "objectiveTopOSolidVolume.H"
+#include "createZeroField.H"
+#include "IOmanip.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace objectives
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(objectiveTopOSolidVolume, 1);
+addToRunTimeSelectionTable
+(
+ objectiveGeometric,
+ objectiveTopOSolidVolume,
+ dictionary
+);
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+objectiveTopOSolidVolume::objectiveTopOSolidVolume
+(
+ const fvMesh& mesh,
+ const dictionary& dict,
+ const word& adjointSolverName,
+ const word& primalSolverName
+)
+:
+ objectiveGeometric(mesh, dict, adjointSolverName, primalSolverName),
+ targetPercentage_(Function1::New("percentage", dict)),
+ percentInDenom_(dict.getOrDefault("percentInDenom", true))
+{
+ // Allocate boundary field pointers
+ dJdbPtr_.reset(createZeroFieldPtr(mesh_, "dJdb", dimless));
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+
+scalar objectiveTopOSolidVolume::J()
+{
+ J_ = Zero;
+ if (mesh_.foundObject("beta"))
+ {
+ const volScalarField& beta = mesh_.lookupObject("beta");
+ const DimensionedField& V = mesh_.V();
+ const scalar time = mesh_.time().timeOutputValue();
+ J_ =
+ gSum(beta.primitiveField()*V)/gSum(V)
+ - targetPercentage_->value(time);
+ if (percentInDenom_)
+ {
+ J_ /= targetPercentage_->value(time);
+ }
+ }
+ else
+ {
+ WarningInFunction
+ << "Beta field not yet registered in database. OK for start-up"
+ << endl;
+ }
+ return J_;
+}
+
+
+void objectiveTopOSolidVolume::update_dJdb()
+{
+ const scalar time = mesh_.time().timeOutputValue();
+ dJdbPtr_().primitiveFieldRef() = scalar(1)/gSum(mesh_.V());
+ if (percentInDenom_)
+ {
+ dJdbPtr_().primitiveFieldRef() /= targetPercentage_->value(time);
+ }
+}
+
+
+void objectiveTopOSolidVolume::addHeaderColumns() const
+{
+ objFunctionFilePtr_()
+ << setw(width_) << "TargetVolume" << " ";
+}
+
+
+void objectiveTopOSolidVolume::addColumnValues() const
+{
+ const scalar time = mesh_.time().timeOutputValue();
+ objFunctionFilePtr_()
+ << setw(width_) << targetPercentage_->value(time) << " ";
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace objectives
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.H b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.H
new file mode 100644
index 0000000000..746fad08fa
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOSolidVolume/objectiveTopOSolidVolume.H
@@ -0,0 +1,118 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2023 PCOpt/NTUA
+ Copyright (C) 2013-2023 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 .
+
+
+Class
+ Foam::objectives::objectiveTopOSolidVolume
+
+Description
+ Objective quantifying the difference between the volume occupied by solid
+ in topology optimisation and a target percentage; the latter can change
+ throughout the optimisation cycles through a Function1.
+
+SourceFiles
+ objectiveTopOSolidVolume.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef objectiveTopOSolidVolume_H
+#define objectiveTopOSolidVolume_H
+
+#include "objectiveGeometric.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace objectives
+{
+
+/*---------------------------------------------------------------------------*\
+ Class objectiveTopOSolidVolume Declaration
+\*---------------------------------------------------------------------------*/
+
+class objectiveTopOSolidVolume
+:
+ public objectiveGeometric
+{
+ // Private data
+
+ autoPtr> targetPercentage_;
+
+ bool percentInDenom_;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("topOSolidVolume");
+
+
+ // Constructors
+
+ //- from components
+ objectiveTopOSolidVolume
+ (
+ const fvMesh& mesh,
+ const dictionary& dict,
+ const word& adjointSolverName,
+ const word& primalSolverName
+ );
+
+
+ //- Destructor
+ virtual ~objectiveTopOSolidVolume() = default;
+
+
+ // Member Functions
+
+ //- Return the objective function value
+ scalar J();
+
+ //- Contribution to field sensitivities
+ virtual void update_dJdb();
+
+ // Helper write functions
+
+ //- Write headers for additional columns
+ virtual void addHeaderColumns() const;
+
+ //- Write information to additional columns
+ virtual void addColumnValues() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace objectives
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.C b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.C
new file mode 100644
index 0000000000..d15b68e3df
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.C
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2023 PCOpt/NTUA
+ Copyright (C) 2013-2023 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "objectiveTopOVolume.H"
+#include "createZeroField.H"
+#include "IOmanip.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace objectives
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(objectiveTopOVolume, 1);
+addToRunTimeSelectionTable
+(
+ objectiveGeometric,
+ objectiveTopOVolume,
+ dictionary
+);
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+objectiveTopOVolume::objectiveTopOVolume
+(
+ const fvMesh& mesh,
+ const dictionary& dict,
+ const word& adjointSolverName,
+ const word& primalSolverName
+)
+:
+ objectiveGeometric(mesh, dict, adjointSolverName, primalSolverName),
+ targetPercentage_(Function1::New("percentage", dict)),
+ percentInDenom_(dict.getOrDefault("percentInDenom", true))
+{
+ // Allocate boundary field pointers
+ dJdbPtr_.reset(createZeroFieldPtr(mesh_, "dJdb", dimless));
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+
+scalar objectiveTopOVolume::J()
+{
+ J_ = Zero;
+ if (mesh_.foundObject("beta"))
+ {
+ const volScalarField& beta = mesh_.lookupObject("beta");
+ const DimensionedField& V = mesh_.V();
+ const scalar time = mesh_.time().timeOutputValue();
+ J_ =
+ scalar(1) - gSum(beta.primitiveField()*V)/gSum(V)
+ - targetPercentage_->value(time);
+ if (percentInDenom_)
+ {
+ J_ /= targetPercentage_->value(time);
+ }
+ }
+ else
+ {
+ WarningInFunction
+ << "Beta field not yet registered in database. OK for start-up"
+ << endl;
+ }
+ return J_;
+}
+
+
+void objectiveTopOVolume::update_dJdb()
+{
+ const scalar time = mesh_.time().timeOutputValue();
+ dJdbPtr_().primitiveFieldRef() = -scalar(1)/gSum(mesh_.V());
+ if (percentInDenom_)
+ {
+ dJdbPtr_().primitiveFieldRef() /= targetPercentage_->value(time);
+ }
+}
+
+
+void objectiveTopOVolume::addHeaderColumns() const
+{
+ objFunctionFilePtr_()
+ << setw(width_) << "TargetVolume" << " ";
+}
+
+
+void objectiveTopOVolume::addColumnValues() const
+{
+ const scalar time = mesh_.time().timeOutputValue();
+ objFunctionFilePtr_()
+ << setw(width_) << targetPercentage_->value(time) << " ";
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace objectives
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.H b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.H
new file mode 100644
index 0000000000..3c494c200a
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/objectives/geometric/objectiveTopOVolume/objectiveTopOVolume.H
@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2023 PCOpt/NTUA
+ Copyright (C) 2013-2023 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 .
+
+
+Class
+ Foam::objectives::objectiveTopOVolume
+
+Description
+ Objective quantifying the difference between the volume occupied by fluid
+ in topology optimisation and a target percentage; the latter can change
+ throughout the optimisation cycles through a Function1.
+
+SourceFiles
+ objectiveTopOVolume.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef objectiveTopOVolume_H
+#define objectiveTopOVolume_H
+
+#include "objectiveGeometric.H"
+#include "Function1.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+namespace objectives
+{
+
+/*---------------------------------------------------------------------------*\
+ Class objectiveTopOVolume Declaration
+\*---------------------------------------------------------------------------*/
+
+class objectiveTopOVolume
+:
+ public objectiveGeometric
+{
+ // Private data
+
+ autoPtr> targetPercentage_;
+
+ bool percentInDenom_;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("topOVolume");
+
+
+ // Constructors
+
+ //- from components
+ objectiveTopOVolume
+ (
+ const fvMesh& mesh,
+ const dictionary& dict,
+ const word& adjointSolverName,
+ const word& primalSolverName
+ );
+
+
+ //- Destructor
+ virtual ~objectiveTopOVolume() = default;
+
+
+ // Member Functions
+
+ //- Return the objective function value
+ scalar J();
+
+ //- Contribution to field sensitivities
+ virtual void update_dJdb();
+
+ // Helper write functions
+
+ //- Write headers for additional columns
+ virtual void addHeaderColumns() const;
+
+ //- Write information to additional columns
+ virtual void addColumnValues() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace objectives
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.C b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.C
new file mode 100644
index 0000000000..1d5ea4a0df
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.C
@@ -0,0 +1,233 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2023 PCOpt/NTUA
+ Copyright (C) 2013-2023 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "adjointSensitivity.H"
+#include "sensitivityTopO.H"
+#include "adjointSolver.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(sensitivityTopO, 0);
+addToRunTimeSelectionTable(adjointSensitivity, sensitivityTopO, dictionary);
+
+
+// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
+
+void sensitivityTopO::zeroSensInFixedPorousZones(scalarField& sens)
+{
+ const labelList& adjointPorousIDs = zones_.adjointPorousZoneIDs();
+ if (adjointPorousIDs.empty())
+ {
+ for (label cellZoneID : zones_.fixedPorousZoneIDs())
+ {
+ const labelList& zoneCells = mesh_.cellZones()[cellZoneID];
+ for (label cellI : zoneCells)
+ {
+ sens[cellI] = 0.;
+ }
+ }
+ for (label cellZoneID : zones_.fixedZeroPorousZoneIDs())
+ {
+ const labelList& zoneCells = mesh_.cellZones()[cellZoneID];
+ for (label cellI : zoneCells)
+ {
+ sens[cellI] = 0.;
+ }
+ }
+ for (label cellI : zones_.IOCells())
+ {
+ sens[cellI] = 0.;
+ }
+ }
+ else
+ {
+ // if adjointPorousZones are not empty, zero sensitivities in all cells
+ // not within them
+ scalarField mask(sens.size(), Zero);
+ for (label cellZoneID : adjointPorousIDs)
+ {
+ const labelList& zoneCells = mesh_.cellZones()[cellZoneID];
+ for (label cellI : zoneCells)
+ {
+ mask[cellI] = 1.;
+ }
+ }
+ sens *= mask;
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+sensitivityTopO::sensitivityTopO
+(
+ const fvMesh& mesh,
+ const dictionary& dict,
+ adjointSolver& adjointSolver
+)
+:
+ adjointSensitivity(mesh, dict, adjointSolver),
+ zones_(mesh, dict.parent()),
+ designVariablesName_("beta")
+{
+ if (includeDistance_)
+ {
+ eikonalSolver_.reset
+ (
+ new adjointEikonalSolver
+ (
+ mesh_,
+ dict_,
+ adjointSolver,
+ labelHashSet(0)
+ )
+ );
+ }
+ // Allocate sensitivities field
+ fieldSensPtr_.reset
+ (
+ createZeroFieldPtr
+ (
+ mesh_,
+ "topologySens" + adjointSolver.solverName(),
+ pow5(dimLength)/sqr(dimTime)
+ )
+ );
+
+ // Set return field size
+ derivatives_ = scalarField(mesh_.nCells(), Zero);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool sensitivityTopO::readDict(const dictionary& dict)
+{
+ if (adjointSensitivity::readDict(dict))
+ {
+ if (includeDistance_)
+ {
+ if (eikonalSolver_)
+ {
+ eikonalSolver_->readDict(dict);
+ }
+ else
+ {
+ eikonalSolver_.reset
+ (
+ new adjointEikonalSolver
+ (
+ mesh_,
+ dict_,
+ adjointSolver_,
+ labelHashSet(0)
+ )
+ );
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void sensitivityTopO::accumulateIntegrand(const scalar dt)
+{
+ // Accumulate source for additional post-processing PDEs, if necessary
+ if (eikonalSolver_)
+ {
+ eikonalSolver_->accumulateIntegrand(dt);
+ }
+
+ adjointSolver_.topOSensMultiplier
+ (fieldSensPtr_().primitiveFieldRef(), designVariablesName_, dt);
+}
+
+
+void sensitivityTopO::assembleSensitivities
+(
+ autoPtr& designVars
+)
+{
+ scalarField& sens = fieldSensPtr_().primitiveFieldRef();
+ if (eikonalSolver_)
+ {
+ eikonalSolver_->solve();
+ sens += eikonalSolver_->topologySensitivities(designVariablesName_);
+ }
+ zeroSensInFixedPorousZones(sens);
+
+ adjointSensitivity::assembleSensitivities(designVars);
+}
+
+
+void sensitivityTopO::postProcessSens
+(
+ scalarField& sens,
+ scalarField& auxSens,
+ fv::options& fvOptions,
+ const word& fieldName,
+ const word& designVariablesName
+)
+{
+ if (fvOptions.appliesToField(fieldName))
+ {
+ DebugInfo
+ << "Computing SD contributions from the interpolation of "
+ << fieldName << endl;
+ fvOptions.postProcessSens(auxSens, fieldName, designVariablesName);
+ sens += auxSens;
+ }
+}
+
+
+void sensitivityTopO::postProcessSens
+(
+ scalarField& sens,
+ scalarField& auxSens,
+ const word& fieldName
+)
+{
+ fv::options& fvOptions(fv::options::New(this->mesh_));
+ postProcessSens(sens, auxSens, fvOptions, fieldName, designVariablesName_);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.H b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.H
new file mode 100644
index 0000000000..49334457e5
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopO.H
@@ -0,0 +1,173 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2007-2020 PCOpt/NTUA
+ Copyright (C) 2013-2020 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 .
+
+
+Description
+ Calculation of adjoint based sensitivities for topology optimisation.
+ This returns just the field part, with contributions from regularisation
+ and projection added by topODesignVariables.
+
+Class
+ Foam::sensitivityTopO
+
+SourceFiles
+ sensitivityTopO.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sensitivityTopO_H
+#define sensitivityTopO_H
+
+#include "adjointSensitivity.H"
+#include "fvOptions.H"
+#include "topOZones.H"
+#include "adjointEikonalSolver.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class sensitivityTopO Declaration
+\*---------------------------------------------------------------------------*/
+
+class sensitivityTopO
+:
+ public adjointSensitivity
+{
+
+protected:
+
+ // Protected data
+
+ //- Zones related to topology optimisation
+ topOZones zones_;
+
+ //- Name used as the argument for the post-processing of the
+ //- sensitivities through fvOptions
+ word designVariablesName_;
+
+
+ // Protected Member Functions
+
+ //- Zero sensitivities in fixed porous zones
+ void zeroSensInFixedPorousZones(scalarField& sens);
+
+
+private:
+
+ // Private Member Functions
+
+ //- No copy construct
+ sensitivityTopO(const sensitivityTopO&);
+
+ //- No copy assignment
+ void operator=(const sensitivityTopO&);
+
+
+public:
+
+ //- Runtime type information
+ TypeName("topO");
+
+
+ // Constructors
+
+ //- Construct from components
+ sensitivityTopO
+ (
+ const fvMesh& mesh,
+ const dictionary& dict,
+ adjointSolver& adjointSolver
+ );
+
+
+ //- Destructor
+ virtual ~sensitivityTopO() = default;
+
+
+ // Member Functions
+
+ //- Read dictionary if changed
+ virtual bool readDict(const dictionary& dict);
+
+ //- Accumulate sensitivity integrands
+ virtual void accumulateIntegrand(const scalar dt);
+
+ //- Assemble sensitivities
+ virtual void assembleSensitivities
+ (
+ autoPtr& designVars
+ );
+
+ //- Add part of the sensitivities coming from fvOptions
+ static void postProcessSens
+ (
+ scalarField& sens,
+ scalarField& auxSens,
+ fv::options& fvOptions,
+ const word& fieldName,
+ const word& designVariablesName
+ );
+
+ //- Add part of the sensitivities coming from fvOptions
+ void postProcessSens
+ (
+ scalarField& sens,
+ scalarField& auxSens,
+ const word& fieldName
+ );
+
+ //- Potentially manipulate auxSens within the fvOption before adding
+ //- the part related to the design variables
+ template class PatchField, class GeoMesh>
+ static void postProcessAuxSens
+ (
+ const GeometricField& primal,
+ const GeometricField& adjoint,
+ fv::options& fvOptions,
+ const word& fieldName,
+ scalarField& auxSens
+ );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "sensitivityTopOTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopOTemplates.C b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopOTemplates.C
new file mode 100644
index 0000000000..8279d6b203
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/adjointSensitivity/adjointSensitivity/topO/sensitivityTopOTemplates.C
@@ -0,0 +1,51 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template class PatchField, class GeoMesh>
+void Foam::sensitivityTopO::postProcessAuxSens
+(
+ const GeometricField& primal,
+ const GeometricField& adjoint,
+ fv::options& fvOptions,
+ const word& fieldName,
+ scalarField& auxSens
+)
+{
+ if (fvOptions.appliesToField(fieldName))
+ {
+ DebugInfo
+ << "Manupulation auxiliary SD contributions from field "
+ << fieldName << endl;
+ fvOptions.postProcessAuxSens(primal, adjoint, auxSens, fieldName);
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/src/optimisation/adjointOptimisation/adjoint/optimisation/designVariables/levelSet/interpolationFunctions/sigmoidalHeaviside/sigmoidalHeaviside.C b/src/optimisation/adjointOptimisation/adjoint/optimisation/designVariables/levelSet/interpolationFunctions/sigmoidalHeaviside/sigmoidalHeaviside.C
new file mode 100644
index 0000000000..dfa06943f5
--- /dev/null
+++ b/src/optimisation/adjointOptimisation/adjoint/optimisation/designVariables/levelSet/interpolationFunctions/sigmoidalHeaviside/sigmoidalHeaviside.C
@@ -0,0 +1,134 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "sigmoidalHeaviside.H"
+#include "mathematicalConstants.H"
+#include "volFields.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(sigmoidalHeaviside, 1);
+addToRunTimeSelectionTable
+(
+ topOInterpolationFunction,
+ sigmoidalHeaviside,
+ dictionary
+);
+
+// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
+
+scalar sigmoidalHeaviside::computeNearBandWidth() const
+{
+ scalar averageVol(gAverage(mesh_.V().field()));
+ const Vector