Commit ecc1fb5e authored by Vaggelis Papoutsis's avatar Vaggelis Papoutsis Committed by Andrew Heather
Browse files

CONTRIB: New adjoint optimisation and tools

A set of libraries and executables creating a workflow for performing
gradient-based optimisation loops. The main executable (adjointOptimisationFoam)
solves the flow (primal) equations, followed by the adjoint equations and,
eventually, the computation of sensitivity derivatives.

Current functionality supports the solution of the adjoint equations for
incompressible turbulent flows, including the adjoint to the Spalart-Allmaras
turbulence model and the adjoint to the nutUSpaldingWallFunction, [1], [2].

Sensitivity derivatives are computed with respect to the normal displacement of
boundary wall nodes/faces (the so-called sensitivity maps) following the
Enhanced Surface Integrals (E-SI) formulation, [3].

The software was developed by PCOpt/NTUA and FOSS GP, with contributions from

Dr. Evangelos Papoutsis-Kiachagias,
Konstantinos Gkaragounis,
Professor Kyriakos Giannakoglou,
Andy Heather

and contributions in earlier version from

Dr. Ioannis Kavvadias,
Dr. A...
parent 56547863
adjointOptimisationFoam.C
EXE = $(FOAM_APPBIN)/adjointOptimisationFoam
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-ladjointOptimisation
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2007-2019 PCOpt/NTUA
| Copyright (C) 2013-2019 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/>.
Application
adjointOptimisation
Description
An automated adjoint-based optimisation loop. Supports multiple types
of optimisation (shape, topology etc)
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "optimisationManager.H"
#include "primalSolver.H"
#include "adjointSolverManager.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
for (om++; !om.end(); om++)
{
Info<< "* * * * * * * * * * * * * * * * * * *" << endl;
Info<< "Time = " << runTime.timeName() << endl;
Info<< "* * * * * * * * * * * * * * * * * * *" << endl;
if (om.update())
{
// Update design variables and solve all primal equations
om.updateDesignVariables();
}
else
{
// Solve all primal equations
om.solvePrimalEquations();
}
// Update primal-based quantities of the adjoint solvers
om.updatePrimalBasedQuantities();
// Solve all adjoint equations
om.solveAdjointEquations();
// Compute all sensitivities
om.computeSensitivities();
}
Info<< "End\n" << endl;
return(0);
}
// ************************************************************************* //
// Construct optimisation manager
autoPtr<optimisationManager> optManagerPtr
(
optimisationManager::New(mesh)
);
optimisationManager& om = optManagerPtr();
computeSensitivities.C
EXE = $(FOAM_APPBIN)/computeSensitivities
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-lturbulenceModels \
-lincompressibleTransportModels \
-lincompressibleTurbulenceModels \
-lfileFormats \
-lsurfMesh \
-ladjointOptimisation
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2007-2019 PCOpt/NTUA
| Copyright (C) 2013-2019 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/>.
Application
computeSensitivities
Description
Computes the sensitivities wrt what is defined in the optimisationDict
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "optimisationManager.H"
#include "primalSolver.H"
#include "adjointSolver.H"
#include "incompressibleVars.H"
#include "incompressibleAdjointVars.H"
#include "adjointBoundaryCondition.H"
#include "adjointSolverManager.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
forAll(adjointSolverManagers, amI)
{
PtrList<adjointSolver>& adjointSolvers =
adjointSolverManagers[amI].adjointSolvers();
forAll(adjointSolvers, asI)
{
adjointSolvers[asI].getObjectiveManager().updateAndWrite();
adjointSolvers[asI].computeObjectiveSensitivities();
}
}
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
Info<< "End" << endl;
return(0);
}
// ************************************************************************* //
// Construct optimisation manager
autoPtr<optimisationManager> optManagerPtr
(
optimisationManager::New(mesh)
);
optimisationManager& om = optManagerPtr();
PtrList<adjointSolverManager>& adjointSolverManagers =
om.adjointSolverManagers();
......@@ -73,6 +73,13 @@ cleanSnappyFiles()
}
cleanOptimisation()
{
rm -rf optimisation
rm -rf constant/controlPoints
}
cleanPostProcessing()
{
rm -rf Ensight EnSight ensightWrite insitu VTK > /dev/null 2>&1
......@@ -87,6 +94,7 @@ cleanCase()
cleanTimeDirectories
cleanPostProcessing
cleanDynamicCode
cleanOptimisation
rm -rf processor* > /dev/null 2>&1
rm -rf TDAC > /dev/null 2>&1
......
......@@ -107,6 +107,7 @@ wmake $targetType rigidBodyDynamics
wmake $targetType rigidBodyMeshMotion
wmake $targetType semiPermeableBaffle
wmake $targetType atmosphericModels
wmake $targetType optimisation/adjointOptimisation/adjoint
phaseSystemModels/Allwmake $targetType $*
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2007-2019 PCOpt/NTUA
| Copyright (C) 2013-2019 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 "ATCModel.H"
#include "localMin.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(ATCModel, 0);
defineRunTimeSelectionTable(ATCModel, dictionary);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void ATCModel::computeLimiter()
{
computeLimiter(ATClimiter_, zeroATCcells_->getZeroATCcells(), nSmooth_);
}
void ATCModel::smoothATC()
{
ATC_ *= ATClimiter_;
DebugInfo<<
"max ATC mag " << gMax(ATC_) << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
ATCModel::ATCModel
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
)
:
regIOobject
(
IOobject
(
"ATCModel" + adjointVars.solverName(),
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
)
),
mesh_(mesh),
primalVars_(primalVars),
adjointVars_(adjointVars),
dict_(dict),
extraConvection_(dict_.lookupOrDefault<scalar>("extraConvection", Zero)),
extraDiffusion_(dict_.lookupOrDefault<scalar>("extraDiffusion", Zero)),
nSmooth_(dict_.lookupOrDefault<label>("nSmooth", 0)),
reconstructGradients_
(
dict_.lookupOrDefault<bool>("reconstructGradients", false)
),
adjointSolverName_(adjointVars.solverName()),
zeroATCcells_(zeroATCcells::New(mesh, dict_)),
ATClimiter_
(
IOobject
(
"ATClimiter" + adjointSolverName_,
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar("limiter", dimless, 1.0),
zeroGradientFvPatchField<scalar>::typeName
),
ATC_
(
IOobject
(
"ATCField" + adjointSolverName_,
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedVector(dimensionSet(0, 1, -2, 0, 0), Zero)
)
{
// Compute ATC limiter
computeLimiter();
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<ATCModel> ATCModel::New
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
)
{
const word modelType(dict.get<word>("ATCModel"));
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
Info<< "ATCModel type " << modelType << endl;
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown ATCModel type " << modelType << nl << nl
<< "Valid ATCModel types are :" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return autoPtr<ATCModel>
(
cstrIter()(mesh, primalVars, adjointVars, dict)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const labelList& ATCModel::getZeroATCcells()
{
return zeroATCcells_->getZeroATCcells();
}
scalar ATCModel::getExtraConvectionMultiplier()
{
return extraConvection_;
}
scalar ATCModel::getExtraDiffusionMultiplier()
{
return extraDiffusion_;
}
const volScalarField& ATCModel::getLimiter() const
{
return ATClimiter_;
}
void ATCModel::computeLimiter
(
volScalarField& limiter,
const labelList& cells,
const label nSmooth
)
{
// Restore values
limiter.primitiveFieldRef() = 1;
limiter.correctBoundaryConditions();
// Set to zero in predefined cells
for (const label celli : cells)
{
limiter[celli] = Zero;
}
// Correct bcs to get the correct value for boundary faces
limiter.correctBoundaryConditions();
// Apply "laplacian" smoother
const fvMesh& mesh = limiter.mesh();
const localMin<scalar> scheme(mesh);
for (label iLimit = 0; iLimit < nSmooth; ++iLimit)
{
surfaceScalarField faceLimiter
(
scheme.interpolate(limiter)
);
limiter = fvc::average(faceLimiter);
}
}
tmp<volScalarField> ATCModel::createLimiter
(
const fvMesh& mesh,
const dictionary& dict
)
{
autoPtr<zeroATCcells> zeroType(zeroATCcells::New(mesh, dict));
const labelList& zeroCells = zeroType->getZeroATCcells();
const label nSmooth = dict.lookupOrDefault<label>("nSmooth", 0);
tmp<volScalarField> tlimiter
(
new volScalarField
(
IOobject
(
"limiter",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("limiter", dimless, 1.0),
zeroGradientFvPatchField<scalar>::typeName
)
);
volScalarField& limiter = tlimiter.ref();
computeLimiter(limiter, zeroCells, nSmooth);
return tlimiter;
}
bool ATCModel::writeData(Ostream&) const
{
// Does nothing
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2007-2019 PCOpt/NTUA
| Copyright (C) 2013-2019 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::ATCModel
Description
Base class for selecting the adjoint transpose convection model.
Inherits from regIOobject to add lookup functionality
SourceFiles
ATCModel.C
\*---------------------------------------------------------------------------*/
#ifndef ATCModel_H
#define ATCModel_H
#include "regIOobject.H"
#include "autoPtr.H"
#include "zeroATCcells.H"
#include "incompressibleVars.H"
#include "incompressibleAdjointVars.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ATCModel Declaration
\*---------------------------------------------------------------------------*/
class ATCModel
: