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. Alexandros Zymaris,
Dr. Dimitrios Papadimitriou

[1] A.S. Zymaris, D.I. Papadimitriou, K.C. Giannakoglou, and C. Othmer.
Continuous adjoint approach to the Spalart-Allmaras turbulence model for
incompressible flows. Computers & Fluids, 38(8):1528–1538, 2009.

[2] E.M. Papoutsis-Kiachagias and K.C. Giannakoglou. Continuous adjoint methods
for turbulent flows, applied to shape and topology optimization: Industrial
applications. 23(2):255–299, 2016.

[3] I.S. Kavvadias, E.M. Papoutsis-Kiachagias, and K.C. Giannakoglou. On the
proper treatment of grid sensitivities in continuous adjoint methods for shape
optimization. Journal of Computational Physics, 301:1–18, 2015.

Integration into the official OpenFOAM release by OpenCFD
This commit is contained in:
Vaggelis Papoutsis
2019-06-17 12:59:11 +01:00
committed by Andrew Heather
parent 56547863c1
commit ecc1fb5efb
435 changed files with 41046 additions and 0 deletions

View File

@ -0,0 +1,3 @@
adjointOptimisationFoam.C
EXE = $(FOAM_APPBIN)/adjointOptimisationFoam

View File

@ -0,0 +1,21 @@
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

View File

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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);
}
// ************************************************************************* //

View File

@ -0,0 +1,6 @@
// Construct optimisation manager
autoPtr<optimisationManager> optManagerPtr
(
optimisationManager::New(mesh)
);
optimisationManager& om = optManagerPtr();

View File

@ -0,0 +1,3 @@
computeSensitivities.C
EXE = $(FOAM_APPBIN)/computeSensitivities

View File

@ -0,0 +1,23 @@
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

View File

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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);
}
// ************************************************************************* //

View File

@ -0,0 +1,9 @@
// Construct optimisation manager
autoPtr<optimisationManager> optManagerPtr
(
optimisationManager::New(mesh)
);
optimisationManager& om = optManagerPtr();
PtrList<adjointSolverManager>& adjointSolverManagers =
om.adjointSolverManagers();

View File

@ -73,6 +73,13 @@ cleanSnappyFiles()
} }
cleanOptimisation()
{
rm -rf optimisation
rm -rf constant/controlPoints
}
cleanPostProcessing() cleanPostProcessing()
{ {
rm -rf Ensight EnSight ensightWrite insitu VTK > /dev/null 2>&1 rm -rf Ensight EnSight ensightWrite insitu VTK > /dev/null 2>&1
@ -87,6 +94,7 @@ cleanCase()
cleanTimeDirectories cleanTimeDirectories
cleanPostProcessing cleanPostProcessing
cleanDynamicCode cleanDynamicCode
cleanOptimisation
rm -rf processor* > /dev/null 2>&1 rm -rf processor* > /dev/null 2>&1
rm -rf TDAC > /dev/null 2>&1 rm -rf TDAC > /dev/null 2>&1

View File

@ -107,6 +107,7 @@ wmake $targetType rigidBodyDynamics
wmake $targetType rigidBodyMeshMotion wmake $targetType rigidBodyMeshMotion
wmake $targetType semiPermeableBaffle wmake $targetType semiPermeableBaffle
wmake $targetType atmosphericModels wmake $targetType atmosphericModels
wmake $targetType optimisation/adjointOptimisation/adjoint
phaseSystemModels/Allwmake $targetType $* phaseSystemModels/Allwmake $targetType $*

View File

@ -0,0 +1,263 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
// ************************************************************************* //

View File

@ -0,0 +1,220 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
:
public regIOobject
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
ATCModel(const ATCModel&) = delete;
//- Disallow default bitwise assignment
void operator=(const ATCModel&) = delete;
protected:
// Protected data
const fvMesh& mesh_;
const incompressibleVars& primalVars_;
const incompressibleAdjointVars& adjointVars_;
const dictionary& dict_;
const scalar extraConvection_;
const scalar extraDiffusion_;
const label nSmooth_;
const bool reconstructGradients_;
word adjointSolverName_;
autoPtr<zeroATCcells> zeroATCcells_;
volScalarField ATClimiter_;
volVectorField ATC_;
// Protected functions
//- Compute limiter based on the cells given by zeroATCcells
void computeLimiter();
//- Limit ATC field using ATClimiter_
void smoothATC();
public:
//- Runtime type information
TypeName("ATCModel");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
ATCModel,
dictionary,
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
),
(mesh, primalVars, adjointVars, dict)
);
// Constructors
//- Construct from components
ATCModel
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<ATCModel> New
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
);
//- Destructor
virtual ~ATCModel() = default;
// Member Functions
//- Add ATC to the given matrix
virtual void addATC(fvVectorMatrix& UaEqn) = 0;
//- Get the list of cells on which to zero ATC
const labelList& getZeroATCcells();
//- Get the extra convection multiplier
scalar getExtraConvectionMultiplier();
//- Get the extra diffusion multiplier
scalar getExtraDiffusionMultiplier();
//- Get the list of cells on which to zero ATC
const volScalarField& getLimiter() const;
//- Compute limiter based on the prescribed cells and number of
//- smoothing iterations
static void computeLimiter
(
volScalarField& limiter,
const labelList& smoothCells,
const label nSmooth
);
//- Return a limiter based on given cells.
//- For use with classes other than ATC which employ the same smoothing
//- mechanism
static tmp<volScalarField> createLimiter
(
const fvMesh& mesh,
const dictionary& dict
);
//- Smooth an arbitrary field on a given list of cells
template<class Type>
void smoothFieldBasedOnCells
(
GeometricField<Type, fvPatchField, volMesh>& vf,
const labelList& cells
);
//- Get the FI sensitivity derivatives term coming from the ATC
virtual tmp<volTensorField> getFISensitivityTerm() const = 0;
//- Dummy writeData function required from regIOobject
virtual bool writeData(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "ATCModelTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "zeroGradientFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::ATCModel::smoothFieldBasedOnCells
(
GeometricField<Type, fvPatchField, volMesh>& vf,
const labelList& cells
)
{
volScalarField limiter
(
IOobject
(
vf.name() + "Limiter",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedScalar("limiter", dimless, 1.0),
zeroGradientFvPatchField<scalar>::typeName
);
computeLimiter(limiter, cells, nSmooth_);
//Limit actual field
vf *= limiter;
}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ATCUaGradU.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(ATCUaGradU, 0);
addToRunTimeSelectionTable
(
ATCModel,
ATCUaGradU,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
ATCUaGradU::ATCUaGradU
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
)
:
ATCModel(mesh, primalVars, adjointVars, dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void ATCUaGradU::addATC(fvVectorMatrix& UaEqn)
{
const volVectorField& U = primalVars_.U();
const volVectorField& Ua = adjointVars_.UaInst();
const surfaceScalarField& phi = primalVars_.phi();
const surfaceScalarField& phia = adjointVars_.phiaInst();
// Build Ua to go into the ATC term, based on whether to smooth field or not
autoPtr<volVectorField> UaForATC(nullptr);
if (reconstructGradients_)
{
UaForATC.reset(new volVectorField(fvc::reconstruct(phia)));
}
else
{
UaForATC.reset(new volVectorField(Ua));
}
// Main ATC term
ATC_ = -fvc::grad(UaForATC(), "gradUaATC") & U;
if (extraConvection_ > 0)
{
// Implicit part added to increase diagonal dominance
// Note: Maybe this needs to be multiplied with the ATClimiter ??
UaEqn += extraConvection_*fvm::div(-phi, Ua);
// correct rhs due to implicitly augmenting the adjoint convection
ATC_ += extraConvection_*(fvc::grad(UaForATC(), "gradUaATC")().T() & U);
}
// Zero ATC on cells next to given patch types
smoothATC();
// Actual ATC term
UaEqn += fvm::Su(ATC_, Ua);
}
tmp<volTensorField> ATCUaGradU::getFISensitivityTerm() const
{
tmp<volTensorField> tvolSDTerm
(
new volTensorField
(
IOobject
(
"ATCFISensitivityTerm" + type(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedTensor(sqr(dimLength)/pow(dimTime, 3), Zero)
)
);
volTensorField& volSDTerm = tvolSDTerm.ref();
const volVectorField& U = primalVars_.U();
const volVectorField& Ua = adjointVars_.Ua();
//const volScalarField& mask = getLimiter();
volSDTerm -=
Ua.component(0) * fvc::grad(U.component(0) * U)
+ Ua.component(1) * fvc::grad(U.component(1) * U)
+ Ua.component(2) * fvc::grad(U.component(2) * U);
return tvolSDTerm;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,109 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::ATCUaGradU
Description
The ATC formualtion resulting by differentiating the
Conservative form of the Momentum equations.
SourceFiles
ATCUaGradU.C
\*---------------------------------------------------------------------------*/
#ifndef ATCUaGradU_H
#define ATCUaGradU_H
#include "ATCModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ATCUaGradU Declaration
\*---------------------------------------------------------------------------*/
class ATCUaGradU
:
public ATCModel
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
ATCUaGradU(const ATCUaGradU&) = delete;
//- Disallow default bitwise assignment
void operator=(const ATCUaGradU&) = delete;
public:
//- Runtime type information
TypeName("UaGradU");
// Constructors
//- Construct from components
ATCUaGradU
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
);
//- Destructor
virtual ~ATCUaGradU() = default;
// Member Functions
//- Add ATC
virtual void addATC(fvVectorMatrix& UaEqn);
//- Get the FI sensitivity derivatives term coming from the ATC
virtual tmp<volTensorField> getFISensitivityTerm() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "ATCstandard.H"
#include "addToRunTimeSelectionTable.H"
#include "wallFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(ATCstandard, 0);
addToRunTimeSelectionTable
(
ATCModel,
ATCstandard,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
ATCstandard::ATCstandard
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
)
:
ATCModel(mesh, primalVars, adjointVars, dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void ATCstandard::addATC(fvVectorMatrix& UaEqn)
{
const volVectorField& U = primalVars_.U();
const volVectorField& Ua = adjointVars_.UaInst();
const surfaceScalarField& phi = primalVars_.phi();
// Build U to go into the ATC term, based on whether to smooth field or not
autoPtr<volVectorField> UForATC(nullptr);
if (reconstructGradients_)
{
UForATC.reset(new volVectorField(fvc::reconstruct(phi)));
}
else
{
UForATC.reset(new volVectorField(U));
}
// Main ATC term
ATC_ = (fvc::grad(UForATC(), "gradUATC") & Ua);
if (extraConvection_ > 0)
{
// Implicit part added to increase diagonal dominance
// Note: Maybe this needs to be multiplied with the ATClimiter ??
UaEqn += extraConvection_*fvm::div(-phi, Ua);
// correct rhs due to implicitly augmenting the adjoint convection
ATC_ += extraConvection_*(fvc::grad(Ua, "gradUaATC")().T() & U);
}
//zero ATC on cells next to given patch types
smoothATC();
// actual ATC term
UaEqn += fvm::Su(ATC_, Ua);
}
tmp<volTensorField> ATCstandard::getFISensitivityTerm() const
{
tmp<volTensorField> tvolSDTerm
(
new volTensorField
(
IOobject
(
"ATCFISensitivityTerm" + type(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedTensor(sqr(dimLength)/pow(dimTime, 3), Zero)
)
);
volTensorField& volSDTerm = tvolSDTerm.ref();
const volVectorField& U = primalVars_.U();
const volVectorField& Ua = adjointVars_.Ua();
volTensorField gradU(fvc::grad(U));
// Explicitly correct the boundary gradient to get rid of the
// tangential component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
gradU.boundaryFieldRef()[patchI] =
nf*U.boundaryField()[patchI].snGrad();
}
}
const volScalarField& mask = getLimiter();
volSDTerm = -(gradU & Ua)*U*mask;
return tvolSDTerm;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,109 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::ATCstandard
Description
The ATC formualtion resulting by differentiating the
Non-conservative form of the momentum equations.
SourceFiles
ATCstandard.C
\*---------------------------------------------------------------------------*/
#ifndef ATCstandard_H
#define ATCstandard_H
#include "ATCModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ATCstandard Declaration
\*---------------------------------------------------------------------------*/
class ATCstandard
:
public ATCModel
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
ATCstandard(const ATCstandard&) = delete;
//- Disallow default bitwise assignment
void operator=(const ATCstandard&) = delete;
public:
//- Runtime type information
TypeName("standard");
// Constructors
//- Construct from components
ATCstandard
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
);
//- Destructor
virtual ~ATCstandard() = default;
// Member Functions
//- Add ATC
virtual void addATC(fvVectorMatrix& UaEqn);
//- Get the FI sensitivity derivatives term coming from the ATC
virtual tmp<volTensorField> getFISensitivityTerm() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "cancelATC.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(cancelATC, 0);
addToRunTimeSelectionTable
(
ATCModel,
cancelATC,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
cancelATC::cancelATC
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
)
:
ATCModel(mesh, primalVars, adjointVars, dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void cancelATC::addATC(fvVectorMatrix& UaEqn)
{
// Do nothing
}
tmp<volTensorField> cancelATC::getFISensitivityTerm() const
{
return
tmp<volTensorField>::New
(
IOobject
(
"ATCFISensitivityTerm" + type(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedTensor(sqr(dimLength)/pow3(dimTime), Zero)
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::cancelATC
Description
Return a zero ATC field. Seriously influences computed sensitivities
SourceFiles
cancelATC.C
\*---------------------------------------------------------------------------*/
#ifndef cancelATC_H
#define cancelATC_H
#include "ATCModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
class cancelATC
:
public ATCModel
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
cancelATC(const cancelATC&) = delete;
//- Disallow default bitwise assignment
void operator=(const cancelATC&) = delete;
public:
//- Runtime type information
TypeName("cancel");
// Constructors
//- Construct from components
cancelATC
(
const fvMesh& mesh,
const incompressibleVars& primalVars,
const incompressibleAdjointVars& adjointVars,
const dictionary& dict
);
//- Destructor
virtual ~cancelATC() = default;
// Member Functions
//- Add ATC
virtual void addATC(fvVectorMatrix& UaEqn);
//- Get the FI sensitivity derivatives term coming from the ATC
virtual tmp<volTensorField> getFISensitivityTerm() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "faceCells.H"
#include "fvMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(faceCells, 0);
addToRunTimeSelectionTable(zeroATCcells, faceCells, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
faceCells::faceCells
(
const fvMesh& mesh,
const dictionary& dict
)
:
zeroATCcells(mesh, dict)
{
for (const fvPatch& patch : mesh_.boundary())
{
for (const word& patchType : zeroATCPatches_)
{
if (patch.type() == patchType)
{
const labelList& faceCells_ = patch.faceCells();
zeroATCcells_.append(faceCells_);
}
}
}
for (const label zoneID: zeroATCZones_)
{
if (zoneID !=-1)
{
const labelList& zoneCells = mesh_.cellZones()[zoneID];
zeroATCcells_.append(zoneCells);
}
}
label size = zeroATCcells_.size();
reduce(size, sumOp<label>());
Info<< "Setting limiter on " << size << " cells" << nl << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::faceCells
Description
Smooth ATC in cells next to a set of patches supplied by type
SourceFiles
faceCells.C
\*---------------------------------------------------------------------------*/
#ifndef faceCells_H
#define faceCells_H
#include "zeroATCcells.H"
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
class faceCells
:
public zeroATCcells
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
faceCells(const faceCells&) = delete;
//- Disallow default bitwise assignment
void operator=(const faceCells&) = delete;
public:
//- Runtime type information
TypeName("faceCells");
// Constructors
//- Construct from components
faceCells
(
const fvMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~faceCells() = default;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "pointCells.H"
#include "fvMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(pointCells, 0);
addToRunTimeSelectionTable(zeroATCcells, pointCells, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
pointCells::pointCells
(
const fvMesh& mesh,
const dictionary& dict
)
:
zeroATCcells(mesh, dict)
{
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
for (const word& patchType : zeroATCPatches_)
{
if (patch.type() == patchType)
{
const labelList& meshPoints =
mesh_.boundaryMesh()[patchI].meshPoints();
for (const label pointI : meshPoints)
{
const labelList& pointCells = mesh_.pointCells()[pointI];
zeroATCcells_.append(pointCells);
}
}
}
}
forAll(zeroATCZones_, zI)
{
const label& zoneID = zeroATCZones_[zI];
if (zoneID != -1)
{
const labelList& zoneCells = mesh_.cellZones()[zoneID];
zeroATCcells_.append(zoneCells);
}
}
/*
label size = zeroATCcells_.size();
reduce(size, sumOp<label>());
Info<< "Zeroing ATC on "<< size << " cells" << nl << endl;
*/
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,100 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::pointCells
Description
Smooth ATC in cells having a point to a set of patches supplied by type
SourceFiles
pointCells.C
\*---------------------------------------------------------------------------*/
#ifndef pointCells_H
#define pointCells_H
#include "zeroATCcells.H"
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
class pointCells
:
public zeroATCcells
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
pointCells(const pointCells&) = delete;
//- Disallow default bitwise assignment
void operator=(const pointCells&) = delete;
public:
//- Runtime type information
TypeName("pointCells");
// Constructors
//- Construct from components
pointCells
(
const fvMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~pointCells() = default;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "zeroATCcells.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(zeroATCcells, 0);
defineRunTimeSelectionTable(zeroATCcells, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
zeroATCcells::zeroATCcells
(
const fvMesh& mesh,
const dictionary& dict
)
:
mesh_(mesh),
zeroATCPatches_
(
dict.lookupOrDefault<wordList>("zeroATCPatchTypes", wordList())
),
zeroATCZones_(0),
zeroATCcells_(0)
{
if (dict.found("zeroATCZones"))
{
const wordList zeroATCZoneNames(dict.get<wordList>("zeroATCZones"));
zeroATCZones_ = labelList(zeroATCZoneNames.size(), -1);
forAll(zeroATCZoneNames, zI)
{
label zoneID = mesh.cellZones().findZoneID(zeroATCZoneNames[zI]);
if (zoneID == -1)
{
WarningInFunction
<< "cannot find cellZone "
<< zeroATCZoneNames[zI]
<< " for smoothing ATC"
<< endl;
}
zeroATCZones_[zI] = zoneID;
}
}
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<zeroATCcells> zeroATCcells::New
(
const fvMesh& mesh,
const dictionary& dict
)
{
const word modelType
(
dict.lookupOrDefault<word>("maskType", "faceCells")
);
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown zeroATCcells type " << modelType << nl << nl
<< "Valid zeroATCcells types are :" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return autoPtr<zeroATCcells> (cstrIter()(mesh,dict));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::zeroATCcells
Description
Base class for selecting cells on which to zero the ATC term
SourceFiles
zeroATCcells.C
\*---------------------------------------------------------------------------*/
#ifndef zeroATCcells_H
#define zeroATCcells_H
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class adjointTurbulenceModel Declaration
\*---------------------------------------------------------------------------*/
class zeroATCcells
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
zeroATCcells(const zeroATCcells&) = delete;
//- Disallow default bitwise assignment
void operator=(const zeroATCcells&) = delete;
protected:
// Protected data
const fvMesh& mesh_;
wordList zeroATCPatches_;
labelList zeroATCZones_;
labelList zeroATCcells_;
public:
//- Runtime type information
TypeName("zeroATCcells");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
zeroATCcells,
dictionary,
(
const fvMesh& mesh,
const dictionary& dict
),
(mesh, dict)
);
// Constructors
//- Construct from components
zeroATCcells
(
const fvMesh& mesh,
const dictionary& dict
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<zeroATCcells> New
(
const fvMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~zeroATCcells() = default;
// Member Functions
//- Get the zeroATCcells
inline const labelList& getZeroATCcells()
{
return zeroATCcells_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,116 @@
/* TURBULENCE MODEL VARIABLE REFS */
turbulenceModels/turbulenceModelVariables/RAS/RASModelVariables/RASModelVariables.C
turbulenceModels/turbulenceModelVariables/RAS/laminar/laminar.C
turbulenceModels/turbulenceModelVariables/RAS/SpalartAllmaras/SpalartAllmaras.C
turbulenceModels/turbulenceModelVariables/RAS/kOmegaSST/kOmegaSST.C
turbulenceModels/turbulenceModelVariables/RAS/kEpsilon/kEpsilon.C
turbulenceModels/turbulenceModelVariables/RAS/LaunderSharmaKE/LaunderSharmaKE.C
/* VARIABLES SET */
solvers/variablesSet/variablesSet/variablesSet.C
solvers/variablesSet/incompressible/incompressibleVars.C
solvers/variablesSet/incompressibleAdjointMeanFlow/incompressibleAdjointMeanFlowVars.C
solvers/variablesSet/incompressibleAdjoint/incompressibleAdjointVars.C
/* SOLVER CONTROL */
solvers/solverControl/solverControl/solverControl.C
solvers/solverControl/SIMPLEControl/SIMPLEControl/SIMPLEControl.C
solvers/solverControl/SIMPLEControl/singleRun/SIMPLEControlSingleRun.C
/* SOLVERS */
solvers/solver/solver.C
solvers/primalSolvers/primalSolver/primalSolver.C
solvers/primalSolvers/incompressible/incompressiblePrimalSolver/incompressiblePrimalSolver.C
solvers/primalSolvers/incompressible/simple/simple.C
solvers/primalSolvers/incompressible/RASTurbulenceModel/RASTurbulenceModel.C
solvers/adjointSolvers/adjointSolver/adjointSolver.C
solvers/adjointSolvers/incompressible/incompressibleAdjointSolver/incompressibleAdjointSolver.C
solvers/adjointSolvers/incompressible/adjointSimple/adjointSimple.C
/* ADJOINT SOLVER MANAGER */
solvers/adjointSolverManager/adjointSolverManager.C
/* ZERO ATC CELLS OPTIONS*/
ATCModel/zeroATCcells/zeroATCcells/zeroATCcells.C
ATCModel/zeroATCcells/faceCells/faceCells.C
ATCModel/zeroATCcells/pointCells/pointCells.C
/* ATC MODELS */
ATCModel/ATCModel/ATCModel.C
ATCModel/ATCstandard/ATCstandard.C
ATCModel/ATCUaGradU/ATCUaGradU.C
ATCModel/cancelATC/cancelATC.C
/* ADJOINT FVOPTIONS */
fvOptionsAdjoint/fvOptions/fvOptionAdjoint.C
fvOptionsAdjoint/fvOptions/fvOptionAdjointList.C
fvOptionsAdjoint/fvOptions/fvIOoptionListAdjoint.C
/* OBJECTIVES */
objectives/objective/objective.C
objectives/incompressible/objectiveIncompressible/objectiveIncompressible.C
objectives/incompressible/objectiveForce/objectiveForce.C
objectives/incompressible/objectiveMoment/objectiveMoment.C
objectives/incompressible/objectivePtLosses/objectivePtLosses.C
/* OBJECTIVE MANAGER*/
objectiveManager/objectiveManager/objectiveManager.C
objectiveManager/objectiveManagerIncompressible/objectiveManagerIncompressible.C
/* BOUNDARY ADJOINT CONTRIBUTIONS */
boundaryAdjointContributions/boundaryAdjointContribution/boundaryAdjointContribution.C
boundaryAdjointContributions/boundaryAdjointContributionIncompressible/boundaryAdjointContributionIncompressible.C
/* ADJOINT TURBULENCE MODELS*/
turbulenceModels/incompressibleAdjoint/adjointTurbulenceModel/adjointTurbulenceModel.C
turbulenceModels/incompressibleAdjoint/adjointRAS/adjointRASModel/adjointRASModel.C
turbulenceModels/incompressibleAdjoint/adjointRAS/adjointLaminar/adjointLaminar.C
turbulenceModels/incompressibleAdjoint/adjointRAS/adjointSpalartAllmaras/adjointSpalartAllmaras.C
turbulenceModels/incompressibleAdjoint/adjointRAS/derivedFvPatchFields/adjointInletNuaTilda/adjointInletNuaTildaFvPatchScalarField.C
turbulenceModels/incompressibleAdjoint/adjointRAS/derivedFvPatchFields/adjointOutletNuaTilda/adjointOutletNuaTildaFvPatchScalarField.C
turbulenceModels/incompressibleAdjoint/adjointRAS/derivedFvPatchFields/adjointFarFieldNuaTilda/adjointFarFieldNuaTildaFvPatchScalarField.C
turbulenceModels/incompressibleAdjoint/adjointRAS/derivedFvPatchFields/adjointOutletNuaTildaFlux/adjointOutletNuaTildaFluxFvPatchScalarField.C
turbulenceModels/incompressibleAdjoint/adjointRAS/derivedFvPatchFields/adjointOutletFlux/adjointOutletFluxFvPatchScalarField.C
/* ADJOINT BOUNDARY CONDITIONS */
adjointBoundaryConditions/adjointBoundaryCondition/adjointBoundaryCondition.C
adjointBoundaryConditions/adjointInletVelocity/adjointInletVelocityFvPatchVectorField.C
adjointBoundaryConditions/adjointOutletVelocity/adjointOutletVelocityFvPatchVectorField.C
adjointBoundaryConditions/adjointWallVelocity/adjointWallVelocityFvPatchVectorField.C
adjointBoundaryConditions/adjointWallVelocityLowRe/adjointWallVelocityLowReFvPatchVectorField.C
adjointBoundaryConditions/adjointOutletPressure/adjointOutletPressureFvPatchScalarField.C
adjointBoundaryConditions/adjointFarFieldPressure/adjointFarFieldPressureFvPatchScalarField.C
adjointBoundaryConditions/adjointFarFieldVelocity/adjointFarFieldVelocityFvPatchVectorField.C
adjointBoundaryConditions/adjointZeroInlet/adjointZeroInletFvPatchFields.C
adjointBoundaryConditions/adjointOutletVelocityFlux/adjointOutletVelocityFluxFvPatchVectorField.C
/* DELTA BOUNDARY */
deltaBoundary/deltaBoundary.C
/* ADJOINT SENSITIVITY */
optimisation/adjointSensitivity/sensitivity/sensitivity.C
incoSens=optimisation/adjointSensitivity/incompressible
$(incoSens)/adjointSensitivity/adjointSensitivityIncompressible.C
$(incoSens)/adjointEikonalSolver/adjointEikonalSolverIncompressible.C
$(incoSens)/adjointMeshMovementSolver/adjointMeshMovementSolverIncompressible.C
$(incoSens)/sensitivitySurface/sensitivitySurfaceIncompressible.C
$(incoSens)/sensitivitySurfacePoints/sensitivitySurfacePointsIncompressible.C
$(incoSens)/sensitivityMultiple/sensitivityMultipleIncompressible.C
/* LINE SEARCH */
optimisation/lineSearch/lineSearch/lineSearch.C
optimisation/lineSearch/stepUpdate/stepUpdate/stepUpdate.C
/* UPDATE METHOD */
optimisation/updateMethod/updateMethod/updateMethod.C
optimisation/updateMethod/constrainedOptimisationMethod/constrainedOptimisationMethod.C
/* OPTIMIZATION TYPE */
incoOptType=optimisation/optimisationType/incompressible
$(incoOptType)/optimisationType/optimisationTypeIncompressible.C
/* OPTIMIZATION MANAGER */
optimisation/optimisationManager/optimisationManager/optimisationManager.C
optimisation/optimisationManager/singleRun/singleRun.C
LIB = $(FOAM_LIBBIN)/libadjointOptimisation

View File

@ -0,0 +1,25 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/fvMotionSolver/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude
LIB_LIBS = \
-lfiniteVolume \
-lmeshTools \
-lsurfMesh \
-lsampling \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lincompressibleTransportModels \
-lfvMotionSolvers \
-ldynamicMesh \
-lfvOptions

View File

@ -0,0 +1,151 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointBoundaryCondition.H"
#include "ATCUaGradU.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(adjointBoundaryCondition, 0);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
bool adjointBoundaryCondition::addATCUaGradUTerm()
{
if (addATCUaGradUTerm_.empty())
{
addATCUaGradUTerm_.reset(new bool(isA<ATCUaGradU>(getATC())));
}
return addATCUaGradUTerm_();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
adjointBoundaryCondition::adjointBoundaryCondition
(
const adjointBoundaryCondition& adjointBC
)
:
patch_(adjointBC.patch_),
managerName_(adjointBC.managerName_),
adjointSolverName_(adjointBC.adjointSolverName_),
simulationType_(adjointBC.simulationType_),
boundaryContrPtr_
(
boundaryAdjointContribution::New
(
adjointBC.managerName_,
adjointBC.adjointSolverName_,
adjointBC.simulationType_,
adjointBC.patch_
)
),
addATCUaGradUTerm_(adjointBC.addATCUaGradUTerm_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const word& adjointBoundaryCondition::objectiveManagerName() const
{
return managerName_;
}
const word& adjointBoundaryCondition::adjointSolverName() const
{
return adjointSolverName_;
}
const word& adjointBoundaryCondition::simulationType() const
{
return simulationType_;
}
void adjointBoundaryCondition::setBoundaryContributionPtr()
{
// Note:
// Check whether there is an objectiveFunctionManager object in the registry
// Necessary for decomposePar if the libadjoint is loaded
// through controlDict. A nicer way should be found
const fvMesh& meshRef = patch_.boundaryMesh().mesh();
if (meshRef.foundObject<regIOobject>(managerName_))
{
boundaryContrPtr_.reset
(
boundaryAdjointContribution::New
(
managerName_,
adjointSolverName_,
simulationType_,
patch_
).ptr()
);
}
else
{
WarningInFunction
<< "No objectiveManager " << managerName_ << " available." << nl
<< "Setting boundaryAdjointContributionPtr to nullptr. " << nl
<< "OK for decomposePar."
<< endl;
}
}
boundaryAdjointContribution&
adjointBoundaryCondition::getBoundaryAdjContribution()
{
return boundaryContrPtr_();
}
const ATCModel& adjointBoundaryCondition::getATC() const
{
return
patch_.boundaryMesh().mesh().lookupObject<ATCModel>
(
"ATCModel" + adjointSolverName_
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,159 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointBoundaryCondition
Description
Base class for solution control classes
\*---------------------------------------------------------------------------*/
#ifndef adjointBoundaryCondition_H
#define adjointBoundaryCondition_H
#include "boundaryAdjointContribution.H"
#include "ATCModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointBoundaryCondition Declaration
\*---------------------------------------------------------------------------*/
class adjointBoundaryCondition
{
protected:
// Protected data
//- Reference to patch
const fvPatch& patch_;
//- objectiveManager name corresponding to field
word managerName_;
//- adjointSolver name corresponding to field
word adjointSolverName_;
//- simulationType corresponding to field.
// A placeholder for now
word simulationType_;
//- Engine to manage contributions of the objective functions
//- to the adjoint boundary conditions
autoPtr<boundaryAdjointContribution> boundaryContrPtr_;
//- Whether to add the extra term from the UaGradU formulation
// autoPtr since ATCModel has not been allocated at the time
// adjointBoundaryConditions are constructed
autoPtr<bool> addATCUaGradUTerm_;
// Protected Member Functions
//- Get gradient of field on a specific boundary
template<class Type>
tmp
<
Field<typename Foam::outerProduct<Foam::vector, Type>::type>
> computePatchGrad(word name);
//- Whether to add the extra term from the UaGradU formulation
bool addATCUaGradUTerm();
public:
// Static Data Members
//- Run-time type information
TypeName("adjointBoundaryCondition");
// Constructors
//- Construct from field and base name
template<class Type>
adjointBoundaryCondition
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const word& solverName
);
//- Construct as copy
adjointBoundaryCondition(const adjointBoundaryCondition&);
//- Destructor
virtual ~adjointBoundaryCondition() = default;
// Member Functions
// Access
//- Return objectiveManager name
const word& objectiveManagerName() const;
//- Return adjointSolverName
const word& adjointSolverName() const;
//- Return the simulationType
const word& simulationType() const;
//- Set the ptr to the correct boundaryAdjointContribution
void setBoundaryContributionPtr();
//- Get boundaryContribution
boundaryAdjointContribution& getBoundaryAdjContribution();
//- ATC type might be useful for a number of BCs. Return here
const ATCModel& getATC() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "adjointBoundaryConditionTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "emptyFvPatch.H"
#include "adjointBoundaryCondition.H"
#include "adjointSolverManager.H"
#include "HashTable.H"
#include "surfaceInterpolationScheme.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
tmp
<
Field<typename Foam::outerProduct<Foam::vector, Type>::type>
>
adjointBoundaryCondition::computePatchGrad(word name)
{
// Return field
typedef typename outerProduct<vector, Type>::type GradType;
auto tresGrad = tmp<Field<GradType>>::New(patch_.size(), Zero);
auto& resGrad = tresGrad.ref();
const labelList& faceCells = patch_.faceCells();
const fvMesh& mesh = patch_.boundaryMesh().mesh();
const cellList& cells = mesh.cells();
// Go through the surfaceInterpolation scheme defined in gradSchemes for
// consistency
const GeometricField<Type, fvPatchField, volMesh>& field =
mesh.lookupObject<volVectorField>(name);
// Gives problems when grad(AdjointVar) is computed using a limited scheme,
// since it is not possible to know a priori how many words to expect in the
// stream.
// Interpolation scheme is now read through interpolation schemes.
/*
word gradSchemeName ("grad(" + name + ')');
Istream& is = mesh.gradScheme(gradSchemeName);
word schemeData(is);
*/
tmp<surfaceInterpolationScheme<Type>> tinterpScheme
(
surfaceInterpolationScheme<Type>::New
(
mesh,
mesh.interpolationScheme("interpolate(" + name + ")")
)
);
GeometricField<Type, fvsPatchField, surfaceMesh> surfField
(
tinterpScheme().interpolate(field)
);
// Auxiliary fields
const surfaceVectorField& Sf = mesh.Sf();
tmp<vectorField> tnf = patch_.nf();
const vectorField& nf = tnf();
const scalarField& V = mesh.V();
const labelUList& owner = mesh.owner();
// Compute grad value of cell adjacent to the boundary
forAll(faceCells, fI)
{
const label cI = faceCells[fI];
const cell& cellI = cells[cI];
for (const label faceI : cellI) // global face numbering
{
label patchID = mesh.boundaryMesh().whichPatch(faceI);
if (patchID == -1) //face is internal
{
const label own = owner[faceI];
tensor flux = Sf[faceI]*surfField[faceI];
if (cI == own)
{
resGrad[fI] += flux;
}
else
{
resGrad[fI] -= flux;
}
}
else // Face is boundary. Covers coupled patches as well
{
if (!isA<emptyFvPatch>(mesh.boundary()[patchID]))
{
const fvPatch& patchForFlux = mesh.boundary()[patchID];
const label boundaryFaceI = faceI - patchForFlux.start();
const vectorField& Sfb = Sf.boundaryField()[patchID];
resGrad[fI] +=
Sfb[boundaryFaceI]
*surfField.boundaryField()[patchID][boundaryFaceI];
}
}
}
resGrad[fI] /= V[cI];
}
// This has concluded the computation of the grad at the cell next to the
// boundary. We now need to compute the grad at the boundary face
const fvPatchField<Type>& bField = field.boundaryField()[patch_.index()];
resGrad = nf*bField.snGrad() + (resGrad - nf*(nf & resGrad));
return tresGrad;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
adjointBoundaryCondition::adjointBoundaryCondition
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const word& solverName
)
:
patch_(p),
managerName_("objectiveManager" + solverName),
adjointSolverName_(solverName),
simulationType_("incompressible"),
boundaryContrPtr_(nullptr),
addATCUaGradUTerm_(nullptr)
{
// Set the boundaryContribution pointer
setBoundaryContributionPtr();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,474 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointFarFieldPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "ATCUaGradU.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointFarFieldPressureFvPatchScalarField::
adjointFarFieldPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointFarFieldPressureFvPatchScalarField::
adjointFarFieldPressureFvPatchScalarField
(
const adjointFarFieldPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchScalarField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointFarFieldPressureFvPatchScalarField::
adjointFarFieldPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchScalarField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<scalar>::operator=
(
scalarField("value", dict, p.size())
);
}
Foam::adjointFarFieldPressureFvPatchScalarField::
adjointFarFieldPressureFvPatchScalarField
(
const adjointFarFieldPressureFvPatchScalarField& tppsf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(tppsf, iF),
adjointBoundaryCondition(tppsf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointFarFieldPressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
// Patch normal and surface
const scalarField& magSf = patch().magSf();
const vectorField nf(patch().nf());
// Primal flux
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
// Adjoint flux
//const fvsPatchField<scalar>& phiap =
// patch().lookupPatchField<surfaceScalarField, scalar>("phia");
// Primal velocity
const fvPatchField<vector>& Up = boundaryContrPtr_->Ub();
// Adjoint velocity
const fvPatchField<vector>& Uap = boundaryContrPtr_->Uab();
// Patch-adjacent normal adjoint velocity
scalarField Uac_n(Uap.patchInternalField()() & nf);
// Patch normal adjoint velocity
scalarField Uap_n(Uap & nf);
//scalarField Uap_n = phiap/magSf;
// Patch normal velocity Uap_n
scalarField phiOverSurf(phip/magSf);
// Patch deltas
const scalarField& delta = patch().deltaCoeffs();
// snGrad Ua_n
scalarField snGradUan(delta*(Uap_n - Uac_n));
// Momentum diffusion coefficient
tmp<scalarField> tmomentumDiffusion =
boundaryContrPtr_->momentumDiffusion();
scalarField& momentumDiffusion = tmomentumDiffusion.ref();
// Objective function and other explicit contributions
tmp<scalarField> tsource = boundaryContrPtr_->pressureSource();
scalarField source = tsource.ref();
// Contribution from the ATC part (if UaGradU)
if (addATCUaGradUTerm())
{
source += Uap & Up;
}
operator==
(
// Inlet
neg(phip)*(patchInternalField())
// Outlet
+ pos(phip)*
(
Uap_n*phiOverSurf
+ 2*momentumDiffusion*snGradUan
+ source
)
);
fixedValueFvPatchScalarField::updateCoeffs();
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::adjointFarFieldPressureFvPatchScalarField::snGrad() const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
return tmp<Field<scalar>>
(
new Field<scalar>
(
pos(phip)*patch().deltaCoeffs()*(*this - patchInternalField())
)
);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::adjointFarFieldPressureFvPatchScalarField::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
return tmp<Field<scalar>>
(
new Field<scalar>
(
neg(phip)*pTraits<scalar>::one
)
);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::adjointFarFieldPressureFvPatchScalarField::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
return tmp<Field<scalar>>
(
new Field<scalar>
(
pos(phip)*(*this)
)
);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::adjointFarFieldPressureFvPatchScalarField::gradientInternalCoeffs() const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
// Act as a zeroGradient pa bc
return tmp<Field<scalar>>
(
new Field<scalar>
(
-pos(phip)*pTraits<scalar>::one*(this->patch().deltaCoeffs())
)
);
}
Foam::tmp<Foam::Field<Foam::scalar>>
Foam::adjointFarFieldPressureFvPatchScalarField::gradientBoundaryCoeffs() const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
// Act as a zeroGradient pa bc
return tmp<Field<scalar>>
(
new Field<scalar>
(
pos(phip)*(this->patch().deltaCoeffs()*(*this))
)
);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::write(Ostream& os) const
{
fvPatchScalarField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::adjointFarFieldPressureFvPatchScalarField::operator=
(
const UList<scalar>& ul
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*ul + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator=
(
const fvPatchField<scalar>& ptf
)
{
check(ptf);
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*ptf + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator+=
(
const fvPatchField<scalar>& ptf
)
{
check(ptf);
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this) + ptf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator-=
(
const fvPatchField<scalar>& ptf
)
{
check(ptf);
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this) - ptf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator*=
(
const fvPatchField<scalar>& ptf
)
{
if (&patch() != &ptf.patch())
{
FatalErrorInFunction
<< "Incompatible patches for patch fields"
<< abort(FatalError);
}
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)*ptf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator/=
(
const fvPatchField<scalar>& ptf
)
{
if (&patch() != &ptf.patch())
{
FatalErrorInFunction
<< "Incompatible patches for patch fields"
<< abort(FatalError);
}
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)/ptf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator+=
(
const Field<scalar>& tf
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this) + tf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator-=
(
const Field<scalar>& tf
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)-tf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator*=
(
const scalarField& tf
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)*tf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator/=
(
const scalarField& tf
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)/tf) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator=
(
const scalar t
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*t + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator+=
(
const scalar t
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this) + t) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator-=
(
const scalar t
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value
(
neg(phip)*((*this)-t)
+ pos(phip)*(*this)
);
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator*=
(
const scalar s
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)*s) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
void Foam::adjointFarFieldPressureFvPatchScalarField::operator/=
(
const scalar s
)
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField value(neg(phip)*((*this)/s) + pos(phip)*(*this));
Field<scalar>::operator=(value);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchScalarField,
adjointFarFieldPressureFvPatchScalarField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,196 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointFarFieldPressureFvPatchScalarField
Description
SourceFiles
adjointFarFieldPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointFarFieldPressureFvPatchScalarField_H
#define adjointFarFieldPressureFvPatchScalarField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointOutletPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointFarFieldPressureFvPatchScalarField
:
public fixedValueFvPatchScalarField,
public adjointBoundaryCondition
{
public:
//- Runtime type information
TypeName("adjointFarFieldPressure");
// Constructors
//- Construct from patch and internal field
adjointFarFieldPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointFarFieldPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointOutletPressureFvPatchScalarField
// onto a new patch
adjointFarFieldPressureFvPatchScalarField
(
const adjointFarFieldPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new adjointFarFieldPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
adjointFarFieldPressureFvPatchScalarField
(
const adjointFarFieldPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new adjointFarFieldPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
//- Return true if this patch field fixes a value.
// Needed to check if a level has to be specified while solving
// Poissons equations.
/*
virtual bool fixesValue() const
{
return true;
}
*/
//- Return gradient at boundary
virtual tmp<Field<scalar>> snGrad() const;
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<scalar>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<scalar>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the gradient of this patchField
virtual tmp<Field<scalar>> gradientInternalCoeffs() const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the gradient of this patchField
virtual tmp<Field<scalar>> gradientBoundaryCoeffs() const;
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const UList<scalar>&);
virtual void operator=(const fvPatchField<scalar>&);
virtual void operator+=(const fvPatchField<scalar>&);
virtual void operator-=(const fvPatchField<scalar>&);
virtual void operator*=(const fvPatchField<scalar>&);
virtual void operator/=(const fvPatchField<scalar>&);
virtual void operator+=(const Field<scalar>&);
virtual void operator-=(const Field<scalar>&);
virtual void operator*=(const Field<scalar>&);
virtual void operator/=(const Field<scalar>&);
virtual void operator=(const scalar);
virtual void operator+=(const scalar);
virtual void operator-=(const scalar);
virtual void operator*=(const scalar);
virtual void operator/=(const scalar);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointFarFieldVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointFarFieldVelocityFvPatchVectorField::
adjointFarFieldVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointFarFieldVelocityFvPatchVectorField::
adjointFarFieldVelocityFvPatchVectorField
(
const adjointFarFieldVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointFarFieldVelocityFvPatchVectorField::
adjointFarFieldVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointFarFieldVelocityFvPatchVectorField::
adjointFarFieldVelocityFvPatchVectorField
(
const adjointFarFieldVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointFarFieldVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
const scalarField& faceMag = patch().magSf();
const vectorField nf(patch().nf());
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
scalarField phiOverSurf(phip/faceMag);
// Ua patch adjacent
vectorField Uac(this->patchInternalField());
// Tangent component of internalField
vectorField Uac_t(Uac - nf*(Uac & nf));
// Inverse distance
const scalarField& delta = patch().deltaCoeffs();
// Objective function and other explicit contributions for
// zeroGradient boundaries
tmp<vectorField> tsourceVelocity =
boundaryContrPtr_->tangentVelocitySource();
vectorField& sourceVelocity = tsourceVelocity.ref();
// Objective function contribution for fixedValue boundaries
tmp<vectorField> tsourcePressure =
boundaryContrPtr_->normalVelocitySource();
vectorField& sourcePressure = tsourcePressure.ref();
// Momentum diffusion coefficient
tmp<scalarField> tmomentumDiffusion =
boundaryContrPtr_->momentumDiffusion();
scalarField& momentumDiffusion = tmomentumDiffusion.ref();
scalarField denom(phiOverSurf + momentumDiffusion*delta);
operator==
(
// Inlet
- neg(phip)*sourcePressure
// Outlet
+ pos(phip)
*((Uac&nf)*nf + (Uac_t*(momentumDiffusion*delta) - sourceVelocity)/denom)
);
fixedValueFvPatchVectorField::updateCoeffs();
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointFarFieldVelocityFvPatchVectorField::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
// For fixedValue U patches
return tmp<Field<vector>>
(
new Field<vector>
(
neg(phip)*pTraits<vector>::one
)
);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointFarFieldVelocityFvPatchVectorField::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
// For zeroGradient U patches
return tmp<Field<vector>>
(
new Field<vector>
(
pos(phip)*(*this)
)
);
}
void Foam::adjointFarFieldVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointFarFieldVelocityFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointFarFieldVelocityFvPatchVectorField
Description
SourceFiles
adjointFarFieldVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointFarFieldVelocityFvPatchVectorField_H
#define adjointFarFieldVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointFarFieldVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointFarFieldVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
public:
//- Runtime type information
TypeName("adjointFarFieldVelocity");
// Constructors
//- Construct from patch and internal field
adjointFarFieldVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointFarFieldVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointFarFieldVelocityFvPatchVectorField
//- onto a new patch
adjointFarFieldVelocityFvPatchVectorField
(
const adjointFarFieldVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointFarFieldVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointFarFieldVelocityFvPatchVectorField
(
const adjointFarFieldVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointFarFieldVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointInletVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointInletVelocityFvPatchVectorField::
adjointInletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointInletVelocityFvPatchVectorField::
adjointInletVelocityFvPatchVectorField
(
const adjointInletVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointInletVelocityFvPatchVectorField::
adjointInletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointInletVelocityFvPatchVectorField::
adjointInletVelocityFvPatchVectorField
(
const adjointInletVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointInletVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// Objective function contribution
tmp<vectorField> tsource = boundaryContrPtr_->normalVelocitySource();
const vectorField& source = tsource();
operator==(-source);
fixedValueFvPatchVectorField::updateCoeffs();
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointInletVelocityFvPatchVectorField::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::one);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointInletVelocityFvPatchVectorField::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::zero);
}
void Foam::adjointInletVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointInletVelocityFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointInletVelocityFvPatchVectorField
Description
SourceFiles
adjointInletVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointInletVelocityFvPatchVectorField_H
#define adjointInletVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointInletVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointInletVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
public:
//- Runtime type information
TypeName("adjointInletVelocity");
// Constructors
//- Construct from patch and internal field
adjointInletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointInletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointInletVelocityFvPatchVectorField
//- onto a new patch
adjointInletVelocityFvPatchVectorField
(
const adjointInletVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointInletVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointInletVelocityFvPatchVectorField
(
const adjointInletVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointInletVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Add explicit sink to zero adjoint velocity tangential motion
//- at the cells next to the inlet
//virtual void manipulateMatrix(fvMatrix<vector>& matrix);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointOutletPressureFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "emptyFvPatch.H"
#include "ATCUaGradU.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointOutletPressureFvPatchScalarField::
adjointOutletPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointOutletPressureFvPatchScalarField::
adjointOutletPressureFvPatchScalarField
(
const adjointOutletPressureFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchScalarField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointOutletPressureFvPatchScalarField::
adjointOutletPressureFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchScalarField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<scalar>::operator=
(
scalarField("value", dict, p.size())
);
}
Foam::adjointOutletPressureFvPatchScalarField::
adjointOutletPressureFvPatchScalarField
(
const adjointOutletPressureFvPatchScalarField& tppsf,
const DimensionedField<scalar, volMesh>& iF
)
:
fixedValueFvPatchScalarField(tppsf, iF),
adjointBoundaryCondition(tppsf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointOutletPressureFvPatchScalarField::updateCoeffs()
{
if (updated())
{
return;
}
// Patch normal and surface
const scalarField& magSf = patch().magSf();
const vectorField nf(patch().nf());
// Primal flux
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
const fvPatchField<vector>& Up = boundaryContrPtr_->Ub();
// Adjoint velocity
const fvPatchField<vector>& Uap = boundaryContrPtr_->Uab();
scalarField snGradUan(Uap.snGrad() & nf);
// Patch normal adjoint velocity
scalarField Uap_n(Uap & nf);
// Patch normal velocity
scalarField phiOverSurf(phip/magSf);
// Momentum diffusion coefficient
tmp<scalarField> tmomentumDiffusion =
boundaryContrPtr_->momentumDiffusion();
const scalarField& momentumDiffusion = tmomentumDiffusion();
// Part of the diffusive flux related to div(nuEff*dev(grad(Ua).T()))
const word& UaName = boundaryContrPtr_->Uab().internalField().name();
tmp<tensorField> tgradUab = computePatchGrad<vector>(UaName);
const tensorField& gradUab = tgradUab();
vectorField explDiffusiveFlux
(
momentumDiffusion*(gradUab - sphericalTensor::oneThirdI*tr(gradUab))
& nf
);
scalarField normalExplDifFlux(explDiffusiveFlux & nf);
// Objective function and other explicit contributions
tmp<scalarField> tsource = boundaryContrPtr_->pressureSource();
scalarField& source = tsource.ref();
// Contribution from the ATC part (if UaGradU)
if (addATCUaGradUTerm())
{
source += Uap & Up;
}
operator==
(
(Uap_n*phiOverSurf)
+ momentumDiffusion*snGradUan
+ normalExplDifFlux
+ source
);
fixedValueFvPatchScalarField::updateCoeffs();
}
void Foam::adjointOutletPressureFvPatchScalarField::write(Ostream& os) const
{
fvPatchScalarField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchScalarField,
adjointOutletPressureFvPatchScalarField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,142 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointOutletPressureFvPatchScalarField
Description
SourceFiles
adjointOutletPressureFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointOutletPressureFvPatchScalarField_H
#define adjointOutletPressureFvPatchScalarField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointOutletPressureFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointOutletPressureFvPatchScalarField
:
public fixedValueFvPatchScalarField,
public adjointBoundaryCondition
{
public:
//- Runtime type information
TypeName("adjointOutletPressure");
// Constructors
//- Construct from patch and internal field
adjointOutletPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointOutletPressureFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given
//- adjointOutletPressureFvPatchScalarField- onto a new patch
adjointOutletPressureFvPatchScalarField
(
const adjointOutletPressureFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new adjointOutletPressureFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
adjointOutletPressureFvPatchScalarField
(
const adjointOutletPressureFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new adjointOutletPressureFvPatchScalarField(*this, iF)
);
}
// Member functions
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,194 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointOutletVelocityFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "emptyFvPatch.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::adjointOutletVelocityFvPatchVectorField::assignBoundaryValue()
{
const scalarField& magSf = patch().magSf();
tmp<vectorField> tnf(patch().nf());
const vectorField& nf = tnf();
// Primal normal velocity
const fvsPatchField<scalar>& phip = boundaryContrPtr_->phib();
const scalarField phiOverSurf(phip/magSf);
// Ua patch adjacent
vectorField Uac(this->patchInternalField());
// Tangent component of internalField
vectorField Uac_t(Uac - nf*(Uac & nf));
// Adjoint normal velocity
const fvsPatchField<scalar>& phiab = boundaryContrPtr_->phiab();
// Inverse distance
const scalarField& delta = patch().deltaCoeffs();
// Objective function and other explicit contributions
tmp<vectorField> tsource(boundaryContrPtr_->tangentVelocitySource());
const vectorField& source = tsource();
// Momentum diffusion coefficient
tmp<scalarField> tmomentumDiffusion
(
boundaryContrPtr_->momentumDiffusion()
);
const scalarField& momentumDiffusion = tmomentumDiffusion();
// Part of the diffusive flux related to div(nuEff*dev(grad(Ua).T()))
const word& fieldName = internalField().name();
tmp<tensorField> tgradUaf(computePatchGrad<vector>(fieldName));
const tensorField& gradUaf = tgradUaf();
const vectorField explDiffusiveFlux
(
momentumDiffusion
*(gradUaf - sphericalTensor::oneThirdI*tr(gradUaf)) & nf
);
const vectorField explDiffusiveFlux_t
(
explDiffusiveFlux - (explDiffusiveFlux & nf)*nf
);
// Auxiliary quantities
scalarField nd(momentumDiffusion*delta);
// Denominator. Susceptible to zero values in case of back flow
// Should use adjointOutletVelocityFlux in such cases.
scalarField denom(phiOverSurf + nd);
vectorField Uat((nd*Uac_t - explDiffusiveFlux_t - source)/denom);
operator==((phiab/magSf)*nf + Uat);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointOutletVelocityFvPatchVectorField::
adjointOutletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointOutletVelocityFvPatchVectorField::
adjointOutletVelocityFvPatchVectorField
(
const adjointOutletVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointOutletVelocityFvPatchVectorField::
adjointOutletVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointOutletVelocityFvPatchVectorField::
adjointOutletVelocityFvPatchVectorField
(
const adjointOutletVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointOutletVelocityFvPatchVectorField::evaluate
(
const Pstream::commsTypes
)
{
assignBoundaryValue();
fvPatchVectorField::evaluate();
}
void Foam::adjointOutletVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::adjointOutletVelocityFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=(patch().nf()*(patch().nf() & pvf));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointOutletVelocityFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,170 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointOutletVelocityFvPatchVectorField
Description
Provides the adjoint outlet velocity values (i.e. adjoint velocity in
case of a zeroGradient U boundary condition). Can have stability issues
in cases of backflow of the primal velocity.
The adjointOutletVelocityFlux should preferably be used.
SourceFiles
adjointOutletVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointOutletVelocityFvPatchVectorField_H
#define adjointOutletVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointOutletVelocityFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointOutletVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
// Private Member Functions
void assignBoundaryValue();
public:
//- Runtime type information
TypeName("adjointOutletVelocity");
// Constructors
//- Construct from patch and internal field
adjointOutletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointOutletVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointOutletVelocityFvPatchVectorField
//- onto a new patch
adjointOutletVelocityFvPatchVectorField
(
const adjointOutletVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointOutletVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointOutletVelocityFvPatchVectorField
(
const adjointOutletVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointOutletVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Return true: Allow adjoint solvers to obtain the outlet phia
// value through HbyA
virtual bool assignable() const
{
return true;
}
//- Update the coefficients associated with the patch field
// Apply adjoint BCs through evaluate rather than updateCoeffs
// in order to have the correct Ua boundaryField when computing the
// adjoint pressure BC
virtual void evaluate
(
const Pstream::commsTypes commsType = Pstream::commsTypes::blocking
);
//virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,232 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointOutletVelocityFluxFvPatchVectorField.H"
#include "emptyFvPatch.H"
#include "fvMatrix.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointOutletVelocityFluxFvPatchVectorField::
adjointOutletVelocityFluxFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, word::null)
{}
Foam::adjointOutletVelocityFluxFvPatchVectorField::
adjointOutletVelocityFluxFvPatchVectorField
(
const adjointOutletVelocityFluxFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_)
{}
Foam::adjointOutletVelocityFluxFvPatchVectorField::
adjointOutletVelocityFluxFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName"))
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointOutletVelocityFluxFvPatchVectorField::
adjointOutletVelocityFluxFvPatchVectorField
(
const adjointOutletVelocityFluxFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointOutletVelocityFluxFvPatchVectorField::manipulateMatrix
(
fvMatrix<vector>& matrix
)
{
vectorField& source = matrix.source();
const vectorField& Sf = patch().Sf();
const labelList& faceCells = patch().faceCells();
const scalarField& magSf = patch().magSf();
tmp<vectorField> tvelocitySource(boundaryContrPtr_->velocitySource());
const vectorField& velocitySource = tvelocitySource();
const fvPatchScalarField& pab = boundaryContrPtr_->pab();
const word& fieldName = internalField().name();
tmp<tensorField> tgradUab(computePatchGrad<vector>(fieldName));
const tensorField& gradUab = tgradUab();
// Momentum diffusion coefficient
tmp<scalarField> tmomentumDiffusion(boundaryContrPtr_->momentumDiffusion());
const scalarField& momentumDiffusion = tmomentumDiffusion();
vectorField explDiffusiveFlux
(
-momentumDiffusion*(gradUab - sphericalTensor::oneThirdI*tr(gradUab))
& Sf
);
// const fvPatchVectorField& Ub = boundaryContrPtr_->Ub();
// const fvPatchVectorField& Uab = boundaryContrPtr_->Uab();
// vectorField cmFormTerm = (Ub & Uab)*Sf;
forAll(faceCells, fI)
{
const label cI = faceCells[fI];
// Contributions from the convection and diffusion term (except from
// the transpose part) will be canceled out through the value and
// gradient coeffs. The pressure flux will be inserted later through
// grad(pa), so it must be canceled out here. Once the typical fluxes
// have been canceled out, add the objective flux. velocitySource
// includes also fluxes from the adjoint turbulence-dependent terms
// found in the adjoint momentum equations.
source[cI] +=
pab[fI]*Sf[fI]
// - cmFormTerm[fI]
+ explDiffusiveFlux[fI]
- velocitySource[fI]*magSf[fI];
}
}
void Foam::adjointOutletVelocityFluxFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
tmp<vectorField> tnf = patch().nf();
const vectorField& nf = tnf();
// vectorField Ua = (patchInternalField() & nf) * nf;
const fvsPatchScalarField& phia = boundaryContrPtr_->phiab();
vectorField Ua((phia/patch().magSf())*nf);
operator==(Ua);
fixedValueFvPatchVectorField::updateCoeffs();
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointOutletVelocityFluxFvPatchVectorField::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::zero);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointOutletVelocityFluxFvPatchVectorField::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::zero);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointOutletVelocityFluxFvPatchVectorField::
gradientBoundaryCoeffs() const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::zero);
}
Foam::tmp<Foam::Field<Foam::vector>>
Foam::adjointOutletVelocityFluxFvPatchVectorField::
gradientInternalCoeffs() const
{
return tmp<Field<vector>>::New(this->size(), pTraits<vector>::zero);
}
void Foam::adjointOutletVelocityFluxFvPatchVectorField::write
(
Ostream& os
) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::adjointOutletVelocityFluxFvPatchVectorField::operator=
(
const fvPatchField<vector>& pvf
)
{
fvPatchField<vector>::operator=(patch().nf()*(patch().nf() & pvf));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointOutletVelocityFluxFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointOutletVelocityFluxFvPatchVectorField
Description
An outlet boundary condition for patches in which the primal flow exhibits
recirculation. Adds the contribution of the objective as an adjoint
momentum flux directly to the PDEs, without the need to first compute an
adjoint outlet velocity, circumventing thus the division with (almost) zero
that manifests in case of primal flow recirculation.
SourceFiles
adjointOutletVelocityFluxFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointOutletVelocityFluxFvPatchVectorField_H
#define adjointOutletVelocityFluxFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointOutletVelocityFluxFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointOutletVelocityFluxFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
// Private Member Functions
tmp<tensorField> computeLocalGrad();
public:
//- Runtime type information
TypeName("adjointOutletVelocityFlux");
// Constructors
//- Construct from patch and internal field
adjointOutletVelocityFluxFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointOutletVelocityFluxFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
//- adjointOutletVelocityFluxFvPatchVectorField
//- onto a new patch
adjointOutletVelocityFluxFvPatchVectorField
(
const adjointOutletVelocityFluxFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointOutletVelocityFluxFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointOutletVelocityFluxFvPatchVectorField
(
const adjointOutletVelocityFluxFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointOutletVelocityFluxFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Return true: Allow adjoint solvers to obtain the outlet phia
// value through HbyA
virtual bool assignable() const
{
return true;
}
//- add source term in the first cells off the wall due to adjoint WF
virtual void manipulateMatrix(fvMatrix<vector>& matrix);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<vector>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the gradient of this patchField
virtual tmp<Field<vector>> gradientBoundaryCoeffs() const;
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the gradient of this patchField
virtual tmp<Field<vector>> gradientInternalCoeffs() const;
//- Write
virtual void write(Ostream&) const;
// Member operators
virtual void operator=(const fvPatchField<vector>& pvf);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,241 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointWallVelocityFvPatchVectorField.H"
#include "nutUSpaldingWallFunctionFvPatchScalarField.H"
#include "fvMatrix.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointWallVelocityFvPatchVectorField::
adjointWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, word::null),
kappa_(0.41),
E_(9.8)
{}
Foam::adjointWallVelocityFvPatchVectorField::
adjointWallVelocityFvPatchVectorField
(
const adjointWallVelocityFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, ptf.adjointSolverName_),
kappa_(ptf.kappa_),
E_(ptf.E_)
{}
Foam::adjointWallVelocityFvPatchVectorField::
adjointWallVelocityFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, dict.get<word>("solverName")),
kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)),
E_(dict.lookupOrDefault<scalar>("E", 9.8))
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointWallVelocityFvPatchVectorField::
adjointWallVelocityFvPatchVectorField
(
const adjointWallVelocityFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf),
kappa_(pivpvf.kappa_),
E_(pivpvf.E_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointWallVelocityFvPatchVectorField::manipulateMatrix
(
fvMatrix<vector>& matrix
)
{
// Grab ref to the diagonal matrix
vectorField& source = matrix.source();
// Define boundary condition type
typedef Foam::nutUSpaldingWallFunctionFvPatchScalarField
SAwallFunctionPatchField;
if
(
isA<SAwallFunctionPatchField>(boundaryContrPtr_->turbulentDiffusivity())
&& patch().size() != 0
)
{
const tmp<vectorField> tnf = patch().nf();
const vectorField& nf = tnf();
const scalarField& magSf = patch().magSf();
const fvPatchField<vector>& Up = boundaryContrPtr_->Ub();
const fvPatchField<vector>& Uap = *this;
const vectorField Uc(Up.patchInternalField());
const vectorField Uc_t(Uc - (Uc & nf)*nf);
// By convention, tf has the direction of the tangent PRIMAL velocity
// at the first cell off the wall
const vectorField tf(Uc_t/mag(Uc_t));
tmp<scalarField> tnuw = boundaryContrPtr_->momentumDiffusion();
const scalarField& nuw = tnuw();
tmp<scalarField> tnu = boundaryContrPtr_->laminarDiffusivity();
const scalarField& nu = tnu();
tmp<scalarField> tyC = boundaryContrPtr_->wallDistance();
const scalarField& yC = tyC();
const scalarField magGradU(mag(Up.snGrad()));
const scalarField vtau(sqrt(nuw*magGradU));
const scalarField uPlus(mag(Uc)/vtau);
const scalarField yPlus(yC*vtau/nu);
const scalarField kUu(min(kappa_*uPlus, scalar(50)));
const scalarField auxA((kappa_/E_)*(exp(kUu)-1 - kUu - 0.5*kUu*kUu));
const scalarField auxB(-(1 + auxA)/(yPlus + uPlus*(1 + auxA)));
// Tangent components are according to tf
tmp<vectorField> tsource = boundaryContrPtr_->normalVelocitySource();
const scalarField rt(tsource() & tf);
const scalarField Uap_t(Uap & tf);
forAll(Up, faceI)
{
label cellI = patch().faceCells()[faceI];
source[cellI] +=
2*auxB[faceI]*vtau[faceI]*((rt[faceI] + Uap_t[faceI]))
*(Uc[faceI]/mag(Uc[faceI]))*magSf[faceI];
}
}
}
void Foam::adjointWallVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
const fvPatchField<vector>& Up = boundaryContrPtr_->Ub();
// Patch geometry
tmp<vectorField> tnf = patch().nf();
const vectorField& nf = tnf();
// Internal fields
vectorField Uac(this->patchInternalField());
vectorField Uc(Up.patchInternalField());
// Tangent vector based on the direction of Vc
vectorField Uc_t(Uc - (Uc & nf)*nf);
vectorField tf1(Uc_t/mag(Uc_t));
// Tangent vector as the cross product of tf1 x nf
vectorField tf2((tf1 ^ nf)/mag(tf1 ^ nf));
// Normal adjoint component comes from the objective function
tmp<vectorField> tsource = boundaryContrPtr_->normalVelocitySource();
vectorField Uan(-(tsource() & nf)*nf);
// Tangential adjoint velocity in the t1 direction depends on the primal
// wall function used
vectorField Uap_t1(patch().size(), vector::zero);
typedef Foam::nutUSpaldingWallFunctionFvPatchScalarField
SAwallFunctionPatchField;
const fvPatchScalarField& nutb = boundaryContrPtr_->turbulentDiffusivity();
if (isA<SAwallFunctionPatchField>(nutb))
{
Uap_t1 = (Uac & tf1)*tf1;
// leaving out second term for now
//- (1./delta)*((gradUaC & nf) & tf1)*tf1;
}
else
{
Uap_t1 = - (tsource() & tf1)*tf1;
}
// Adjoint velocity in the t2 direction
vectorField Uap_t2(-(tsource() & tf2)*tf2);
operator==(Uan + Uap_t1 + Uap_t2);
fixedValueFvPatchVectorField::updateCoeffs();
}
void Foam::adjointWallVelocityFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("kappa", kappa_);
os.writeEntry("E", E_);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointWallVelocityFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,165 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointWallVelocityFvPatchVectorField
Description
Adjoint wall velocity boundary condition. If nutUSpaldingWallFunction is
employed in the flow solution, the corresponding adjoint wall function is
used. Otherwise, the typical low-Re boundary condition is applied
Reference:
\verbatim
For both the low- and high-Re variants
Papoutsis-Kiachagias, E. M., & Giannakoglou, K. C. (2014).
Continuous Adjoint Methods for Turbulent Flows, Applied to Shape
and Topology Optimization: Industrial Applications.
Archives of Computational Methods in Engineering, 23(2), 255-299.
http://doi.org/10.1007/s11831-014-9141-9
\endverbatim
SourceFiles
adjointWallVelocityFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointWallVelocityFvPatchVectorField_H
#define adjointWallVelocityFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointWallVelocity Declaration
\*---------------------------------------------------------------------------*/
class adjointWallVelocityFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
private:
// Private Data
scalar kappa_;
scalar E_;
public:
//- Runtime type information
TypeName("adjointWallVelocity");
// Constructors
//- Construct from patch and internal field
adjointWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointWallVelocityFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointWallVelocityFvPatchVectorField
//- onto a new patch
adjointWallVelocityFvPatchVectorField
(
const adjointWallVelocityFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointWallVelocityFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointWallVelocityFvPatchVectorField
(
const adjointWallVelocityFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointWallVelocityFvPatchVectorField(*this, iF)
);
}
// Member functions
//- In case of High-Re runs based on the nutUSpaldingWallFunction
//- add source terms in the first cell centre off the wall
virtual void manipulateMatrix(fvMatrix<vector>& matrix);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointWallVelocityLowReFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::adjointWallVelocityLowReFvPatchVectorField::
adjointWallVelocityLowReFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, "Ua")
{}
Foam::adjointWallVelocityLowReFvPatchVectorField::
adjointWallVelocityLowReFvPatchVectorField
(
const adjointWallVelocityLowReFvPatchVectorField& ptf,
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchVectorField(ptf, p, iF, mapper),
adjointBoundaryCondition(p, iF, "Ua")
{}
Foam::adjointWallVelocityLowReFvPatchVectorField::
adjointWallVelocityLowReFvPatchVectorField
(
const fvPatch& p,
const DimensionedField<vector, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchVectorField(p, iF),
adjointBoundaryCondition(p, iF, "Ua")
{
fvPatchField<vector>::operator=
(
vectorField("value", dict, p.size())
);
}
Foam::adjointWallVelocityLowReFvPatchVectorField::
adjointWallVelocityLowReFvPatchVectorField
(
const adjointWallVelocityLowReFvPatchVectorField& pivpvf,
const DimensionedField<vector, volMesh>& iF
)
:
fixedValueFvPatchVectorField(pivpvf, iF),
adjointBoundaryCondition(pivpvf)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::adjointWallVelocityLowReFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}
// Objective function contribution
tmp<vectorField> tsource = boundaryContrPtr_->normalVelocitySource();
vectorField& source = tsource.ref();
operator==(-source);
fixedValueFvPatchVectorField::updateCoeffs();
}
void Foam::adjointWallVelocityLowReFvPatchVectorField::write(Ostream& os) const
{
fvPatchVectorField::write(os);
writeEntry("value", os);
os.writeEntry("solverName", adjointSolverName_);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
makePatchTypeField
(
fvPatchVectorField,
adjointWallVelocityLowReFvPatchVectorField
);
}
// ************************************************************************* //

View File

@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointWallVelocityLowReFvPatchVectorField
Description
SourceFiles
adjointWallVelocityLowReFvPatchVectorField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointWallVelocityLowReFvPatchVectorField_H
#define adjointWallVelocityLowReFvPatchVectorField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
#include "adjointBoundaryCondition.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointWallVelocityLowReFvPatch Declaration
\*---------------------------------------------------------------------------*/
class adjointWallVelocityLowReFvPatchVectorField
:
public fixedValueFvPatchVectorField,
public adjointBoundaryCondition
{
public:
//- Runtime type information
TypeName("adjointWallVelocityLowRe");
// Constructors
//- Construct from patch and internal field
adjointWallVelocityLowReFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointWallVelocityLowReFvPatchVectorField
(
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const dictionary&
);
//- Construct by mapping given
//- adjointWallVelocityLowReFvPatchVectorField onto a new patch
adjointWallVelocityLowReFvPatchVectorField
(
const adjointWallVelocityLowReFvPatchVectorField&,
const fvPatch&,
const DimensionedField<vector, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchVectorField> clone() const
{
return tmp<fvPatchVectorField>
(
new adjointWallVelocityLowReFvPatchVectorField(*this)
);
}
//- Construct as copy setting internal field reference
adjointWallVelocityLowReFvPatchVectorField
(
const adjointWallVelocityLowReFvPatchVectorField&,
const DimensionedField<vector, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchVectorField> clone
(
const DimensionedField<vector, volMesh>& iF
) const
{
return tmp<fvPatchVectorField>
(
new adjointWallVelocityLowReFvPatchVectorField(*this, iF)
);
}
// Member functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointZeroInletFvPatchField.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::adjointZeroInletFvPatchField<Type>::adjointZeroInletFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fixedValueFvPatchField<Type>(p, iF, pTraits<Type>::zero)
{}
template<class Type>
Foam::adjointZeroInletFvPatchField<Type>::adjointZeroInletFvPatchField
(
const adjointZeroInletFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchField<Type>(p, iF, pTraits<Type>::zero)
{}
template<class Type>
Foam::adjointZeroInletFvPatchField<Type>::adjointZeroInletFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchField<Type>(p, iF, pTraits<Type>::zero)
{}
template<class Type>
Foam::adjointZeroInletFvPatchField<Type>::adjointZeroInletFvPatchField
(
const adjointZeroInletFvPatchField<Type>& azipf,
const DimensionedField<Type, volMesh>& iF
)
:
fixedValueFvPatchField<Type>(azipf, iF)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::adjointZeroInletFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<Type>>::New(this->size(), pTraits<Type>::one);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::adjointZeroInletFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<Field<Type>>::New(this->size(), pTraits<Type>::zero);
}
// ************************************************************************* //

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::adjointZeroInletFvPatchField
Description
SourceFiles
adjointZeroInletFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef adjointZeroInletFvPatchField_H
#define adjointZeroInletFvPatchField_H
#include "fvPatchFields.H"
#include "fixedValueFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class adjointZeroInletFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class adjointZeroInletFvPatchField
:
public fixedValueFvPatchField<Type>
{
public:
//- Runtime type information
TypeName("adjointZeroInlet");
// Constructors
//- Construct from patch and internal field
adjointZeroInletFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
adjointZeroInletFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given adjointZeroInletFvPatchField
//- onto a new patch
adjointZeroInletFvPatchField
(
const adjointZeroInletFvPatchField&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type>> clone() const
{
return tmp<fvPatchField<Type>>
(
new adjointZeroInletFvPatchField(*this)
);
}
//- Construct as copy setting internal field reference
adjointZeroInletFvPatchField
(
const adjointZeroInletFvPatchField&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new adjointZeroInletFvPatchField(*this, iF)
);
}
// Member functions
//- Return the matrix diagonal coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<Type>> valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
//- evaluation of the value of this patchField with given weights
virtual tmp<Field<Type>> valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "adjointZeroInletFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointZeroInletFvPatchFields.H"
#include "volFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(adjointZeroInlet);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
#ifndef adjointZeroInletFvPatchFields_H
#define adjointZeroInletFvPatchFields_H
#include "adjointZeroInletFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(adjointZeroInlet);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
#ifndef adjointZeroInletFvPatchFieldsFwd_H
#define adjointZeroInletFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class adjointZeroInletFvPatchField;
makePatchTypeFieldTypedefs(adjointZeroInlet);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "boundaryAdjointContribution.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(boundaryAdjointContribution, 0);
defineRunTimeSelectionTable(boundaryAdjointContribution, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
boundaryAdjointContribution::boundaryAdjointContribution
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
)
:
patch_(patch)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<boundaryAdjointContribution> boundaryAdjointContribution::New
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
)
{
auto cstrIter = dictionaryConstructorTablePtr_->cfind(simulationType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown boundaryAdjointContribution type " << simulationType
<< endl << endl
<< "Valid boundaryAdjointContribution types are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalError);
}
return
autoPtr<boundaryAdjointContribution>
(
cstrIter()
(
managerName,
adjointSolverName,
simulationType,
patch
)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
tmp<scalarField> boundaryAdjointContribution::adjointTMVariable1Source()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::adjointTMVariable2Source()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::TMVariable1Diffusion()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::TMVariable2Diffusion()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::TMVariable1()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
tmp<scalarField> boundaryAdjointContribution::TMVariable2()
{
return tmp<scalarField>::New(patch_.size(), Zero);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::boundaryAdjointContribution
Description
Abstract base class for computing contributions of the objective functions
to the adjoint boundary conditions
SourceFiles
boundaryAdjointContribution.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryAdjointContribution_H
#define boundaryAdjointContribution_H
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "fvPatchFields.H"
#include "fvsPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class boundaryAdjointContribution Declaration
\*---------------------------------------------------------------------------*/
class boundaryAdjointContribution
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
boundaryAdjointContribution
(
const boundaryAdjointContribution&
) = delete;
//- Disallow default bitwise assignment
void operator=(const boundaryAdjointContribution&) = delete;
protected:
// Protected data
const fvPatch& patch_;
public:
//- Runtime type information
TypeName("boundaryAdjointContribution");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
boundaryAdjointContribution,
dictionary,
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
),
(managerName, adjointSolverName, simulationType, patch)
);
// Constructors
//- Construct from components
boundaryAdjointContribution
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<boundaryAdjointContribution> New
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
);
//- Destructor
virtual ~boundaryAdjointContribution() = default;
// Member Functions
// Contribution to surface sensitivities for a specific patch
virtual tmp<scalarField> pressureSource() = 0;
virtual tmp<vectorField> velocitySource() = 0;
virtual tmp<vectorField> tangentVelocitySource() = 0;
virtual tmp<vectorField> normalVelocitySource() = 0;
virtual tmp<scalarField> adjointTMVariable1Source();
virtual tmp<scalarField> adjointTMVariable2Source();
virtual tmp<scalarField> energySource() = 0;
virtual tmp<scalarField> momentumDiffusion() = 0;
virtual tmp<scalarField> laminarDiffusivity() = 0;
virtual tmp<scalarField> thermalDiffusion() = 0;
virtual tmp<scalarField> wallDistance() = 0;
virtual tmp<scalarField> TMVariable1Diffusion();
virtual tmp<scalarField> TMVariable2Diffusion();
virtual tmp<scalarField> TMVariable1();
virtual tmp<scalarField> TMVariable2();
// References to primal and adjoint fields for the specific patch
virtual const fvPatchVectorField& Ub() const = 0;
virtual const fvPatchScalarField& pb() const = 0;
virtual const fvsPatchScalarField& phib() const = 0;
virtual const fvPatchScalarField& turbulentDiffusivity() const = 0;
virtual const fvPatchVectorField& Uab() const = 0;
virtual const fvPatchScalarField& pab() const = 0;
virtual const fvsPatchScalarField& phiab() const = 0;
// Field suffixes for primal and adjoint fields
virtual const word primalSolverName() const = 0;
virtual const word adjointSolverName() const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,421 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "boundaryAdjointContributionIncompressible.H"
#include "adjointRASModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(boundaryAdjointContributionIncompressible, 0);
addToRunTimeSelectionTable
(
boundaryAdjointContribution,
boundaryAdjointContributionIncompressible,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
boundaryAdjointContributionIncompressible::
boundaryAdjointContributionIncompressible
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
)
:
boundaryAdjointContribution
(
managerName,
adjointSolverName,
simulationType,
patch
),
objectiveManager_
(
patch_.patch().boundaryMesh().mesh().
lookupObjectRef<objectiveManager>(managerName)
),
primalVars_
(
patch_.patch().boundaryMesh().mesh().
lookupObject<incompressibleAdjointSolver>(adjointSolverName).
getPrimalVars()
),
adjointSolver_
(
patch_.patch().boundaryMesh().mesh().
lookupObject<incompressibleAdjointSolver>(adjointSolverName)
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
tmp<vectorField> boundaryAdjointContributionIncompressible::velocitySource()
{
// Objective function contribution
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<vectorField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdv
);
vectorField& source = tsource.ref();
// Turbulence model differentiation contribution.
const autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS =
adjointVars().adjointTurbulence();
source += adjointRAS().adjointMomentumBCSource()[patch_.index()];
return tsource;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::pressureSource()
{
// Objective function contribution
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<scalarField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdvn
);
scalarField& source = tsource.ref();
// Turbulence model differentiation contribution.
const autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS =
adjointVars().adjointTurbulence();
const vectorField& adjointTurbulenceContr =
adjointRAS().adjointMomentumBCSource()[patch_.index()];
tmp<vectorField> tnf = patch_.nf();
const vectorField& nf = tnf();
source += adjointTurbulenceContr & nf;
return (tsource);
}
tmp<vectorField>
boundaryAdjointContributionIncompressible::tangentVelocitySource()
{
// Objective function contribution
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<vectorField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdvt
);
vectorField& source = tsource.ref();
// Turbulence model differentiation contribution.
const autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS =
adjointVars().adjointTurbulence();
const vectorField& adjointTurbulenceContr =
adjointRAS().adjointMomentumBCSource()[patch_.index()];
tmp<vectorField> tnf = patch_.nf();
const vectorField& nf = tnf();
source += adjointTurbulenceContr - (adjointTurbulenceContr & nf)*nf;
return (tsource);
}
tmp<vectorField>
boundaryAdjointContributionIncompressible::normalVelocitySource()
{
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<vectorField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdp
);
return (tsource);
}
tmp<scalarField> boundaryAdjointContributionIncompressible::energySource()
{
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<scalarField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdT
);
return (tsource);
}
tmp<scalarField>
boundaryAdjointContributionIncompressible::adjointTMVariable1Source()
{
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<scalarField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdTMvar1
);
return (tsource);
}
tmp<scalarField>
boundaryAdjointContributionIncompressible::adjointTMVariable2Source()
{
PtrList<objective>& objectives = objectiveManager_.getObjectiveFunctions();
tmp<scalarField> tsource =
sumContributions
(
objectives,
&objectiveIncompressible::boundarydJdTMvar2
);
return (tsource);
}
tmp<scalarField> boundaryAdjointContributionIncompressible::momentumDiffusion()
{
tmp<scalarField> tnuEff(new scalarField(patch_.size(), Zero));
scalarField& nuEff = tnuEff.ref();
const autoPtr<incompressibleAdjoint::adjointRASModel>&
adjointTurbulenceModel = adjointVars().adjointTurbulence();
nuEff = adjointTurbulenceModel().nuEff()().boundaryField()[patch_.index()];
return tnuEff;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::laminarDiffusivity()
{
tmp<scalarField> tnu(new scalarField(patch_.size(), Zero));
scalarField& nu = tnu.ref();
const autoPtr<incompressible::turbulenceModel>& turbulenceModel =
primalVars_.turbulence();
nu = turbulenceModel().nu()().boundaryField()[patch_.index()];
return tnu;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::thermalDiffusion()
{
/*
const polyMesh& mesh = patch_.patch().boundaryMesh().mesh();
const compressible::turbulenceModel& turbulenceModel =
mesh.lookupObject<compressible::turbulenceModel>("turbulenceModel");
tmp<scalarField> talphaEff = turbulenceModel.alphaEff(patch_.index());
*/
tmp<scalarField> talphaEff(new scalarField(patch_.size(), Zero));
WarningInFunction
<< "no abstract thermalDiffusion is implemented. Returning zero field";
return talphaEff;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::wallDistance()
{
tmp<scalarField> twallDist(new scalarField(patch_.size(), Zero));
scalarField& wallDist = twallDist.ref();
wallDist = primalVars_.turbulence()->y()[patch_.index()];
return twallDist;
}
tmp<scalarField>
boundaryAdjointContributionIncompressible::TMVariable1Diffusion()
{
const autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS =
adjointVars().adjointTurbulence();
tmp<scalarField> tdiffCoeff =
adjointRAS().diffusionCoeffVar1(patch_.index());
return tdiffCoeff;
}
tmp<scalarField>
boundaryAdjointContributionIncompressible::TMVariable2Diffusion()
{
const autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS =
adjointVars().adjointTurbulence();
tmp<scalarField> tdiffCoeff =
adjointRAS().diffusionCoeffVar2(patch_.index());
return tdiffCoeff;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::TMVariable1()
{
const autoPtr<incompressible::RASModelVariables>& RASVariables =
primalVars_.RASModelVariables();
tmp<scalarField> tboundField(new scalarField(patch_.size(), Zero));
scalarField& boundField = tboundField.ref();
boundField = RASVariables().TMVar1().boundaryField()[patch_.index()];
return tboundField;
}
tmp<scalarField> boundaryAdjointContributionIncompressible::TMVariable2()
{
const autoPtr<incompressible::RASModelVariables>& RASVariables =
primalVars_.RASModelVariables();
tmp<scalarField> tboundField(new scalarField(patch_.size(), Zero));
scalarField& boundField = tboundField.ref();
boundField = RASVariables().TMVar2().boundaryField()[patch_.index()];
return tboundField;
}
const fvPatchVectorField& boundaryAdjointContributionIncompressible::Ub() const
{
return primalVars_.U().boundaryField()[patch_.index()];
}
const fvPatchScalarField& boundaryAdjointContributionIncompressible::pb() const
{
return primalVars_.p().boundaryField()[patch_.index()];
}
const fvsPatchScalarField&
boundaryAdjointContributionIncompressible::phib() const
{
return primalVars_.phi().boundaryField()[patch_.index()];
}
const fvPatchScalarField&
boundaryAdjointContributionIncompressible::turbulentDiffusivity() const
{
return
primalVars_.RASModelVariables()().nutRef().boundaryField()
[
patch_.index()
];
}
const fvPatchVectorField& boundaryAdjointContributionIncompressible::Uab() const
{
return adjointVars().UaInst().boundaryField()[patch_.index()];
}
const fvPatchScalarField& boundaryAdjointContributionIncompressible::pab() const
{
return adjointVars().paInst().boundaryField()[patch_.index()];
}
const fvsPatchScalarField&
boundaryAdjointContributionIncompressible::phiab() const
{
return adjointVars().phiaInst().boundaryField()[patch_.index()];
}
const word boundaryAdjointContributionIncompressible::primalSolverName() const
{
return primalVars_.solverName();
}
const word boundaryAdjointContributionIncompressible::adjointSolverName() const
{
return adjointVars().solverName();
}
const incompressibleVars&
boundaryAdjointContributionIncompressible::primalVars() const
{
return primalVars_;
}
const incompressibleAdjointVars&
boundaryAdjointContributionIncompressible::adjointVars() const
{
return adjointSolver_.getAdjointVars();
}
objectiveManager&
boundaryAdjointContributionIncompressible::getObjectiveManager()
{
return objectiveManager_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::boundaryAdjointContributionIncompressible
Description
Contributions of objective function differentiation to adjoint
boundary conditions for incompressible flows
SourceFiles
boundaryAdjointContributionIncompressible.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryAdjointContributionIncompressible_H
#define boundaryAdjointContributionIncompressible_H
#include "boundaryAdjointContribution.H"
#include "IOdictionary.H"
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "objectiveManager.H"
#include "objectiveIncompressible.H"
#include "incompressibleAdjointSolver.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class boundaryAdjointContributionIncompressible Declaration
\*---------------------------------------------------------------------------*/
class boundaryAdjointContributionIncompressible
:
public boundaryAdjointContribution
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
boundaryAdjointContributionIncompressible
(
const boundaryAdjointContributionIncompressible&
) = delete;
//- Disallow default bitwise assignment
void operator=
(
const boundaryAdjointContributionIncompressible&
) = delete;
protected:
// Protected data
objectiveManager& objectiveManager_;
const incompressibleVars& primalVars_;
//- Note: getting a reference to the adjoint vars in the contructor of
//- boundaryAdjointContributionIncompressible is dangerous since the
//- autoPtr that holds them has not been completed yet. Instead, get
//- a reference to the solver and grad the adjoint vars from there,
//- when necessary
const incompressibleAdjointSolver& adjointSolver_;
// Protected Member Functions
template<class returnType, class sourceType, class castType>
tmp<Field<returnType>> sumContributions
(
PtrList<sourceType>& sourceList,
const fvPatchField<returnType>&(castType::*boundaryFunction)
(const label)
);
public:
//- Runtime type information
TypeName("incompressible");
// Constructors
//- Construct from components
boundaryAdjointContributionIncompressible
(
const word& managerName,
const word& adjointSolverName,
const word& simulationType,
const fvPatch& patch
);
//- Destructor
virtual ~boundaryAdjointContributionIncompressible() = default;
// Member Functions
// tmp<vectorField> boundarydJtotdv();
tmp<scalarField> pressureSource();
tmp<vectorField> velocitySource();
tmp<vectorField> tangentVelocitySource();
tmp<vectorField> normalVelocitySource();
tmp<scalarField> energySource();
tmp<scalarField> adjointTMVariable1Source();
tmp<scalarField> adjointTMVariable2Source();
tmp<scalarField> momentumDiffusion();
tmp<scalarField> laminarDiffusivity();
tmp<scalarField> thermalDiffusion();
tmp<scalarField> wallDistance();
tmp<scalarField> TMVariable1Diffusion();
tmp<scalarField> TMVariable2Diffusion();
tmp<scalarField> TMVariable1();
tmp<scalarField> TMVariable2();
const fvPatchVectorField& Ub() const;
const fvPatchScalarField& pb() const;
const fvsPatchScalarField& phib() const;
const fvPatchScalarField& turbulentDiffusivity() const;
const fvPatchVectorField& Uab() const;
const fvPatchScalarField& pab() const;
const fvsPatchScalarField& phiab() const;
const word primalSolverName() const;
const word adjointSolverName() const;
const incompressibleVars& primalVars() const;
const incompressibleAdjointVars& adjointVars() const;
objectiveManager& getObjectiveManager();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "boundaryAdjointContributionIncompressibleTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class returnType, class sourceType, class castType>
Foam::tmp<Foam::Field<returnType>>
Foam::boundaryAdjointContributionIncompressible::sumContributions
(
PtrList<sourceType>& sourceList,
const fvPatchField<returnType>&(castType::*boundaryFunction)(const label)
)
{
// Objective function contribution
tmp<Field<returnType>> tdJtotdvar
(new Field<returnType>(patch_.size(), pTraits<returnType>::zero));
Field<returnType>& dJtotdvar = tdJtotdvar.ref();
// Get weighthed contribution
for (sourceType& funcI : sourceList)
{
castType& cfuncI = refCast<castType>(funcI);
const fvPatchField<returnType>& dJdvar =
(cfuncI.*boundaryFunction)(patch_.index());
dJtotdvar += cfuncI.weight()*dJdvar;
}
return tdJtotdvar;
}
// ************************************************************************* //

View File

@ -0,0 +1,369 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "deltaBoundary.H"
#include "fvMesh.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
tensor deltaBoundary::tensorCrossVector(const tensor& T, const vector& v)
{
// The correct approach when T is not a diagonal tensor
tensor res(tensor::zero);
vector vec1(T.xx(), T.yx(), T.zx());
vector res1(vec1 ^ v);
res.xx() = res1.x(); res.yx() = res1.y(); res.zx() = res1.z();
vector vec2(T.xy(), T.yy(), T.zy());
vector res2(vec2 ^ v);
res.xy() = res2.x(); res.yy() = res2.y(); res.zy() = res2.z();
vector vec3(T.xz(), T.yz(), T.zz());
vector res3(vec3 ^ v);
res.xz() = res3.x(); res.yz() = res3.y(); res.zz() = res3.z();
return res;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
deltaBoundary::deltaBoundary(const fvMesh& mesh)
:
mesh_(mesh)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
vectorField deltaBoundary::makeFaceCentresAndAreas_d
(
const pointField& p,
const pointField& p_d
)
{
vector fCtrs_d(vector::zero);
vector fAreas_d(vector::zero);
vector unitVector_d(vector::zero);
// Container field to return results
vectorField deltaVecs(3, vector::zero);
label nPoints = p.size();
// If the face is a triangle, do a direct calculation for efficiency
// and to avoid round-off error-related problems
if (nPoints == 3)
{
//fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
vector fAreas = 0.5*((p[1] - p[0])^(p[2] - p[0]));
fCtrs_d = (1.0/3.0)*(p_d[0] + p_d[1] + p_d[2]);
fAreas_d =
0.5*((p_d[1] - p_d[0])^(p[2] - p[0]))
+ 0.5*((p[1] - p[0])^(p_d[2] - p_d[0]));
scalar ds = mag(fAreas);
unitVector_d = fAreas_d/ds - (fAreas*(fAreas&fAreas_d))/ds/ds/ds;
deltaVecs[0] = fCtrs_d;
deltaVecs[1] = fAreas_d;
deltaVecs[2] = unitVector_d;
}
else
{
vector sumN(vector::zero);
vector sumN_d(vector::zero);
scalar sumA = Zero;
scalar sumA_d = Zero;
vector sumAc = vector::zero;
vector sumAc_d = vector::zero;
point fCentre = p[0];
point fCentre_d = p_d[0];
for (label pi = 1; pi < nPoints; pi++)
{
fCentre += p[pi];
fCentre_d += p_d[pi];
}
fCentre /= nPoints;
fCentre_d /= nPoints;
for (label pi = 0; pi < nPoints; pi++)
{
const point& nextPoint = p[(pi + 1) % nPoints];
const point& nextPoint_d = p_d[(pi + 1) % nPoints];
vector c = p[pi] + nextPoint + fCentre;
vector c_d = p_d[pi] + nextPoint_d + fCentre_d;
vector n = (nextPoint - p[pi])^(fCentre - p[pi]);
vector n_d =
((nextPoint_d - p_d[pi])^(fCentre - p[pi]))
+ ((nextPoint - p[pi])^(fCentre_d - p_d[pi]));
scalar a = mag(n);
if (a < ROOTVSMALL)
{
// This shouldn't happen in general.
// Manually zero contribution from zero area face for now
WarningInFunction
<< "Zero area face sub triangle found " << endl
<< p[pi] << " " << nextPoint << " " << fCentre << endl
<< "Neglecting contributions of this element " << endl;
}
else
{
scalar a_d = (n&n_d)/mag(n);
sumN += n;
sumN_d += n_d;
sumA += a;
sumA_d += a_d;
sumAc += a*c;
sumAc_d += a_d*c + a*c_d;
}
}
// fCtrs[facei] = (1.0/3.0)*sumAc/(sumA + VSMALL);
vector fAreas = 0.5*sumN;
fCtrs_d = (1.0/3.0)*(sumAc_d*sumA - sumAc*sumA_d)/sumA/sumA;
fAreas_d = 0.5*sumN_d;
scalar ds = mag(fAreas);
unitVector_d = fAreas_d/ds - (fAreas*(fAreas&fAreas_d))/ds/ds/ds;
deltaVecs[0] = fCtrs_d;
deltaVecs[1] = fAreas_d;
deltaVecs[2] = unitVector_d;
}
return deltaVecs;
}
tensorField deltaBoundary::makeFaceCentresAndAreas_d
(
const pointField& p,
const tensorField& p_d
)
{
label nPoints = p.size();
tensor fCtrs_d(tensor::zero);
tensor fAreas_d(tensor::zero);
tensor unitVector_d(tensor::zero);
// Container field to return results
tensorField deltaVecs(3, tensor::zero);
// If the face is a triangle, do a direct calculation for efficiency
// and to avoid round-off error-related problems
if (nPoints == 3)
{
vector fAreas = 0.5*((p[1] - p[0])^(p[2] - p[0]));
fCtrs_d = (1.0/3.0)*(p_d[0] + p_d[1] + p_d[2]);
fAreas_d =
0.5*tensorCrossVector(p_d[1] - p_d[0], p[2] - p[0])
//minus sign since it is vector ^ tensor
- 0.5*tensorCrossVector(p_d[2] - p_d[0], p[1] - p[0]);
scalar ds = mag(fAreas);
unitVector_d = fAreas_d/ds - (fAreas*(fAreas&fAreas_d))/ds/ds/ds;
deltaVecs[0] = fCtrs_d;
deltaVecs[1] = fAreas_d;
deltaVecs[2] = unitVector_d;
}
else
{
vector sumN(vector::zero);
tensor sumN_d(tensor::zero);
scalar sumA = Zero;
vector sumA_d(vector::zero);
vector sumAc(vector::zero);
tensor sumAc_d(tensor::zero);
point fCentre = p[0];
tensor fCentre_d = p_d[0];
for (label pi = 1; pi < nPoints; pi++)
{
fCentre += p[pi];
fCentre_d += p_d[pi];
}
fCentre /= nPoints;
fCentre_d /= nPoints;
for (label pi = 0; pi < nPoints; pi++)
{
const point& nextPoint = p[(pi + 1) % nPoints];
const tensor& nextPoint_d = p_d[(pi + 1) % nPoints];
vector c = p[pi] + nextPoint + fCentre;
tensor c_d = p_d[pi] + nextPoint_d + fCentre_d;
vector n = (nextPoint - p[pi])^(fCentre - p[pi]);
tensor n_d =
tensorCrossVector(nextPoint_d - p_d[pi], fCentre - p[pi])
//minus sign since it is vector ^ tensor
- tensorCrossVector(fCentre_d - p_d[pi], nextPoint - p[pi]);
scalar a = mag(n);
if (a < ROOTVSMALL)
{
// This shouldn't happen in general.
// Manually zero contribution from zero area face for now
WarningInFunction
<< "Zero area face sub triangle found " << nl
<< p[pi] << " " << nextPoint << " " << fCentre << nl
<< "Neglecting contributions of this element " << endl;
}
else
{
vector a_d = (n & n_d)/a;
sumN += n;
sumN_d += n_d;
sumA += a;
sumA_d += a_d;
sumAc += a*c;
// c*a_d since we need to get the correct outer product
sumAc_d += (c*a_d) + a*c_d;
}
}
vector fAreas = 0.5*sumN;
fCtrs_d = (1.0/3.0)*(sumAc_d/sumA - (sumAc*sumA_d)/sqr(sumA));
fAreas_d = 0.5*sumN_d;
scalar ds = mag(fAreas);
unitVector_d = fAreas_d/ds - (fAreas*(fAreas&fAreas_d))/ds/ds/ds;
deltaVecs[0] = fCtrs_d;
deltaVecs[1] = fAreas_d;
deltaVecs[2] = unitVector_d;
}
return deltaVecs;
}
tmp<tensorField> deltaBoundary::cellCenters_d(const label pointI)
{
const labelListList& pointCells(mesh_.pointCells());
const labelList& pointCellsI(pointCells[pointI]);
const pointField& points(mesh_.points());
tmp<tensorField> tC_d(new tensorField(pointCellsI.size(), tensor::zero));
tensorField& C_d(tC_d.ref());
const labelList& pointFaces(mesh_.pointFaces()[pointI]);
tensorField Cf_d(pointFaces.size(), tensor::zero);
tensorField Sf_d(pointFaces.size(), tensor::zero);
forAll(pointFaces, pfI)
{
const label pointFaceI = pointFaces[pfI];
const face& faceI = mesh_.faces()[pointFaceI];
tensorField p_d(faceI.size(), tensor::zero);
forAll(faceI, pI)
{
if (faceI[pI] == pointI)
{
p_d[pI] = tensor::I;
break;
}
}
pointField facePoints(faceI.points(points));
// Compute changes in the face
tensorField dFace(makeFaceCentresAndAreas_d(facePoints, p_d));
Cf_d[pfI] = dFace[0];
Sf_d[pfI] = dFace[1];
}
// Face variations have now been computed. Now, compute cell contributions
forAll(pointCellsI, pcI)
{
const label pointCellI = pointCellsI[pcI];
const cell& cellI(mesh_.cells()[pointCellI]);
vectorField fAreas(cellI.size(), vector::zero);
vectorField fCtrs(cellI.size(), vector::zero);
tensorField fAreas_d(cellI.size(), tensor::zero);
tensorField fCtrs_d(cellI.size(), tensor::zero);
forAll(cellI, fI)
{
const label globalFaceI = cellI[fI];
// Assign values to faceAreas and faceCtrs
if (globalFaceI < mesh_.nInternalFaces())
{
fAreas[fI] = mesh_.Sf()[globalFaceI];
fCtrs[fI] = mesh_.Cf()[globalFaceI];
}
else
{
const label whichPatch =
mesh_.boundaryMesh().whichPatch(globalFaceI);
const fvPatch& patch = mesh_.boundary()[whichPatch];
const label patchStart = patch.patch().start();
const label localFace = globalFaceI - patchStart;
fAreas[fI] = patch.Sf()[localFace];
fCtrs[fI] = patch.Cf()[localFace];
}
// Assign values to differentiated face areas and centres
forAll(pointFaces, pfI)
{
if (pointFaces[pfI] == globalFaceI)
{
fAreas_d[fI] = Sf_d[pfI];
fCtrs_d[fI] = Cf_d[pfI];
}
}
}
C_d[pcI] = makeCellCentres_d(fAreas, fCtrs, fAreas_d, fCtrs_d);
}
return tC_d;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::deltaBoundary
Description
Differentiation of the mesh data structure
SourceFiles
deltaBoundary.C
\*---------------------------------------------------------------------------*/
#ifndef deltaBoundary_H
#define deltaBoundary_H
#include "fieldTypes.H"
#include "vectorField.H"
#include "tensorField.H"
#include "pointField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class deltaBoundary Declaration
\*---------------------------------------------------------------------------*/
class deltaBoundary
{
protected:
// Protected data
//- Reference to the mesh
const fvMesh& mesh_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
deltaBoundary(const deltaBoundary&) = delete;
//- Disallow default bitwise assignment
void operator=(const deltaBoundary&) = delete;
//- Compute tensor-vector products
tensor tensorCrossVector(const tensor& T, const vector& v);
public:
// Constructors
//- Construct from components
deltaBoundary(const fvMesh& mesh);
//- Destructor
~deltaBoundary() = default;
// Member Functions
//- Given a face and the points to be moved in the normal direction,
//- find faceArea, faceCentre and unitVector changes
vectorField makeFaceCentresAndAreas_d
(
const pointField& p,
const pointField& p_d
);
//- Given a face and the points to be moved in an arbitrary direction,
//- find faceArea, faceCentre and unitVector changes
tensorField makeFaceCentresAndAreas_d
(
const pointField& p,
const tensorField& p_d
);
//- Compute cell center variation wrt
//- given face movement or derivative.
// pT (perturbation type) should be a vector in case
// of known face area and ctr movements
// or a tensor for gradients
template<class pT>
pT makeCellCentres_d
(
const vectorField& fAreas,
const vectorField& fCtrs,
const Field<pT>& fAreas_d,
const Field<pT>& fCtrs_d
);
//- Compute the change of the cell centers of the pointCells
//- of pointI, for a unitary movement of pointI in all three directions
tmp<tensorField> cellCenters_d(const label pointI);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "deltaBoundaryTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "deltaBoundary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class pT>
pT deltaBoundary::makeCellCentres_d
(
const vectorField& fAreas,
const vectorField& fCtrs,
const Field<pT>& fAreas_d,
const Field<pT>& fCtrs_d
)
{
// Define type that in an order smaller than pT. Used for volume-related
// variations
typedef typename innerProduct<vector, pT>::type vT;
// First estimate the approximate cell centre as the average of
// face centres
vector cEst(vector::zero);
vector cellCtrs(vector::zero);
scalar cellVols(Zero);
pT cEst_d(pTraits<pT>::zero);
pT cellCtrs_d(pTraits<pT>::zero);
vT cellVols_d(pTraits<vT>::zero);
forAll(fAreas, facei)
{
cEst += fCtrs[facei];
cEst_d += fCtrs_d[facei];
}
cEst /= fAreas.size();
cEst_d /= fAreas.size();
forAll(fAreas, facei)
{
// Calculate 3*face-pyramid volume
scalar pyr3Vol =
mag(fAreas[facei] & (fCtrs[facei] - cEst));
vT pyr3Vol_d =
(fAreas[facei] & (fCtrs[facei] - cEst))
*(
((fCtrs[facei] - cEst) & fAreas_d[facei])
// Reverse order to get the correct inner product
+ (fAreas[facei] & (fCtrs_d[facei] - cEst_d))
)/pyr3Vol;
// Calculate face-pyramid centre
vector pc = (3.0/4.0)*fCtrs[facei] + (1.0/4.0)*cEst;
pT pc_d = (3.0/4.0)*fCtrs_d[facei] + (1.0/4.0)*cEst_d;
// Accumulate volume-weighted face-pyramid centre
cellCtrs += pyr3Vol*pc;
// Reverse order to get the correct outer product
cellCtrs_d += (pc*pyr3Vol_d + pyr3Vol*pc_d);
// Accumulate face-pyramid volume
cellVols += pyr3Vol;
cellVols_d += pyr3Vol_d;
}
cellCtrs /= cellVols;
cellCtrs_d = cellCtrs_d/cellVols - cellCtrs*cellVols_d/cellVols;
cellVols *= (1.0/3.0);
cellVols_d *= (1.0/3.0);
return cellCtrs_d;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "linearUpwindNormal.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
Foam::linearUpwindNormal<Type>::correction
(
const GeometricField<Type, fvPatchField, volMesh>& vf
) const
{
const fvMesh& mesh = this->mesh();
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tsfCorr
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
"linearUpwind::correction(" + vf.name() + ')',
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensioned<Type>(vf.name(), vf.dimensions(), pTraits<Type>::zero)
)
);
GeometricField<Type, fvsPatchField, surfaceMesh>& sfCorr = tsfCorr();
const surfaceScalarField& faceFlux = this->faceFlux_;
const labelList& owner = mesh.owner();
const labelList& neighbour = mesh.neighbour();
const volVectorField& C = mesh.C();
const surfaceVectorField& Cf = mesh.Cf();
tmp
<
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>
> tgradVf = gradScheme_().grad(vf, gradSchemeName_);
GeometricField
<
typename outerProduct<vector, Type>::type,
fvPatchField,
volMesh
>& gradVf = tgradVf();
gradVf /= mag(gradVf) + 1.e-12;
forAll(faceFlux, facei)
{
label celli = (faceFlux[facei] > 0) ? owner[facei] : neighbour[facei];
sfCorr[facei] = (Cf[facei] - C[celli]) & gradVf[celli];
}
typename GeometricField<Type, fvsPatchField, surfaceMesh>::
GeometricBoundaryField& bSfCorr = sfCorr.boundaryField();
forAll(bSfCorr, patchi)
{
fvsPatchField<Type>& pSfCorr = bSfCorr[patchi];
if (pSfCorr.coupled())
{
const labelUList& pOwner =
mesh.boundary()[patchi].faceCells();
const vectorField& pCf = Cf.boundaryField()[patchi];
const scalarField& pFaceFlux = faceFlux.boundaryField()[patchi];
const Field<typename outerProduct<vector, Type>::type> pGradVfNei
(
gradVf.boundaryField()[patchi].patchNeighbourField()
);
// Build the d-vectors
vectorField pd(Cf.boundaryField()[patchi].patch().delta());
forAll(pOwner, facei)
{
label own = pOwner[facei];
if (pFaceFlux[facei] > 0)
{
pSfCorr[facei] = (pCf[facei] - C[own]) & gradVf[own];
}
else
{
pSfCorr[facei] =
(pCf[facei] - pd[facei] - C[own]) & pGradVfNei[facei];
}
}
}
}
return tsfCorr;
}
namespace Foam
{
//makelimitedSurfaceInterpolationScheme(linearUpwindNormal)
makelimitedSurfaceInterpolationTypeScheme(linearUpwindNormal, scalar)
makelimitedSurfaceInterpolationTypeScheme(linearUpwindNormal, vector)
}
// ************************************************************************* //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::linearUpwindNormal
Description
linearUpwindNormal interpolation scheme class derived from upwind and
returns upwind weighting factors and also applies a gradient-based
explicit correction. The magnitude of the correcting gradient is equal to 1
SourceFiles
linearUpwindNormal.C
\*---------------------------------------------------------------------------*/
#ifndef linearUpwindNormal_H
#define linearUpwindNormal_H
#include "upwind.H"
#include "gaussGrad.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class linearUpwindNormal Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class linearUpwindNormal
:
public upwind<Type>
{
// Private Data
word gradSchemeName_;
tmp<fv::gradScheme<Type>> gradScheme_;
// Private Member Functions
//- Disallow default bitwise copy construct
linearUpwindNormal(const linearUpwindNormal&);
//- Disallow default bitwise assignment
void operator=(const linearUpwindNormal&);
public:
//- Runtime type information
TypeName("linearUpwindNormal");
// Constructors
//- Construct from faceFlux
linearUpwindNormal
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux
)
:
upwind<Type>(mesh, faceFlux),
gradSchemeName_("grad"),
gradScheme_
(
new fv::gaussGrad<Type>(mesh)
)
{}
//- Construct from Istream.
// The name of the flux field is read from the Istream and looked-up
// from the mesh objectRegistry
linearUpwindNormal
(
const fvMesh& mesh,
Istream& schemeData
)
:
upwind<Type>(mesh, schemeData),
gradSchemeName_(schemeData),
gradScheme_
(
fv::gradScheme<Type>::New
(
mesh,
mesh.gradScheme(gradSchemeName_)
)
)
{}
//- Construct from faceFlux and Istream
linearUpwindNormal
(
const fvMesh& mesh,
const surfaceScalarField& faceFlux,
Istream& schemeData
)
:
upwind<Type>(mesh, faceFlux, schemeData),
gradSchemeName_(schemeData),
gradScheme_
(
fv::gradScheme<Type>::New
(
mesh,
mesh.gradScheme(gradSchemeName_)
)
)
{}
// Member Functions
//- Return true if this scheme uses an explicit correction
virtual bool corrected() const
{
return true;
}
//- Return the explicit correction to the face-interpolate
virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
correction
(
const GeometricField<Type, fvPatchField, volMesh>&
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "fvIOoptionListAdjoint.H"
#include "fvMesh.H"
#include "Time.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::IOobject Foam::fv::IOoptionListAdjoint::createIOobject
(
const fvMesh& mesh
) const
{
IOobject io
(
"fvOptionsAdjoint",
mesh.time().system(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (io.typeHeaderOk<IOdictionary>(true))
{
Info<< "Creating fintite volume adjoint options from " << io.name()
<< nl << endl;
io.readOpt() = IOobject::MUST_READ_IF_MODIFIED;
return io;
}
else
{
Info<< "No finite volume adjoint options present" << nl << endl;
io.readOpt() = IOobject::NO_READ;
return io;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::IOoptionListAdjoint::IOoptionListAdjoint
(
const fvMesh& mesh
)
:
IOdictionary(createIOobject(mesh)),
optionList(mesh, *this)
{}
bool Foam::fv::IOoptionListAdjoint::read()
{
if (regIOobject::read())
{
optionList::read(*this);
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::fv::IOoptionListAdjoint
Description
IOoptionListAdjoint
SourceFiles
IOoptionListAdjoint.C
\*---------------------------------------------------------------------------*/
#ifndef IOoptionListAdjoint_H
#define IOoptionListAdjoint_H
#include "fvOptionList.H"
#include "IOdictionary.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class IOoptionListAdjoint Declaration
\*---------------------------------------------------------------------------*/
class IOoptionListAdjoint
:
public IOdictionary,
public optionList
{
private:
// Private Member Functions
//- Create IO object if dictionary is present
IOobject createIOobject(const fvMesh& mesh) const;
//- Disallow default bitwise copy construct
IOoptionListAdjoint(const IOoptionListAdjoint&) = delete;
//- Disallow default bitwise assignment
void operator=(const IOoptionListAdjoint&) = delete;
public:
// Constructors
//- Construct from components with list of field names
IOoptionListAdjoint(const fvMesh& mesh);
//- Destructor
virtual ~IOoptionListAdjoint() = default;
// Member Functions
//- Read dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,113 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "fvOptionAdjoint.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(optionAdjoint, 0);
defineRunTimeSelectionTable(optionAdjoint, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::optionAdjoint::optionAdjoint
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
)
:
option(name, modelType, dict, mesh)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::fv::optionAdjoint> Foam::fv::optionAdjoint::New
(
const word& name,
const dictionary& coeffs,
const fvMesh& mesh
)
{
word modelType(coeffs.get<word>("type"));
Info<< indent
<< "Selecting finite volume options model type " << modelType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown Model type " << modelType << nl << nl
<< "Valid model types are:" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<optionAdjoint>(cstrIter()(name, modelType, coeffs, mesh));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField> Foam::fv::optionAdjoint::dxdbMult
(
const incompressibleAdjointVars&
)
{
tmp<volVectorField> tdxdbMult
(
new volVectorField
(
IOobject
(
"fvOptionAdj::dxdbMult",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedVector(dimLength/pow3(dimTime), Zero)
)
);
return tdxdbMult;
}
// ************************************************************************* //

View File

@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::fv::optionAdjoint
Description
Similar to fv::option but with additional functionality to contribute to
the sensitivity deriavtives
SourceFiles
fvOptionAdjoint.C
\*---------------------------------------------------------------------------*/
#ifndef fvOptionAdjoint_H
#define fvOptionAdjoint_H
#include "fvOption.H"
#include "incompressibleAdjointVars.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class optionAdjoint Declaration
\*---------------------------------------------------------------------------*/
class optionAdjoint
:
public option
{
public:
//- Runtime type information
TypeName("optionAdjoint");
// Constructors
//- Construct from components
optionAdjoint
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
);
//- Return clone
autoPtr<optionAdjoint> clone() const
{
notImplemented("autoPtr<optionAdjoint> clone() const");
return autoPtr<optionAdjoint>(nullptr);
}
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
optionAdjoint,
dictionary,
(
const word& name,
const word& modelType,
const dictionary& dict,
const fvMesh& mesh
),
(name, modelType, dict, mesh)
);
// Selectors
//- Return a reference to the selected fvOption model
static autoPtr<optionAdjoint> New
(
const word& name,
const dictionary& dict,
const fvMesh& mesh
);
//- Destructor
virtual ~optionAdjoint() = default;
// Member Functions
virtual tmp<volVectorField> dxdbMult(const incompressibleAdjointVars&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,182 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "fvOptionAdjointList.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
defineTypeNameAndDebug(optionAdjointList, 0);
}
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
const Foam::dictionary& Foam::fv::optionAdjointList::optionAdjointsDict
(
const dictionary& dict
) const
{
if (dict.found("optionAdjoints"))
{
return dict.subDict("optionAdjoints");
}
else
{
return dict;
}
}
bool Foam::fv::optionAdjointList::readOptionAdjoints(const dictionary& dict)
{
checkTimeIndex_ = mesh_.time().timeIndex() + 2;
bool allOk = true;
forAll(*this, i)
{
optionAdjoint& bs = this->operator[](i);
bool ok = bs.read(dict.subDict(bs.name()));
allOk = (allOk && ok);
}
return allOk;
}
void Foam::fv::optionAdjointList::checkApplied() const
{
if (mesh_.time().timeIndex() == checkTimeIndex_)
{
forAll(*this, i)
{
const optionAdjoint& bs = this->operator[](i);
bs.checkApplied();
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fv::optionAdjointList::optionAdjointList
(
const fvMesh& mesh,
const dictionary& dict
)
:
PtrList<optionAdjoint>(),
mesh_(mesh),
checkTimeIndex_(mesh_.time().startTimeIndex() + 2)
{
reset(optionAdjointsDict(dict));
}
Foam::fv::optionAdjointList::optionAdjointList(const fvMesh& mesh)
:
PtrList<optionAdjoint>(),
mesh_(mesh),
checkTimeIndex_(mesh_.time().startTimeIndex() + 2)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fv::optionAdjointList::reset(const dictionary& dict)
{
label count = 0;
forAllConstIter(dictionary, dict, iter)
{
// safety:
if (iter().isDict())
{
count++;
}
}
this->setSize(count);
label i = 0;
forAllConstIter(dictionary, dict, iter)
{
if (iter().isDict())
{
const word& name = iter().keyword();
const dictionary& sourceDict = iter().dict();
this->set
(
i++,
optionAdjoint::New(name, sourceDict, mesh_)
);
}
}
}
bool Foam::fv::optionAdjointList::read(const dictionary& dict)
{
return readOptionAdjoints(optionAdjointsDict(dict));
}
bool Foam::fv::optionAdjointList::writeData(Ostream& os) const
{
// Write list contents
forAll(*this, i)
{
os << nl;
this->operator[](i).writeData(os);
}
// Check state of IOstream
return os.good();
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
namespace Foam
{
Ostream& operator<<
(
Ostream& os,
const fv::optionAdjointList& optionAdjoints
)
{
optionAdjoints.writeData(os);
return os;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,220 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::fv::optionAdjointList
DescriptionAdjoint
List of finite volume optionAdjoints
SourceFile
optionAdjointList.C
\*---------------------------------------------------------------------------*/
#ifndef optionAdjointList_H
#define optionAdjointList_H
#include "PtrList.H"
#include "GeometricField.H"
#include "fvPatchField.H"
#include "fvOptionAdjoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace fv
{
/*---------------------------------------------------------------------------*\
Class optionAdjointList Declaration
\*---------------------------------------------------------------------------*/
class optionAdjointList
:
public PtrList<optionAdjoint>
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
optionAdjointList(const optionAdjointList&) = delete;
//- Disallow default bitwise assignment
void operator=(const optionAdjointList&) = delete;
protected:
// Protected data
//- Reference to the mesh database
const fvMesh& mesh_;
//- Time index to check that all defined sources have been applied
label checkTimeIndex_;
// Protected Member Functions
//- Return the "optionAdjoints" sub-dictionary if present otherwise
//- return dict
const dictionary& optionAdjointsDict(const dictionary& dict) const;
//- Read optionAdjoints dictionary
bool readOptionAdjoints(const dictionary& dict);
//- Check that all sources have been applied
void checkApplied() const;
public:
//- Runtime type information
TypeName("optionAdjointList");
// Constructors
//- Construct null
optionAdjointList(const fvMesh& mesh);
//- Construct from mesh and dictionary
optionAdjointList(const fvMesh& mesh, const dictionary& dict);
//- Destructor
virtual ~optionAdjointList() = default;
// Member Functions
//- Reset the source list
void reset(const dictionary& dict);
//- Correct
template<class Type>
void correct(GeometricField<Type, fvPatchField, volMesh>& fld);
// Sources
//- Return source for equation
template<class Type>
tmp<fvMatrix<Type>> operator()
(
GeometricField<Type, fvPatchField, volMesh>& fld
);
//- Return source for equation with specified name
template<class Type>
tmp<fvMatrix<Type>> operator()
(
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
);
//- Return source for equation
template<class Type>
tmp<fvMatrix<Type>> operator()
(
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld
);
//- Return source for equation with specified name
template<class Type>
tmp<fvMatrix<Type>> operator()
(
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
);
//- Return source for equation
template<class Type>
tmp<fvMatrix<Type>> operator()
(
const volScalarField& alpha,
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld
);
//- Return source for equation with specified name
template<class Type>
tmp<fvMatrix<Type>> operator()
(
const volScalarField& alpha,
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
);
// Constraints
//- Apply constraints to equation
template<class Type>
void constrain(fvMatrix<Type>& eqn);
// I-O
//- Read dictionary
virtual bool read(const dictionary& dict);
//- Write data to Ostream
virtual bool writeData(Ostream& os) const;
//- Ostream operator
friend Ostream& operator<<
(
Ostream& os,
const optionAdjointList& optionAdjoints
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "fvOptionAdjointListTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,254 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::fv::optionAdjointList::correct
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
{
const word& fieldName = fld.name();
forAll(*this, i)
{
optionAdjoint& source = this->operator[](i);
label fieldI = source.applyToField(fieldName);
if (fieldI != -1)
{
source.setApplied(fieldI);
if (source.isActive())
{
if (debug)
{
Info<< "Correcting source " << source.name()
<< " for field " << fieldName << endl;
}
source.correct(fld);
}
}
}
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
{
return this->operator()(fld, fld.name());
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
)
{
checkApplied();
const dimensionSet ds = fld.dimensions()/dimTime*dimVolume;
tmp<fvMatrix<Type>> tmtx(new fvMatrix<Type>(fld, ds));
fvMatrix<Type>& mtx = tmtx.ref();
forAll(*this, i)
{
optionAdjoint& source = this->operator[](i);
label fieldI = source.applyToField(fieldName);
if (fieldI != -1)
{
source.setApplied(fieldI);
if (source.isActive())
{
if (debug)
{
Info<< "Applying source " << source.name() << " to field "
<< fieldName << endl;
}
source.addSup(mtx, fieldI);
}
}
}
return tmtx;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld
)
{
return this->operator()(rho, fld, fld.name());
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
)
{
checkApplied();
const dimensionSet ds = rho.dimensions()*fld.dimensions()/dimTime*dimVolume;
tmp<fvMatrix<Type>> tmtx(new fvMatrix<Type>(fld, ds));
fvMatrix<Type>& mtx = tmtx.ref();
forAll(*this, i)
{
optionAdjoint& source = this->operator[](i);
label fieldI = source.applyToField(fieldName);
if (fieldI != -1)
{
source.setApplied(fieldI);
if (source.isActive())
{
if (debug)
{
Info<< "Applying source " << source.name() << " to field "
<< fieldName << endl;
}
source.addSup(rho, mtx, fieldI);
}
}
}
return tmtx;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
const volScalarField& alpha,
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld
)
{
return this->operator()(alpha, rho, fld, fld.name());
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type>> Foam::fv::optionAdjointList::operator()
(
const volScalarField& alpha,
const volScalarField& rho,
GeometricField<Type, fvPatchField, volMesh>& fld,
const word& fieldName
)
{
checkApplied();
const dimensionSet ds =
alpha.dimensions()*rho.dimensions()*fld.dimensions()/dimTime*dimVolume;
tmp<fvMatrix<Type>> tmtx(new fvMatrix<Type>(fld, ds));
fvMatrix<Type>& mtx = tmtx.ref();
forAll(*this, i)
{
optionAdjoint& source = this->operator[](i);
label fieldI = source.applyToField(fieldName);
if (fieldI != -1)
{
source.setApplied(fieldI);
if (source.isActive())
{
if (debug)
{
Info<< "Applying source " << source.name() << " to field "
<< fieldName << endl;
}
source.addSup(alpha, rho, mtx, fieldI);
}
}
}
return tmtx;
}
template<class Type>
void Foam::fv::optionAdjointList::constrain(fvMatrix<Type>& eqn)
{
checkApplied();
forAll(*this, i)
{
optionAdjoint& source = this->operator[](i);
label fieldI = source.applyToField(eqn.psi().name());
if (fieldI != -1)
{
source.setApplied(fieldI);
if (source.isActive())
{
if (debug)
{
Info<< "Applying constraint " << source.name()
<< " to field " << eqn.psi().name() << endl;
}
source.constrain(eqn, fieldI);
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1 @@
fv::IOoptionListAdjoint fvOptionsAdjoint(mesh);

View File

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
InClass
Foam::boundaryFieldsFwd
Description
Useful typenames for fields defined only at the boundaries
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef boundaryFieldsFwd_H
#define boundaryFieldsFwd_H
#include "fieldTypes.H"
#include "volFields.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//volFields
typedef typename volScalarField::Boundary boundaryScalarField;
typedef typename volVectorField::Boundary boundaryVectorField;
typedef typename volTensorField::Boundary boundaryTensorField;
//pointFields - actually a plain list of fields with dimension equal to the
// number of points per patch
typedef List<Field<scalar>> pointBoundaryScalarField;
typedef List<Field<vector>> pointBoundaryVectorField;
typedef List<Field<tensor>> pointBoundaryTensorField;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifndef createZeroField_H
#define createZeroField_H
namespace Foam
{
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
autoPtr<GeometricField<Type, fvPatchField, volMesh>>
createZeroFieldPtr
(
const fvMesh& mesh,
const word& name,
const dimensionSet dims,
bool printAllocation = false
)
{
if (printAllocation)
{
Info<< "Allocating new volField " << name << nl << endl;
}
return
(
autoPtr<GeometricField<Type, fvPatchField, volMesh>>::New
(
IOobject
(
name,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensioned<Type>(dims, Zero)
)
);
}
template<class Type>
autoPtr<typename GeometricField<Type, fvPatchField, volMesh>::Boundary>
createZeroBoundaryPtr
(
const fvMesh& mesh,
bool printAllocation = false
)
{
if (printAllocation)
{
Info<< "Allocating new boundaryField " << nl << endl;
}
typedef typename GeometricField<Type, fvPatchField, volMesh>::Boundary
Boundary;
autoPtr<Boundary> bPtr
(
new Boundary
(
mesh.boundary(),
mesh.V()*pTraits<Type>::zero, // Dummy internal field,
calculatedFvPatchField<Type>::typeName
)
);
// Values are not assigned! Assign manually
Boundary& bRef = bPtr();
forAll(bRef, pI)
{
bRef[pI] = pTraits<Type>::zero;
}
return (bPtr);
}
template<class Type>
autoPtr<List<Field<Type>>>
createZeroBoundaryPointFieldPtr
(
const fvMesh& mesh,
bool printAllocation = false
)
{
if (printAllocation)
{
Info<< "Allocating new point boundaryField " << nl << endl;
}
autoPtr<List<Field<Type>>> bPtr
(
new List<Field<Type>>
(
mesh.boundary().size()
)
);
List<Field<Type>>& bRef = bPtr();
forAll(bRef, pI)
{
bRef[pI] =
Field<Type>
(
mesh.boundaryMesh()[pI].nPoints(),
pTraits<Type>::zero
);
}
return (bPtr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,241 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectiveManager.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectiveManager, 0);
defineRunTimeSelectionTable(objectiveManager, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectiveManager::objectiveManager
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
regIOobject
(
IOobject
(
"objectiveManager" + adjointSolverName,
mesh.time().system(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
true //register object
)
),
mesh_(mesh),
dict_(dict),
adjointSolverName_(adjointSolverName),
primalSolverName_(primalSolverName),
objectives_(0)
{
// Construct objectives
//~~~~~~~~~~~~~~~~~~~~~
Info << "Constructing objective functions " << nl << endl;
const word objectiveType = dict.get<word>("type");
const dictionary& objectiveNamesDict(dict.subDict("objectiveNames"));
wordList objectiveNames(objectiveNamesDict.toc());
objectives_.setSize(objectiveNames.size());
forAll(objectiveNames, objectivei)
{
const word& objectiveName = objectiveNames[objectivei];
objectives_.set
(
objectivei,
objective::New
(
mesh_,
objectiveNamesDict.subDict(objectiveName),
objectiveType,
adjointSolverName,
primalSolverName
)
);
}
if (objectives_.empty())
{
FatalIOErrorInFunction(objectiveNamesDict)
<< "No objectives have been set - cannot perform an optimisation"
<< exit(FatalIOError);
}
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<objectiveManager> objectiveManager::New
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
{
// Determine type of objectiveManager from objectiveType
const word objectiveType(dict.get<word>("type"));
const word managerType("objectiveManager" & objectiveType);
auto cstrIter = dictionaryConstructorTablePtr_->cfind(managerType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown objectiveManagerType type " << managerType
<< nl << nl
<< "Valid objectiveManagerTypes are :" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<objectiveManager>
(
cstrIter()(mesh, dict, adjointSolverName, primalSolverName)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool objectiveManager::readDict(const dictionary& dict)
{
for (objective& obj : objectives_)
{
obj.readDict
(
dict.subDict("objectiveNames").subDict(obj.objectiveName())
);
}
return true;
}
void objectiveManager::updateNormalizationFactor()
{
// Update normalization factors for all objectives
for (objective& obj : objectives_)
{
obj.updateNormalizationFactor();
}
}
void objectiveManager::update()
{
// Update all fields related to the objective function
for (objective& obj : objectives_)
{
obj.update();
}
}
scalar objectiveManager::print()
{
scalar objValue(Zero);
for (objective& obj : objectives_)
{
scalar cost = obj.J();
scalar weight = obj.weight();
objValue += weight*cost;
Info<< obj.type() << " : " << cost << endl;
}
Info<< "Objective function manager" << nl
<< " Weighted Lagrangian " << " : " << objValue << nl << endl;
return objValue;
}
bool objectiveManager::write(const bool valid) const
{
for (const objective& obj : objectives_)
{
// Write objective function to file
obj.write();
obj.writeMeanValue();
}
return true;
}
void objectiveManager::updateAndWrite()
{
updateNormalizationFactor();
update();
print();
write();
}
PtrList<objective>& objectiveManager::getObjectiveFunctions()
{
return objectives_;
}
const PtrList<objective>& objectiveManager::getObjectiveFunctions() const
{
return objectives_;
}
const word& objectiveManager::adjointSolverName() const
{
return adjointSolverName_;
}
const word& objectiveManager::primalSolverName() const
{
return primalSolverName_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,193 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectiveManager
Description
class for managing incompressible objective functions.
SourceFiles
objectiveManager.C
\*---------------------------------------------------------------------------*/
#ifndef objectiveManager_H
#define objectiveManager_H
#include "fvMesh.H"
#include "objective.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class objectiveManager Declaration
\*---------------------------------------------------------------------------*/
class objectiveManager
:
public regIOobject
{
protected:
// Protected data
const fvMesh& mesh_;
const dictionary& dict_;
const word adjointSolverName_;
const word primalSolverName_;
PtrList<objective> objectives_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
objectiveManager(const objectiveManager&) = delete;
//- Disallow default bitwise assignment
void operator=(const objectiveManager&) = delete;
public:
TypeName("objectiveManager");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
objectiveManager,
dictionary,
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
),
(mesh, dict, adjointSolverName, primalSolverName)
);
// Constructors
//- Construct from components
objectiveManager
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<objectiveManager> New
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectiveManager() = default;
// Member Functions
virtual bool readDict(const dictionary& dict);
//- Update objective function related values
void updateNormalizationFactor();
//- Update objective function related values
void update();
//- Print to screen
scalar print();
//- Write objective function history
virtual bool write(const bool valid = true) const;
//- Call all functions required prior to the solution of the adjoint
//- equations
void updateAndWrite();
//- Return reference to objective functions
PtrList<objective>& getObjectiveFunctions();
//- Return constant reference to objective functions
const PtrList<objective>& getObjectiveFunctions() const;
//- Return name of adjointSolverManager
const word& adjointSolverManagerName() const;
//- Return name of the adjointSolver
const word& adjointSolverName() const;
//- Return name of the primalSolver
const word& primalSolverName() const;
//- Add contribution to adjoint momentum PDEs
virtual void addUaEqnSource(fvVectorMatrix& UaEqn) = 0;
//- Add contribution to adjoint momentum PDEs
virtual void addPaEqnSource(fvScalarMatrix& paEqn) = 0;
//- Add contribution to first adjoint turbulence model PDE
virtual void addTMEqn1Source(fvScalarMatrix& adjTMEqn1) = 0;
//- Add contribution to second adjoint turbulence model PDE
virtual void addTMEqn2Source(fvScalarMatrix& adjTMEqn2) = 0;
// IO
virtual bool writeData(Ostream&) const
{
return true;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectiveManagerIncompressible.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectiveManagerIncompressible, 0);
addToRunTimeSelectionTable
(
objectiveManager,
objectiveManagerIncompressible,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectiveManagerIncompressible::objectiveManagerIncompressible
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
objectiveManager(mesh, dict, adjointSolverName, primalSolverName)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void objectiveManagerIncompressible::addUaEqnSource(fvVectorMatrix& UaEqn)
{
// Add contributions from objective functions
for (objective& obj : objectives_)
{
auto& icoObj = refCast<objectiveIncompressible>(obj);
if (icoObj.hasdJdv())
{
scalar weight = icoObj.weight();
UaEqn += weight*icoObj.dJdv();
}
}
}
void objectiveManagerIncompressible::addPaEqnSource(fvScalarMatrix& paEqn)
{
// Add contributions from objective functions
for (objective& obj : objectives_)
{
auto& icoObj = refCast<objectiveIncompressible>(obj);
if (icoObj.hasdJdp())
{
scalar weight = icoObj.weight();
paEqn += weight*icoObj.dJdp();
}
}
}
void objectiveManagerIncompressible::addTMEqn1Source(fvScalarMatrix& adjTMEqn1)
{
// Add contributions from objective functions
for (objective& obj : objectives_)
{
auto& icoObj = refCast<objectiveIncompressible>(obj);
if (icoObj.hasdJdTMVar1())
{
scalar weight = icoObj.weight();
adjTMEqn1 += weight*icoObj.dJdTMvar1();
}
}
}
void objectiveManagerIncompressible::addTMEqn2Source(fvScalarMatrix& adjTMEqn2)
{
// Add contributions from objective functions
for (objective& obj : objectives_)
{
auto& icoObj = refCast<objectiveIncompressible>(obj);
if (icoObj.hasdJdTMVar2())
{
scalar weight = icoObj.weight();
adjTMEqn2 += weight*icoObj.dJdTMvar2();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectiveManagerIncompressible
Description
class for managing incompressible objective functions.
SourceFiles
objectiveManagerIncompressible.C
\*---------------------------------------------------------------------------*/
#ifndef objectiveManagerIncompressible_H
#define objectiveManagerIncompressible_H
#include "objectiveManager.H"
#include "objectiveIncompressible.H"
#include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class objectiveManagerIncompressible Declaration
\*---------------------------------------------------------------------------*/
class objectiveManagerIncompressible
:
public objectiveManager
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
objectiveManagerIncompressible
(
const objectiveManagerIncompressible&
) = delete;
//- Disallow default bitwise assignment
void operator=(const objectiveManagerIncompressible&) = delete;
public:
TypeName("objectiveManagerIncompressible");
// Constructors
//- Construct from components
objectiveManagerIncompressible
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectiveManagerIncompressible() = default;
// Member Functions
//- Add contribution to adjoint momentum PDEs
virtual void addUaEqnSource(fvVectorMatrix& UaEqn);
//- Add contribution to adjoint momentum PDEs
virtual void addPaEqnSource(fvScalarMatrix& paEqn);
//- Add contribution to adjoint turbulence model PDE
virtual void addTMEqn1Source(fvScalarMatrix& adjTMEqn1);
//- Add contribution to adjoint turbulence model PDE
virtual void addTMEqn2Source(fvScalarMatrix& adjTMEqn2);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectiveForce.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectiveForce, 0);
addToRunTimeSelectionTable
(
objectiveIncompressible,
objectiveForce,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectiveForce::objectiveForce
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
objectiveIncompressible(mesh, dict, adjointSolverName, primalSolverName),
forcePatches_
(
mesh_.boundaryMesh().patchSet
(
wordReList(dict.get<wordRes>("patches"))
)
),
forceDirection_(dict.get<vector>("direction")),
Aref_(dict.get<scalar>("Aref")),
rhoInf_(dict.get<scalar>("rhoInf")),
UInf_(dict.get<scalar>("UInf")),
stressXPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressX", dimLength/sqr(dimTime)
)
),
stressYPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressY", dimLength/sqr(dimTime)
)
),
stressZPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressZ", dimLength/sqr(dimTime)
)
)
{
// Sanity check and print info
if (forcePatches_.empty())
{
FatalErrorInFunction
<< "No valid patch name on which to minimize " << type() << endl
<< exit(FatalError);
}
if (debug)
{
Info<< "Minimizing " << type() << " in patches:" << endl;
for (const label patchI : forcePatches_)
{
Info<< "\t " << mesh_.boundary()[patchI].name() << endl;
}
}
// Allocate boundary field pointers
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
scalar objectiveForce::J()
{
vector pressureForce(Zero);
vector viscousForce(Zero);
vector cumulativeForce(Zero);
const volScalarField& p = vars_.pInst();
const autoPtr<incompressible::turbulenceModel>&
turbulence = vars_.turbulence();
volSymmTensorField devReff(turbulence->devReff());
for (const label patchI : forcePatches_)
{
pressureForce += gSum
(
mesh_.Sf().boundaryField()[patchI] * p.boundaryField()[patchI]
);
// Viscous term calculated using the full tensor derivative
viscousForce += gSum
(
devReff.boundaryField()[patchI]
& mesh_.Sf().boundaryField()[patchI]
);
}
cumulativeForce = pressureForce + viscousForce;
scalar force = cumulativeForce & forceDirection_;
// Intentionally not using denom - derived might implement virtual denom()
// function differently
scalar Cforce = force/(0.5*UInf_*UInf_*Aref_);
DebugInfo
<< "Force|Coeff " << force << "|" << Cforce << endl;
J_ = Cforce;
return Cforce;
}
void objectiveForce::update_boundarydJdp()
{
for (const label patchI : forcePatches_)
{
bdJdpPtr_()[patchI] = forceDirection_/denom();
}
}
void objectiveForce::update_dSdbMultiplier()
{
// Compute contributions with mean fields, if present
const volScalarField& p = vars_.p();
const volVectorField& U = vars_.U();
const autoPtr<incompressible::RASModelVariables>&
turbVars = vars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = vars_.laminarTransport();
tmp<volSymmTensorField> tdevReff = turbVars->devReff(lamTransp, U);
const volSymmTensorField& devReff = tdevReff();
for (const label patchI : forcePatches_)
{
bdSdbMultPtr_()[patchI] =
(
(
forceDirection_& devReff.boundaryField()[patchI]
)
+ (forceDirection_)*p.boundaryField()[patchI]
)
/denom();
}
}
void objectiveForce::update_dxdbMultiplier()
{
const volScalarField& p = vars_.p();
const volVectorField& U = vars_.U();
const autoPtr<incompressible::RASModelVariables>&
turbVars = vars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = vars_.laminarTransport();
//tmp<volSymmTensorField> tdevReff = turbVars->devReff(lamTransp, U);
//const volSymmTensorField& devReff = tdevReff();
volScalarField nuEff(lamTransp.nu() + turbVars->nutRef());
volTensorField gradU(fvc::grad(U));
volTensorField::Boundary& gradUbf = gradU.boundaryFieldRef();
// Explicitly correct the boundary gradient to get rid of
// the tangential component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> nf = patch.nf();
gradUbf[patchI] = nf*U.boundaryField()[patchI].snGrad();
}
}
volTensorField stress(nuEff*(gradU + T(gradU)));
stressXPtr_().replace(0, stress.component(0));
stressXPtr_().replace(1, stress.component(1));
stressXPtr_().replace(2, stress.component(2));
stressYPtr_().replace(0, stress.component(3));
stressYPtr_().replace(1, stress.component(4));
stressYPtr_().replace(2, stress.component(5));
stressZPtr_().replace(0, stress.component(6));
stressZPtr_().replace(1, stress.component(7));
stressZPtr_().replace(2, stress.component(8));
volTensorField gradStressX(fvc::grad(stressXPtr_()));
volTensorField gradStressY(fvc::grad(stressYPtr_()));
volTensorField gradStressZ(fvc::grad(stressZPtr_()));
// the notorious second-order derivative at the wall. Use with caution!
volVectorField gradp(fvc::grad(p));
for (const label patchI : forcePatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
bdxdbMultPtr_()[patchI] =
(
(
(
-(forceDirection_.x() * gradStressX.boundaryField()[patchI])
-(forceDirection_.y() * gradStressY.boundaryField()[patchI])
-(forceDirection_.z() * gradStressZ.boundaryField()[patchI])
) & nf
)
+ (forceDirection_ & nf)*gradp.boundaryField()[patchI]
)
/denom();
}
}
void objectiveForce::update_dJdStressMultiplier()
{
for (const label patchI : forcePatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
bdJdStressPtr_()[patchI] = (forceDirection_ * nf)/denom();
}
}
scalar objectiveForce::denom() const
{
return 0.5*UInf_*UInf_*Aref_;
}
const vector& objectiveForce::forceDirection() const
{
return forceDirection_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectives
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectives::objectiveForce
Description
SourceFiles
objectiveForce.C
\*---------------------------------------------------------------------------*/
#ifndef objectiveForce_H
#define objectiveForce_H
#include "objectiveIncompressible.H"
#include "wallFvPatch.H"
#include "createZeroField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
/*---------------------------------------------------------------------------*\
Class objectiveForce Declaration
\*---------------------------------------------------------------------------*/
class objectiveForce
:
public objectiveIncompressible
{
protected:
// Protected Data
labelHashSet forcePatches_;
vector forceDirection_;
scalar Aref_;
scalar rhoInf_;
scalar UInf_;
autoPtr<volVectorField> stressXPtr_;
autoPtr<volVectorField> stressYPtr_;
autoPtr<volVectorField> stressZPtr_;
public:
//- Runtime type information
TypeName("force");
// Constructors
//- Construct from components
objectiveForce
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectiveForce() = default;
// Member Functions
//- Return the objective function value
scalar J();
//- Update values to be added to the adjoint wall velocity
void update_boundarydJdp();
//- Update delta(n dS)/delta b multiplier
void update_dSdbMultiplier();
//- Update delta(x)/delta b multiplier
void update_dxdbMultiplier();
//- Update dJ/dStress multiplier
void update_dJdStressMultiplier();
//- Return denominator, without density
virtual scalar denom() const;
//- Return force direction
const vector& forceDirection() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectives
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,432 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectiveIncompressible.H"
#include "incompressiblePrimalSolver.H"
#include "createZeroField.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectiveIncompressible, 0);
defineRunTimeSelectionTable(objectiveIncompressible, dictionary);
addToRunTimeSelectionTable
(
objective,
objectiveIncompressible,
objective
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectiveIncompressible::objectiveIncompressible
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
objective(mesh, dict, adjointSolverName, primalSolverName),
vars_
(
mesh.lookupObject<incompressiblePrimalSolver>(primalSolverName).
getVars()
),
// Initialize pointers to nullptr.
// Not all of them are required for each objective function.
// Each child should allocate whatever is needed.
// Field adjoint Eqs
dJdvPtr_(nullptr),
dJdpPtr_(nullptr),
dJdTPtr_(nullptr),
dJdTMvar1Ptr_(nullptr),
dJdTMvar2Ptr_(nullptr),
// Adjoint boundary conditions
bdJdvPtr_(nullptr),
bdJdvnPtr_(nullptr),
bdJdvtPtr_(nullptr),
bdJdpPtr_(nullptr),
bdJdTPtr_(nullptr),
bdJdTMvar1Ptr_(nullptr),
bdJdTMvar2Ptr_(nullptr)
{
weight_ = dict.get<scalar>("weight");
computeMeanFields_ = vars_.computeMeanFields();
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<objectiveIncompressible> objectiveIncompressible::New
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
{
const word objectiveName = dict.dictName();
const word modelType(dict.get<word>("type"));
Info<< "Creating objective function : " << objectiveName
<< " of type " << modelType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown objectiveIncompressible type " << modelType << nl << nl
<< "Valid objectiveIncompressible types are :" << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<objectiveIncompressible>
(
cstrIter()(mesh, dict, adjointSolverName, primalSolverName)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const volVectorField& objectiveIncompressible::dJdv()
{
if (dJdvPtr_.empty())
{
// If pointer is not set, set it to a zero field
dJdvPtr_.reset
(
createZeroFieldPtr<vector>
(
mesh_,
("dJdv_"+type()),
dimensionSet(0, 3, -2, 0, 0, 0, 0)
)
);
}
return dJdvPtr_();
}
const volScalarField& objectiveIncompressible::dJdp()
{
if (dJdpPtr_.empty())
{
// If pointer is not set, set it to a zero field
dJdpPtr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("dJdp_"+type()),
dimensionSet(0, 3, -2, 0, 0, 0, 0)
)
);
}
return dJdpPtr_();
}
const volScalarField& objectiveIncompressible::dJdT()
{
if (dJdTPtr_.empty())
{
// If pointer is not set, set it to a zero field
dJdTPtr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("dJdT_"+type()),
dimensionSet(0, 3, -2, 0, 0, 0, 0)
)
);
}
return dJdTPtr_();
}
const volScalarField& objectiveIncompressible::dJdTMvar1()
{
if (dJdTMvar1Ptr_.empty())
{
// If pointer is not set, set it to a zero field
dJdTMvar1Ptr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("dJdTMvar1_"+type()),
dimensionSet(0, 0, -2, 0, 0, 0, 0)
)
);
}
return dJdTMvar1Ptr_();
}
const volScalarField& objectiveIncompressible::dJdTMvar2()
{
if (dJdTMvar2Ptr_.empty())
{
// If pointer is not set, set it to a zero field
dJdTMvar2Ptr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("dJdTMvar2_"+type()),
dimensionSet(0, 3, -2, 0, 0, 0, 0)
)
);
}
return dJdTMvar2Ptr_();
}
const fvPatchVectorField& objectiveIncompressible::boundarydJdv
(
const label patchI
)
{
if (bdJdvPtr_.empty())
{
bdJdvPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdvPtr_()[patchI];
}
const fvPatchScalarField& objectiveIncompressible::boundarydJdvn
(
const label patchI
)
{
if (bdJdvnPtr_.empty())
{
bdJdvnPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdvnPtr_()[patchI];
}
const fvPatchVectorField& objectiveIncompressible::boundarydJdvt
(
const label patchI
)
{
if (bdJdvtPtr_.empty())
{
bdJdvtPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdvtPtr_()[patchI];
}
const fvPatchVectorField& objectiveIncompressible::boundarydJdp
(
const label patchI
)
{
if (bdJdpPtr_.empty())
{
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdpPtr_()[patchI];
}
const fvPatchScalarField& objectiveIncompressible::boundarydJdT
(
const label patchI
)
{
if (bdJdTPtr_.empty())
{
bdJdTPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTPtr_()[patchI];
}
const fvPatchScalarField& objectiveIncompressible::boundarydJdTMvar1
(
const label patchI
)
{
if (bdJdTMvar1Ptr_.empty())
{
bdJdTMvar1Ptr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTMvar1Ptr_()[patchI];
}
const fvPatchScalarField& objectiveIncompressible::boundarydJdTMvar2
(
const label patchI
)
{
if (bdJdTMvar2Ptr_.empty())
{
bdJdTMvar2Ptr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTMvar2Ptr_()[patchI];
}
const boundaryVectorField& objectiveIncompressible::boundarydJdv()
{
if (bdJdvPtr_.empty())
{
bdJdvPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdvPtr_();
}
const boundaryScalarField& objectiveIncompressible::boundarydJdvn()
{
if (bdJdvnPtr_.empty())
{
bdJdvnPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdvnPtr_();
}
const boundaryVectorField& objectiveIncompressible::boundarydJdvt()
{
if (bdJdvtPtr_.empty())
{
bdJdvtPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdvtPtr_();
}
const boundaryVectorField& objectiveIncompressible::boundarydJdp()
{
if (bdJdpPtr_.empty())
{
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdpPtr_();
}
const boundaryScalarField& objectiveIncompressible::boundarydJdT()
{
if (bdJdTPtr_.empty())
{
bdJdTPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTPtr_();
}
const boundaryScalarField& objectiveIncompressible::boundarydJdTMvar1()
{
if (bdJdTMvar1Ptr_.empty())
{
bdJdTMvar1Ptr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTMvar1Ptr_();
}
const boundaryScalarField& objectiveIncompressible::boundarydJdTMvar2()
{
if (bdJdTMvar2Ptr_.empty())
{
bdJdTMvar2Ptr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
}
return bdJdTMvar2Ptr_();
}
void objectiveIncompressible::update()
{
// Objective function value
J();
// Update mean values here since they might be used in the
// subsequent functions
update_meanValues();
// volFields
update_dJdv();
update_dJdp();
update_dJdT();
update_dJdTMvar1();
update_dJdTMvar2();
update_dJdb();
update_divDxDbMultiplier();
update_gradDxDbMultiplier();
// boundaryFields
update_boundarydJdv();
update_boundarydJdvn();
update_boundarydJdvt();
update_boundarydJdp();
update_boundarydJdT();
update_boundarydJdTMvar1();
update_boundarydJdTMvar2();
update_boundarydJdb();
update_dSdbMultiplier();
update_dndbMultiplier();
update_dxdbMultiplier();
update_dxdbDirectMultiplier();
update_boundaryEdgeContribution();
update_dJdStressMultiplier();
}
void objectiveIncompressible::write() const
{
objective::write();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,332 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectiveIncompressible
Description
Abstract base class for objective functions in incompressible flows
SourceFiles
objectiveIncompressible.C
\*---------------------------------------------------------------------------*/
#ifndef objectiveIncompressible_H
#define objectiveIncompressible_H
#include "objective.H"
#include "incompressibleVars.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class objectiveIncompressible Declaration
\*---------------------------------------------------------------------------*/
class objectiveIncompressible
:
public objective
{
protected:
// Protected data
const incompressibleVars& vars_;
// Contribution to field adjoint equations
// v,p,T and turbulence model variables
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
autoPtr<volVectorField> dJdvPtr_;
autoPtr<volScalarField> dJdpPtr_;
autoPtr<volScalarField> dJdTPtr_;
//- First turbulence model variable
autoPtr<volScalarField> dJdTMvar1Ptr_;
//- Second turbulence model variable
autoPtr<volScalarField> dJdTMvar2Ptr_;
// Contribution to adjoint boundary conditions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
autoPtr<boundaryVectorField> bdJdvPtr_;
//- Adjoint outlet pressure
autoPtr<boundaryScalarField> bdJdvnPtr_;
//- Adjoint outlet velocity
autoPtr<boundaryVectorField> bdJdvtPtr_;
//- Adjoint (intlet,wall) velocity
autoPtr<boundaryVectorField> bdJdpPtr_;
//- Adjoint outlet temperature
autoPtr<boundaryScalarField> bdJdTPtr_;
//- Adjoint outlet turbulence model var 1
autoPtr<boundaryScalarField> bdJdTMvar1Ptr_;
//- Adjoint outlet turbulence model var 2
autoPtr<boundaryScalarField> bdJdTMvar2Ptr_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
objectiveIncompressible(const objectiveIncompressible&) = delete;
//- Disallow default bitwise assignment
void operator=(const objectiveIncompressible&) = delete;
public:
//- Runtime type information
TypeName("incompressible");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
objectiveIncompressible,
dictionary,
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
),
(mesh, dict, adjointSolverName, primalSolverName)
);
// Constructors
//- Construct from components
objectiveIncompressible
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<objectiveIncompressible> New
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectiveIncompressible() = default;
// Member Functions
//- Return the objective function value
virtual scalar J() = 0;
//- Contribution to field adjoint momentum eqs
const volVectorField& dJdv();
//- Contribution to field adjoint continuity eq
const volScalarField& dJdp();
//- Contribution to field adjoint energy eq
const volScalarField& dJdT();
//- Contribution to field adjoint turbulence model variable 1
const volScalarField& dJdTMvar1();
//- Contribution to field adjoint turbulence model variable 2
const volScalarField& dJdTMvar2();
//- Objective partial deriv wrt velocity for a specific patch
const fvPatchVectorField& boundarydJdv(const label);
//- Objective partial deriv wrt normal velocity for a specific patch
const fvPatchScalarField& boundarydJdvn(const label);
//- Objective partial deriv wrt tangent velocity for a specific patch
const fvPatchVectorField& boundarydJdvt(const label);
//- Objective partial deriv wrt pressure (times normal) for a specific
//- patch
const fvPatchVectorField& boundarydJdp(const label);
//- Objective partial deriv wrt temperature for a specific patch
const fvPatchScalarField& boundarydJdT(const label);
//- Objective partial deriv wrt turbulence model var 1 for a specific
//- patch
const fvPatchScalarField& boundarydJdTMvar1(const label);
//- Objective partial deriv wrt turbulence model var 2 for a specific
//- patch
const fvPatchScalarField& boundarydJdTMvar2(const label);
//- Objective partial deriv wrt velocity for all patches
const boundaryVectorField& boundarydJdv();
//- Objective partial deriv wrt normal velocity for all patches
const boundaryScalarField& boundarydJdvn();
//- Objective partial deriv wrt tangent velocity for all patches
const boundaryVectorField& boundarydJdvt();
//- Objective partial deriv wrt pressure (times normal) for all patches
const boundaryVectorField& boundarydJdp();
//- Objective partial deriv wrt temperature for all patches
const boundaryScalarField& boundarydJdT();
//- Objective partial deriv wrt turbulence model var 1 for all patches
const boundaryScalarField& boundarydJdTMvar1();
//- Objective partial deriv wrt turbulence model var 2 for all patches
const boundaryScalarField& boundarydJdTMvar2();
//- Update objective function derivatives
void update();
//- Update vol and boundary fields and derivatives
// Do nothing in the base. The relevant ones should be overwritten
// in the child objective functions
virtual void update_dJdv()
{}
virtual void update_dJdp()
{}
virtual void update_dJdT()
{}
virtual void update_dJdTMvar1()
{}
virtual void update_dJdTMvar2()
{}
virtual void update_dJdb()
{}
virtual void update_divDxDbMultiplier()
{}
virtual void update_gradDxDbMultiplier()
{}
virtual void update_boundarydJdv()
{}
virtual void update_boundarydJdvn()
{}
virtual void update_boundarydJdvt()
{}
virtual void update_boundarydJdp()
{}
virtual void update_boundarydJdT()
{}
virtual void update_boundarydJdTMvar1()
{}
virtual void update_boundarydJdTMvar2()
{}
virtual void update_boundarydJdb()
{}
virtual void update_dSdbMultiplier()
{}
virtual void update_dndbMultiplier()
{}
virtual void update_dxdbMultiplier()
{}
virtual void update_dxdbDirectMultiplier()
{}
//- Some objectives need to store some auxiliary values.
//- If averaging is enabled, update these mean values here.
// By convention, the mean values (eg mean drag) refer to these flow
// values computed using the mean fields, rather than averaging the
// values themselves
virtual void update_meanValues()
{}
//- Write objective function history
virtual void write() const;
//- Inline functions for checking whether pointers are set or not
inline bool hasdJdv();
inline bool hasdJdp();
inline bool hasdJdT();
inline bool hasdJdTMVar1();
inline bool hasdJdTMVar2();
inline bool hasBoundarydJdv();
inline bool hasBoundarydJdvn();
inline bool hasBoundarydJdvt();
inline bool hasBoundarydJdp();
inline bool hasBoundarydJdT();
inline bool hasBoundarydJdTMVar1();
inline bool hasBoundarydJdTMVar2();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "objectiveIncompressibleI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::objectiveIncompressible::hasdJdv()
{
return dJdvPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasdJdp()
{
return dJdpPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasdJdT()
{
return dJdTPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasdJdTMVar1()
{
return dJdTMvar1Ptr_.valid();
}
inline bool Foam::objectiveIncompressible::hasdJdTMVar2()
{
return dJdTMvar2Ptr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdv()
{
return bdJdvPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdvn()
{
return bdJdvnPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdvt()
{
return bdJdvtPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdp()
{
return bdJdpPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdT()
{
return bdJdTPtr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar1()
{
return bdJdTMvar1Ptr_.valid();
}
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar2()
{
return bdJdTMvar2Ptr_.valid();
}
// ************************************************************************* //

View File

@ -0,0 +1,313 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectiveMoment.H"
#include "createZeroField.H"
#include "wallFvPatch.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectiveMoment, 0);
addToRunTimeSelectionTable
(
objectiveIncompressible,
objectiveMoment,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectiveMoment::objectiveMoment
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
objectiveIncompressible(mesh, dict, adjointSolverName, primalSolverName),
momentPatches_
(
mesh_.boundaryMesh().patchSet
(
wordReList(dict.get<wordRes>("patches"))
)
),
momentDirection_(dict.get<vector>("direction")),
rotationCentre_(dict.get<vector>("rotationCenter")),
Aref_(dict.get<scalar>("Aref")),
lRef_(dict.get<scalar>("lRef")),
rhoInf_(dict.get<scalar>("rhoInf")),
UInf_(dict.get<scalar>("UInf")),
invDenom_(2./(rhoInf_*UInf_*UInf_*Aref_*lRef_)),
stressXPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressX", dimLength/sqr(dimTime)
)
),
stressYPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressY", dimLength/sqr(dimTime)
)
),
stressZPtr_
(
Foam::createZeroFieldPtr<vector>
(
mesh_, "stressZ", dimLength/sqr(dimTime)
)
),
devReff_(vars_.turbulence()->devReff()())
{
// Sanity check and print info
if (momentPatches_.empty())
{
FatalErrorInFunction
<< "No valid patch name on which to minimize " << type() << endl
<< exit(FatalError);
}
if (debug)
{
Info<< "Minimizing " << type() << " in patches:" << endl;
for (const label patchI : momentPatches_)
{
Info<< "\t " << mesh_.boundary()[patchI].name() << endl;
}
}
// Allocate boundary field pointers
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
scalar objectiveMoment::J()
{
vector pressureMoment(Zero);
vector viscousMoment(Zero);
vector cumulativeMoment(Zero);
// Update field here and use the same value for all functions
const volScalarField& p = vars_.pInst();
devReff_ = vars_.turbulence()->devReff()();
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
const vectorField& Sf = patch.Sf();
vectorField dx(patch.Cf() - rotationCentre_);
pressureMoment += gSum
(
rhoInf_*(dx ^ Sf)*p.boundaryField()[patchI]
);
// Viscous term calculated using the full tensor derivative
viscousMoment += gSum
(
rhoInf_*(dx^(devReff_.boundaryField()[patchI] & Sf))
);
}
cumulativeMoment = pressureMoment + viscousMoment;
scalar moment = cumulativeMoment & momentDirection_;
scalar Cm = moment*invDenom_;
DebugInfo<<
"Moment|Coeff " << moment << "|" << Cm << endl;
J_ = Cm;
return Cm;
}
void objectiveMoment::update_meanValues()
{
if (computeMeanFields_)
{
const volVectorField& U = vars_.U();
const autoPtr<incompressible::RASModelVariables>&
turbVars = vars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = vars_.laminarTransport();
devReff_ = turbVars->devReff(lamTransp, U)();
}
}
void objectiveMoment::update_boundarydJdp()
{
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
vectorField dx(patch.Cf() - rotationCentre_);
bdJdpPtr_()[patchI] = (momentDirection_ ^ dx)*invDenom_*rhoInf_;
}
}
void objectiveMoment::update_dSdbMultiplier()
{
const volScalarField& p = vars_.p();
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
const vectorField dx(patch.Cf() - rotationCentre_);
bdSdbMultPtr_()[patchI] =
(
(
rhoInf_*
(
(momentDirection_^dx) &
(
devReff_.boundaryField()[patchI]
)
)
)
+ rhoInf_ * (momentDirection_^dx) * p.boundaryField()[patchI]
)
*invDenom_;
}
}
void objectiveMoment::update_dxdbMultiplier()
{
const volScalarField& p = vars_.p();
const volVectorField& U = vars_.U();
const autoPtr<incompressible::RASModelVariables>&
turbVars = vars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = vars_.laminarTransport();
volScalarField nuEff(lamTransp.nu() + turbVars->nutRef());
volTensorField gradU(fvc::grad(U));
// Explicitly correct the boundary gradient to get rid of the
// tangential component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
gradU.boundaryFieldRef()[patchI] =
nf * U.boundaryField()[patchI].snGrad();
}
}
volTensorField stress(nuEff*(gradU + T(gradU)));
stressXPtr_().replace(0, stress.component(0));
stressXPtr_().replace(1, stress.component(1));
stressXPtr_().replace(2, stress.component(2));
stressYPtr_().replace(0, stress.component(3));
stressYPtr_().replace(1, stress.component(4));
stressYPtr_().replace(2, stress.component(5));
stressZPtr_().replace(0, stress.component(6));
stressZPtr_().replace(1, stress.component(7));
stressZPtr_().replace(2, stress.component(8));
volTensorField gradStressX(fvc::grad(stressXPtr_()));
volTensorField gradStressY(fvc::grad(stressYPtr_()));
volTensorField gradStressZ(fvc::grad(stressZPtr_()));
volVectorField gradp(fvc::grad(p));
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
vectorField dx(patch.Cf() - rotationCentre_);
vectorField aux(momentDirection_^dx);
bdxdbMultPtr_()[patchI] =
(
(
(
-(aux.component(0) * gradStressX.boundaryField()[patchI])
-(aux.component(1) * gradStressY.boundaryField()[patchI])
-(aux.component(2) * gradStressZ.boundaryField()[patchI])
) & nf
)
+ (momentDirection_ & (dx^nf))*gradp.boundaryField()[patchI]
)
*invDenom_*rhoInf_;
}
}
void objectiveMoment::update_dxdbDirectMultiplier()
{
const volScalarField& p = vars_.p();
for (const label patchI : momentPatches_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
const vectorField dx(patch.Cf() - rotationCentre_);
const vectorField force
(
rhoInf_
*(
((p.boundaryField()[patchI]*nf)
+ (devReff_.boundaryField()[patchI] & nf))
)
);
bdxdbDirectMultPtr_()[patchI] =
(force^momentDirection_)*invDenom_*rhoInf_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectives
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,132 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectives::objectiveMoment
Description
SourceFiles
objectiveMoment.C
\*---------------------------------------------------------------------------*/
#ifndef objectiveMoment_H
#define objectiveMoment_H
#include "objectiveIncompressible.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
/*---------------------------------------------------------------------------*\
Class objectiveMoment Declaration
\*---------------------------------------------------------------------------*/
class objectiveMoment
:
public objectiveIncompressible
{
// Private data
labelHashSet momentPatches_;
vector momentDirection_;
vector rotationCentre_;
scalar Aref_;
scalar lRef_;
scalar rhoInf_;
scalar UInf_;
scalar invDenom_;
autoPtr<volVectorField> stressXPtr_;
autoPtr<volVectorField> stressYPtr_;
autoPtr<volVectorField> stressZPtr_;
// Store this in order to computed only once per objective call
volSymmTensorField devReff_;
public:
//- Runtime type information
TypeName("moment");
// Constructors
//- from components
objectiveMoment
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectiveMoment() = default;
// Member Functions
//- Return the objective function value
scalar J();
//- Update mean drag and lift values
void update_meanValues();
//- Update values to be added to the adjoint wall velocity
void update_boundarydJdp();
//- Update delta(n dS)/delta b multiplier
void update_dSdbMultiplier();
//- Update delta(x)/delta b multiplier
void update_dxdbMultiplier();
//- Update delta(x)/delta b multiplier coming directly from the
//- objective
void update_dxdbDirectMultiplier();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectiveMoment
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,279 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objectivePtLosses.H"
#include "createZeroField.H"
#include "coupledFvPatch.H"
#include "IOmanip.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(objectivePtLosses, 1);
addToRunTimeSelectionTable
(
objectiveIncompressible,
objectivePtLosses,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objectivePtLosses::objectivePtLosses
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
objectiveIncompressible(mesh, dict, adjointSolverName, primalSolverName),
patches_(0),
patchPt_(0)
{
// Find inlet/outlet patches
initialize();
// Allocate boundary field pointers
bdJdpPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdJdvPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
bdJdvnPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
bdJdvtPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void objectivePtLosses::initialize()
{
// If patches are prescribed, use them
if (dict().found("patches"))
{
labelHashSet patches
(
mesh_.boundaryMesh().patchSet
(
wordReList(dict().get<wordRes>("patches"))
)
);
patches_ = patches.toc();
}
// Otherwise, pick them up based on the mass flow.
// Note: a non-zero U initialisation should be used in order to pick up the
// outlet patches correctly
else
{
WarningInFunction
<< "No patches provided to PtLosses. Chossing them according to "
<< "the patch mass flows"
<< endl;
DynamicList<label> objectiveReportPatches(mesh_.boundary().size());
const surfaceScalarField& phi = vars_.phiInst();
forAll(mesh_.boundary(), patchI)
{
const fvsPatchScalarField& phiPatch = phi.boundaryField()[patchI];
if (!isA<coupledFvPatch>(mesh_.boundary()[patchI]))
{
const scalar mass = gSum(phiPatch);
if (mag(mass) > SMALL)
{
objectiveReportPatches.append(patchI);
}
}
}
patches_.transfer(objectiveReportPatches);
}
patchPt_.setSize(patches_.size());
if (patches_.empty())
{
FatalErrorInFunction
<< "No valid patch name on which to minimize " << type() << endl
<< exit(FatalError);
}
if (debug)
{
Info<< "Minimizing " << type() << " in patches:" << endl;
forAll(patches_, pI)
{
Info<< "\t " << mesh_.boundary()[patches_[pI]].name() << endl;
}
}
}
scalar objectivePtLosses::J()
{
J_ = Zero;
// References
const volScalarField& p = vars_.pInst();
const volVectorField& U = vars_.UInst();
// Inlet/outlet patches
forAll(patches_, oI)
{
const label patchI = patches_[oI];
const vectorField& Sf = mesh_.boundary()[patchI].Sf();
scalar pt = -gSum
(
(U.boundaryField()[patchI] & Sf)
*(
p.boundaryField()[patchI]
+ 0.5*magSqr(U.boundaryField()[patchI])
)
);
patchPt_[oI] = mag(pt);
J_ += pt;
}
return J_;
}
void objectivePtLosses::update_boundarydJdp()
{
const volVectorField& U = vars_.U();
forAll(patches_, oI)
{
const label patchI = patches_[oI];
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
bdJdpPtr_()[patchI] = -(U.boundaryField()[patchI] & nf)*nf;
}
}
void objectivePtLosses::update_boundarydJdv()
{
const volScalarField& p = vars_.p();
const volVectorField& U = vars_.U();
forAll(patches_, oI)
{
const label patchI = patches_[oI];
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
const fvPatchVectorField& Ub = U.boundaryField()[patchI];
bdJdvPtr_()[patchI] =
- (p.boundaryField()[patchI] + 0.5*magSqr(Ub))*nf
- (Ub & nf)*Ub;
}
}
void objectivePtLosses::update_boundarydJdvn()
{
const volScalarField& p = vars_.p();
const volVectorField& U = vars_.U();
forAll(patches_, oI)
{
const label patchI = patches_[oI];
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
bdJdvnPtr_()[patchI] =
- p.boundaryField()[patchI]
- 0.5*magSqr(U.boundaryField()[patchI])
- sqr(U.boundaryField()[patchI] & nf);
}
}
void objectivePtLosses::update_boundarydJdvt()
{
const volVectorField& U = vars_.U();
forAll(patches_, oI)
{
const label patchI = patches_[oI];
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
scalarField Un(U.boundaryField()[patchI] & nf);
bdJdvtPtr_()[patchI] = -Un*(U.boundaryField()[patchI] - Un*nf);
}
}
void objectivePtLosses::write() const
{
if (Pstream::master())
{
// file is opened only upon invocation of the write function
// in order to avoid various instantiations of the same objective
// opening the same file
unsigned int width = IOstream::defaultPrecision() + 5;
if (objFunctionFilePtr_.empty())
{
setObjectiveFilePtr();
objFunctionFilePtr_() << setw(4) << "#" << " ";
objFunctionFilePtr_() << setw(width) << "ptLosses" << " ";
forAll(patches_, oI)
{
label patchI = patches_[oI];
objFunctionFilePtr_()
<< setw(width) << mesh_.boundary()[patchI].name() << " ";
}
objFunctionFilePtr_() << endl;
}
objFunctionFilePtr_() << setw(4) << mesh_.time().value() << " ";
objFunctionFilePtr_() << setw(width) << J_ << " ";
forAll(patchPt_, pI)
{
objFunctionFilePtr_() << setw(width) << patchPt_[pI] << " ";
}
objFunctionFilePtr_() << endl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectives
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objectives::objectivePtLosses
Description
SourceFiles
objectivePtLosses.C
\*---------------------------------------------------------------------------*/
#ifndef objectivePtLosses_H
#define objectivePtLosses_H
#include "objectiveIncompressible.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace objectives
{
/*---------------------------------------------------------------------------*\
Class objectivePtLosses Declaration
\*---------------------------------------------------------------------------*/
class objectivePtLosses
:
public objectiveIncompressible
{
// Private data
labelList patches_;
scalarField patchPt_;
public:
//- Runtime type information
TypeName("PtLosses");
// Constructors
//- from components
objectivePtLosses
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objectivePtLosses() = default;
// Member Functions
//- Return the objectiveReportPatches
void initialize();
//- Return the objective function value
scalar J();
//- Update values to be added to the adjoint inlet velocity
void update_boundarydJdp();
//- Update values to be added to the adjoint outlet velocity
void update_boundarydJdv();
//- Update values to be added to the adjoint outlet pressure
void update_boundarydJdvn();
//- Update values to be added to the adjoint outlet tangential velocity
void update_boundarydJdvt();
//- Write objective function values and its contrituents
void write() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace objectivePtLosses
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,486 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "objective.H"
#include "createZeroField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(objective, 0);
defineRunTimeSelectionTable(objective, objective);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void objective::makeFolder()
{
if (Pstream::master())
{
const Time& time = mesh_.time();
objFunctionFolder_ =
time.globalPath()/"optimisation"/type()/time.timeName();
mkDir(objFunctionFolder_);
}
}
void objective::setObjectiveFilePtr() const
{
objFunctionFilePtr_.reset
(
new OFstream(objFunctionFolder_/objectiveName_ + adjointSolverName_)
);
}
void objective::setInstantValueFilePtr() const
{
instantValueFilePtr_.reset
(
new OFstream
(
objFunctionFolder_/objectiveName_ + "Instant" + adjointSolverName_
)
);
}
void objective::setMeanValueFilePtr() const
{
meanValueFilePtr_.reset
(
new OFstream
(
objFunctionFolder_/objectiveName_ + "Mean" + adjointSolverName_
)
);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
const dictionary& objective::dict() const
{
return dict_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
objective::objective
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
)
:
mesh_(mesh),
dict_(dict),
adjointSolverName_(adjointSolverName),
primalSolverName_(primalSolverName),
objectiveName_(dict.dictName()),
computeMeanFields_(false), // is reset in derived classes
J_(Zero),
JMean_(Zero),
weight_(Zero),
// Initialize pointers to nullptr.
// Not all of them are required for each objective function.
// Each child should allocate whatever is needed.
dJdbPtr_(nullptr),
bdJdbPtr_(nullptr),
bdSdbMultPtr_(nullptr),
bdndbMultPtr_(nullptr),
bdxdbMultPtr_(nullptr),
bdxdbDirectMultPtr_(nullptr),
bEdgeContribution_(nullptr),
bdJdStressPtr_(nullptr),
divDxDbMultPtr_(nullptr),
gradDxDbMultPtr_(nullptr),
objFunctionFolder_("word"),
objFunctionFilePtr_(nullptr),
instantValueFilePtr_(nullptr),
meanValueFilePtr_(nullptr)
{
makeFolder();
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<objective> objective::New
(
const fvMesh& mesh,
const dictionary& dict,
const word& objectiveType,
const word& adjointSolverName,
const word& primalSolverName
)
{
auto cstrIter = objectiveConstructorTablePtr_->cfind(objectiveType);
if (!cstrIter.found())
{
FatalErrorInFunction
<< "Unknown objective type " << objectiveType << nl << nl
<< "Valid types are :" << nl
<< objectiveConstructorTablePtr_->toc()
<< exit(FatalError);
}
return autoPtr<objective>
(
cstrIter()
(
mesh,
dict,
adjointSolverName,
primalSolverName
)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool objective::readDict(const dictionary& dict)
{
dict_ = dict;
return true;
}
void objective::updateNormalizationFactor()
{
// Does nothing in base
}
void objective::accumulateJMean(solverControl& solverControl)
{
if (solverControl.doAverageIter())
{
const label iAverageIter = solverControl.averageIter();
if (iAverageIter == 0)
{
JMean_ = Zero;
}
scalar avIter(iAverageIter);
scalar oneOverItP1 = 1./(avIter + 1);
scalar mult = avIter*oneOverItP1;
JMean_ = JMean_*mult + J_*oneOverItP1;
}
}
scalar objective::weight() const
{
return weight_;
}
const volScalarField& objective::dJdb()
{
if (dJdbPtr_.empty())
{
// If pointer is not set, set it to a zero field
dJdbPtr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("dJdb_" + objectiveName_),
dimensionSet(0, 5, -2, 0, 0, 0, 0)
)
);
}
return dJdbPtr_();
}
const fvPatchVectorField& objective::boundarydJdb(const label patchI)
{
if (bdJdbPtr_.empty())
{
bdJdbPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdbPtr_()[patchI];
}
const fvPatchVectorField& objective::dSdbMultiplier(const label patchI)
{
if (bdSdbMultPtr_.empty())
{
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdSdbMultPtr_()[patchI];
}
const fvPatchVectorField& objective::dndbMultiplier(const label patchI)
{
if (bdndbMultPtr_.empty())
{
bdndbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdndbMultPtr_()[patchI];
}
const fvPatchVectorField& objective::dxdbMultiplier(const label patchI)
{
if (bdxdbMultPtr_.empty())
{
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdxdbMultPtr_()[patchI];
}
const fvPatchVectorField& objective::dxdbDirectMultiplier(const label patchI)
{
if (bdxdbDirectMultPtr_.empty())
{
bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdxdbDirectMultPtr_()[patchI];
}
const vectorField& objective::boundaryEdgeMultiplier
(
const label patchI,
const label edgeI
)
{
if (bdxdbDirectMultPtr_.empty())
{
FatalErrorInFunction
<< "Unallocated boundaryEdgeMultiplier field"
<< exit(FatalError);
}
return bEdgeContribution_()[patchI][edgeI];
}
const fvPatchTensorField& objective::boundarydJdStress(const label patchI)
{
if (bdJdStressPtr_.empty())
{
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return bdJdStressPtr_()[patchI];
}
const boundaryVectorField& objective::boundarydJdb()
{
if (bdJdbPtr_.empty())
{
bdJdbPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdJdbPtr_();
}
const boundaryVectorField& objective::dSdbMultiplier()
{
if (bdSdbMultPtr_.empty())
{
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdSdbMultPtr_();
}
const boundaryVectorField& objective::dndbMultiplier()
{
if (bdndbMultPtr_.empty())
{
bdndbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdndbMultPtr_();
}
const boundaryVectorField& objective::dxdbMultiplier()
{
if (bdxdbMultPtr_.empty())
{
bdxdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdxdbMultPtr_();
}
const boundaryVectorField& objective::dxdbDirectMultiplier()
{
if (bdxdbDirectMultPtr_.empty())
{
bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
}
return bdxdbDirectMultPtr_();
}
const vectorField3& objective::boundaryEdgeMultiplier()
{
if (bdxdbDirectMultPtr_.empty())
{
FatalErrorInFunction
<< "Unallocated boundaryEdgeMultiplier field"
<< endl << endl
<< exit(FatalError);
}
return bEdgeContribution_();
}
const boundaryTensorField& objective::boundarydJdStress()
{
if (bdJdStressPtr_.empty())
{
bdJdStressPtr_.reset(createZeroBoundaryPtr<tensor>(mesh_));
}
return bdJdStressPtr_();
}
const volScalarField& objective::divDxDbMultiplier()
{
if (divDxDbMultPtr_.empty())
{
// If pointer is not set, set it to a zero field
divDxDbMultPtr_.reset
(
createZeroFieldPtr<scalar>
(
mesh_,
("divDxDbMult"+objectiveName_),
// Variable dimensions!!
// Dummy dimensionless. Only the internalField will be used
dimless
)
);
}
return divDxDbMultPtr_();
}
const volTensorField& objective::gradDxDbMultiplier()
{
if (gradDxDbMultPtr_.empty())
{
// If pointer is not set, set it to a zero field
gradDxDbMultPtr_.reset
(
createZeroFieldPtr<tensor>
(
mesh_,
("gradDxDbMult"+objectiveName_),
// Variable dimensions!!
dimensionSet(pow2(dimLength)/pow3(dimTime))
)
);
}
return gradDxDbMultPtr_();
}
void objective::write() const
{
if (Pstream::master())
{
// File is opened only upon invocation of the write function
// in order to avoid various instantiations of the same objective
// opening the same file
if (objFunctionFilePtr_.empty())
{
setObjectiveFilePtr();
}
objFunctionFilePtr_() << mesh_.time().value() << tab << J_ << endl;
}
}
void objective::writeInstantaneousValue() const
{
if (Pstream::master())
{
// File is opened only upon invocation of the write function
// in order to avoid various instantiations of the same objective
// opening the same file
if (instantValueFilePtr_.empty())
{
setInstantValueFilePtr();
}
instantValueFilePtr_() << mesh_.time().value() << tab << J_ << endl;
}
}
void objective::writeMeanValue() const
{
if (Pstream::master())
{
// Write mean value if necessary
if (computeMeanFields_)
{
// File is opened only upon invocation of the write function
// in order to avoid various instantiations of the same objective
// opening the same file
if (meanValueFilePtr_.empty())
{
setMeanValueFilePtr();
}
meanValueFilePtr_()
<< mesh_.time().value() << tab << JMean_ << endl;
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,365 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::objective
Description
Abstract base class for objective functions. No point in making this
runTime selectable since its children will have different constructors.
SourceFiles
objective.C
\*---------------------------------------------------------------------------*/
#ifndef objective_H
#define objective_H
#include "autoPtr.H"
#include "runTimeSelectionTables.H"
#include "OFstream.H"
#include "boundaryFieldsFwd.H"
#include "solverControl.H"
#include "objectiveFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class objective Declaration
\*---------------------------------------------------------------------------*/
class objective
{
protected:
// Protected data
const fvMesh& mesh_;
dictionary dict_;
const word adjointSolverName_;
const word primalSolverName_;
const word objectiveName_;
bool computeMeanFields_;
// Objective function value and weight
scalar J_;
scalar JMean_; //average value
scalar weight_;
// Contribution to field sensitivity derivatives
// Topology optimisation
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
autoPtr<volScalarField> dJdbPtr_;
// Contribution to surface sensitivity derivatives
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//- Term from material derivative
autoPtr<boundaryVectorField> bdJdbPtr_;
//- Term multiplying delta(n dS)/delta b
autoPtr<boundaryVectorField> bdSdbMultPtr_;
//- Term multiplying delta(n)/delta b
autoPtr<boundaryVectorField> bdndbMultPtr_;
//- Term multiplying delta(x)/delta b at the boundary
autoPtr<boundaryVectorField> bdxdbMultPtr_;
//- Term multiplying delta(x)/delta b at the boundary
//- for objectives that directly depend on x, e.g. moment
//- Needed in both FI and SI computations
autoPtr<boundaryVectorField> bdxdbDirectMultPtr_;
//- Contribution located in specific parts of a patch.
//- Mainly intended for patch boundary edges contributions, e.g.
//- NURBS surfaces G1 continuity
autoPtr<vectorField3> bEdgeContribution_;
//- For use with discrete-like sensitivities
autoPtr<boundaryTensorField> bdJdStressPtr_;
// Contribution to volume-based sensitivities from volume-based
// objective functions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//- Multiplier of d(Volume)/db
autoPtr<volScalarField> divDxDbMultPtr_;
//- Emerging from volume objectives that include spatial derivatives
autoPtr<volTensorField> gradDxDbMultPtr_;
//- Output file variables
fileName objFunctionFolder_;
//- File to keep the objective values after the end of the primal solver
mutable autoPtr<OFstream> objFunctionFilePtr_;
//- File to keep the objective values at each iteration of the primal
//- solver
mutable autoPtr<OFstream> instantValueFilePtr_;
//- File to keep the average objective values after the end of the
//- primal solver
mutable autoPtr<OFstream> meanValueFilePtr_;
// Protected Member Functions
//- Return objective dictionary
const dictionary& dict() const;
//- Set the output file ptr
void setObjectiveFilePtr() const;
//- Set the output file ptr for the instantaneous value
void setInstantValueFilePtr() const;
//- Set the output file ptr for the mean value
void setMeanValueFilePtr() const;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
objective(const objective&) = delete;
//- Disallow default bitwise assignment
void operator=(const objective&) = delete;
//- Make objective Function Folder
void makeFolder();
public:
//- Runtime type information
TypeName("objective");
// Declare run-time constructor selection table
declareRunTimeNewSelectionTable
(
autoPtr,
objective,
objective,
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
),
(mesh, dict, adjointSolverName, primalSolverName)
);
// Constructors
//- Construct from components
objective
(
const fvMesh& mesh,
const dictionary& dict,
const word& adjointSolverName,
const word& primalSolverName
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<objective> New
(
const fvMesh& mesh,
const dictionary& dict,
const word& objectiveType,
const word& adjointSolverName,
const word& primalSolverName
);
//- Destructor
virtual ~objective() = default;
// Member Functions
virtual bool readDict(const dictionary& dict);
//- Return the objective function value
virtual scalar J() = 0;
//- Accumulate contribution for the mean objective value
void accumulateJMean(solverControl& solverControl);
//- Return the objective function weight
scalar weight() const;
//- Contribution to field sensitivities
const volScalarField& dJdb();
//- Contribution to surface sensitivities for a specific patch
const fvPatchVectorField& boundarydJdb(const label);
//- Multiplier of delta(n dS)/delta b
const fvPatchVectorField& dSdbMultiplier(const label);
//- Multiplier of delta(n dS)/delta b
const fvPatchVectorField& dndbMultiplier(const label);
//- Multiplier of delta(x)/delta b
const fvPatchVectorField& dxdbMultiplier(const label);
//- Multiplier of delta(x)/delta b
const fvPatchVectorField& dxdbDirectMultiplier(const label);
//- Multiplier located at patch boundary edges
const vectorField& boundaryEdgeMultiplier
(
const label patchI,
const label edgeI
);
//- Objective partial deriv wrt stress tensor
const fvPatchTensorField& boundarydJdStress(const label);
//- Contribution to surface sensitivities for all patches
const boundaryVectorField& boundarydJdb();
//- Multiplier of delta(n dS)/delta b for all patches
const boundaryVectorField& dSdbMultiplier();
//- Multiplier of delta(n dS)/delta b for all patches
const boundaryVectorField& dndbMultiplier();
//- Multiplier of delta(x)/delta b for all patches
const boundaryVectorField& dxdbMultiplier();
//- Multiplier of delta(x)/delta b for all patches
const boundaryVectorField& dxdbDirectMultiplier();
//- Multiplier located at patch boundary edges
const vectorField3& boundaryEdgeMultiplier();
//- Objective partial deriv wrt stress tensor
const boundaryTensorField& boundarydJdStress();
//- Multiplier of grad( delta(x)/delta b) for volume-based sensitivities
const volScalarField& divDxDbMultiplier();
//- Multiplier of grad( delta(x)/delta b) for volume-based sensitivities
const volTensorField& gradDxDbMultiplier();
//- Update objective function derivatives
virtual void update() = 0;
//- Update normalization factors, for objectives in
//- which the factor is not known a priori
virtual void updateNormalizationFactor();
//- Update objective function derivative term
virtual void update_boundarydJdb()
{}
//- Update d (normal dS) / db multiplier. Surface-based sensitivity term
virtual void update_dSdbMultiplier()
{}
//- Update d (normal) / db multiplier. Surface-based sensitivity term
virtual void update_dndbMultiplier()
{}
//- Update d (x) / db multiplier. Surface-based sensitivity term
virtual void update_dxdbMultiplier()
{}
//- Update d (x) / db multiplier. Surface and volume-based sensitivity
//- term
virtual void update_dxdbDirectMultiplier()
{}
//- Update boundary edge contributions
virtual void update_boundaryEdgeContribution()
{}
//- Update dJ/dStress field
virtual void update_dJdStressMultiplier()
{}
//- Update div( dx/db multiplier). Volume-based sensitivity term
virtual void update_divDxDbMultiplier()
{}
//- Update grad( dx/db multiplier). Volume-based sensitivity term
virtual void update_gradDxDbMultiplier()
{}
//- Write objective function history
virtual void write() const;
//- Write objective function history at each primal solver iteration
virtual void writeInstantaneousValue() const;
//- Write mean objective function history
virtual void writeMeanValue() const;
// Inline functions for checking whether pointers are set or not
inline const word& objectiveName() const;
inline bool hasdJdb();
inline bool hasBoundarydJdb();
inline bool hasdSdbMult();
inline bool hasdndbMult();
inline bool hasdxdbMult();
inline bool hasdxdbDirectMult();
inline bool hasBoundaryEdgeContribution();
inline bool hasBoundarydJdStress();
inline bool hasDivDxDbMult();
inline bool hasGradDxDbMult();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "objectiveI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
#ifndef objectiveFwd_H
#define objectiveFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef Field<Field<vectorField>> vectorField3;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::word& Foam::objective::objectiveName() const
{
return objectiveName_;
}
inline bool Foam::objective::hasdJdb()
{
return dJdbPtr_.valid();
}
inline bool Foam::objective::hasBoundarydJdb()
{
return bdJdbPtr_.valid();
}
inline bool Foam::objective::hasdSdbMult()
{
return bdSdbMultPtr_.valid();
}
inline bool Foam::objective::hasdndbMult()
{
return bdndbMultPtr_.valid();
}
inline bool Foam::objective::hasdxdbMult()
{
return bdxdbMultPtr_.valid();
}
inline bool Foam::objective::hasdxdbDirectMult()
{
return bdxdbDirectMultPtr_.valid();
}
inline bool Foam::objective::hasBoundaryEdgeContribution()
{
return bEdgeContribution_.valid();
}
inline bool Foam::objective::hasDivDxDbMult()
{
return divDxDbMultPtr_.valid();
}
inline bool Foam::objective::hasGradDxDbMult()
{
return gradDxDbMultPtr_.valid();
}
inline bool Foam::objective::hasBoundarydJdStress()
{
return bdJdStressPtr_.valid();
}
// ************************************************************************* //

View File

@ -0,0 +1,300 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointEikonalSolverIncompressible.H"
#include "wallFvPatch.H"
#include "patchDistMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(adjointEikonalSolver, 0);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
wordList adjointEikonalSolver::patchTypes() const
{
wordList daTypes
(
mesh_.boundary().size(),
fixedValueFvPatchScalarField::typeName
);
for (const label patchi : wallPatchIDs_)
{
daTypes[patchi] = zeroGradientFvPatchScalarField::typeName;
}
return daTypes;
}
void adjointEikonalSolver::read()
{
nEikonalIters_ = dict_.lookupOrDefault<label>("iters", 1000);
tolerance_ = dict_.lookupOrDefault<scalar>("tolerance", 1e-6);
epsilon_ = dict_.lookupOrDefault<scalar>("epsilon", 0.1);
}
tmp<surfaceScalarField> adjointEikonalSolver::computeYPhi()
{
// Primal distance field
const volScalarField& d = RASModelVars_().d();
volVectorField ny
(
IOobject
(
"ny",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh_,
dimensionedVector(dimless, Zero),
patchDistMethod::patchTypes<vector>(mesh_, wallPatchIDs_)
);
const fvPatchList& patches = mesh_.boundary();
volVectorField::Boundary& nybf = ny.boundaryFieldRef();
for (const label patchi : wallPatchIDs_)
{
nybf[patchi] == -patches[patchi].nf();
}
ny = fvc::grad(d);
surfaceVectorField nf(fvc::interpolate(ny));
return tmp<surfaceScalarField>::New("yPhi", mesh_.Sf() & nf);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
adjointEikonalSolver::adjointEikonalSolver
(
const fvMesh& mesh,
const dictionary& dict,
const autoPtr<incompressible::RASModelVariables>& RASModelVars,
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>& adjointTurbulence,
const labelList& sensitivityPatchIDs
)
:
mesh_(mesh),
dict_(dict.subOrEmptyDict("adjointEikonalSolver")),
RASModelVars_(RASModelVars),
adjointTurbulence_(adjointTurbulence),
sensitivityPatchIDs_(sensitivityPatchIDs),
nEikonalIters_(-1),
tolerance_(-1),
epsilon_(Zero),
wallPatchIDs_(mesh_.boundaryMesh().findPatchIDs<wallPolyPatch>()),
da_
(
IOobject
(
"da",
mesh_.time().timeName(),
mesh_,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedScalar(sqr(dimLength)/pow3(dimTime), Zero),
patchTypes()
),
distanceSensPtr_(createZeroBoundaryPtr<vector>(mesh_))
{
read();
};
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool adjointEikonalSolver::readDict(const dictionary& dict)
{
dict_ = dict.subOrEmptyDict("adjointEikonalSolver");
return true;
}
void adjointEikonalSolver::solve()
{
read();
// Primal distance field
const volScalarField& d = RASModelVars_().d();
// Populate the source term. Not dependent from da, so only
// need to update it once per optimisation cycle
tmp<volScalarField> tsource = adjointTurbulence_->distanceSensitivities();
const volScalarField& source = tsource();
// Convecting flux
tmp<surfaceScalarField> tyPhi = computeYPhi();
const surfaceScalarField& yPhi = tyPhi();
// Iterate the adjoint to the eikonal equation
for (label iter = 0; iter < nEikonalIters_; ++iter)
{
read();
Info<< "Adjoint Eikonal Iteration : " << iter << endl;
fvScalarMatrix daEqn
(
2*fvm::div(-yPhi, da_)
+ fvm::SuSp(-epsilon_*fvc::laplacian(d), da_)
- epsilon_*fvm::laplacian(d, da_)
+ source
);
daEqn.relax();
scalar residual = daEqn.solve().initialResidual();
Info<< "Max da " << gMax(mag(da_)()) << endl;
Info<< "ExecutionTime = " << mesh_.time().elapsedCpuTime() << " s"
<< " ClockTime = " << mesh_.time().elapsedClockTime() << " s"
<< nl << endl;
// Check convergence
if (residual < tolerance_)
{
Info<< "\n***Reached adjoint eikonal convergence limit, iteration "
<< iter << "***\n\n";
break;
}
}
da_.write();
}
boundaryVectorField& adjointEikonalSolver::distanceSensitivities()
{
Info<< "Calculating distance sensitivities " << endl;
boundaryVectorField& distanceSens = distanceSensPtr_();
const volScalarField& d = RASModelVars_().d();
for (const label patchi : sensitivityPatchIDs_)
{
vectorField nf(mesh_.boundary()[patchi].nf());
// No surface area included. Will be done by the actual sensitivity tool
distanceSens[patchi] =
-2.*da_.boundaryField()[patchi]
*d.boundaryField()[patchi].snGrad()
*d.boundaryField()[patchi].snGrad()*nf;
}
return distanceSens;
}
tmp<volTensorField> adjointEikonalSolver::getFISensitivityTerm() const
{
Info<< "Calculating distance sensitivities " << endl;
const volScalarField& d = RASModelVars_().d();
const volVectorField gradD(fvc::grad(d));
volVectorField gradDDa
(
IOobject
(
"gradDDa",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedVector(d.dimensions()*da_.dimensions()/dimLength, Zero),
patchDistMethod::patchTypes<vector>(mesh_, wallPatchIDs_)
);
gradDDa = fvc::grad(d*da_);
tmp<volTensorField> tdistanceSens
(
new volTensorField
(
IOobject
(
"distanceSensFI",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh_,
dimensionedTensor(da_.dimensions(), Zero)
)
);
volTensorField& distanceSens = tdistanceSens.ref();
distanceSens =
- 2.*da_*gradD*gradD
- epsilon_*gradD*gradDDa
+ epsilon_*da_*d*fvc::grad(gradD);
return tdistanceSens;
}
const volScalarField& adjointEikonalSolver::da()
{
return da_;
}
tmp<volVectorField> adjointEikonalSolver::gradEikonal()
{
const volScalarField& d = RASModelVars_().d();
volVectorField gradD(fvc::grad(d));
return tmp<volVectorField>::New("gradEikonal", 2*gradD & fvc::grad(gradD));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,259 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::adjointEikonalSolver
Description
Solver of the adjoint to the eikonal PDE
Reference:
\verbatim
For the development of the adjoint eikonal PDE and its boundary
conditions
Papoutsis-Kiachagias, E. M., & Giannakoglou, K. C. (2014).
Continuous Adjoint Methods for Turbulent Flows, Applied to Shape
and Topology Optimization: Industrial Applications.
Archives of Computational Methods in Engineering, 23(2), 255-299.
http://doi.org/10.1007/s11831-014-9141-9
\endverbatim
To be as consistent as possible, it is recommended to use the
advectionDiffusion wallDist method in fvSchemes, instead of the more widely
used meshWave
Example of the adjointEikonalSolver specification in optimisationDict:
\verbatim
optimisation
{
sensitivities
{
includeDistance true;
adjointEikonalSolver
{
// epsilon should be the same as the one used
// in fvSchemes/wallDist/advectionDiffusionCoeffs
epsilon 0.1;
iters 1000;
tolerance 1e-6;
}
}
}
\endverbatim
Example of the entries in fvSchemes:
\verbatim
divSchemes
{
.
.
// avoid bounded schemes since yPhi is not conservative
div(-yPhi,da) Gauss linearUpwind grad(da);
.
.
}
laplacianSchemes
{
.
.
laplacian(yWall,da) Gauss linear corrected;
.
.
}
\endverbatim
Also, the solver specification and a relaxation factor for da are required
in fvSolution
\verbatim
da
{
solver PBiCGStab;
preconditioner DILU;
tolerance 1e-9;
relTol 0.1;
}
relaxationFactors
{
equations
{
.
.
da 0.5;
.
.
}
}
\endverbatim
See also
Foam::patchDistMethod::advectionDiffusion
Foam::wallDist
SourceFiles
adjointEikonalSolver.C
\*---------------------------------------------------------------------------*/
#ifndef adjointEikonalSolverIncompressible_H
#define adjointEikonalSolverIncompressible_H
#include "IOdictionary.H"
#include "adjointRASModel.H"
#include "createZeroField.H"
#include "boundaryFieldsFwd.H"
#include "RASModelVariables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class adjointEikonalSolver Declaration
\*---------------------------------------------------------------------------*/
class adjointEikonalSolver
{
private:
// Private Member Functions
//- No copy construct
adjointEikonalSolver(const adjointEikonalSolver&) = delete;
//- No copy assignment
void operator=(const adjointEikonalSolver&) = delete;
protected:
// Protected data
const fvMesh& mesh_;
dictionary dict_;
const autoPtr<incompressible::RASModelVariables>& RASModelVars_;
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>&
adjointTurbulence_;
const labelList& sensitivityPatchIDs_;
label nEikonalIters_;
scalar tolerance_;
scalar epsilon_;
labelHashSet wallPatchIDs_;
volScalarField da_;
//- Wall face sens w.r.t. (x,y.z)
autoPtr<boundaryVectorField> distanceSensPtr_;
// Protected functions
//- Return the boundary condition types for da
wordList patchTypes() const;
//- Compute convecting velocity
tmp<surfaceScalarField> computeYPhi();
//- Read options each time a new solution is found
void read();
public:
//- Runtime type information
TypeName("adjointEikonalSolver");
// Constructors
//- Construct from components
adjointEikonalSolver
(
const fvMesh& mesh,
const dictionary& dict,
const autoPtr<incompressible::RASModelVariables>& RASModelVars,
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>&
adjointTurbulence,
const labelList& sensitivityPatchIDs
);
// Destructor
virtual ~adjointEikonalSolver() = default;
// Member Functions
//- Read dict if changed
virtual bool readDict(const dictionary& dict);
//- Calculate the adjoint distance field
void solve();
//- Return the sensitivity term depending on da
boundaryVectorField& distanceSensitivities();
//- Return the volume-based sensitivity term depending on da
tmp<volTensorField> getFISensitivityTerm() const;
//- Return the adjoint distance field
const volScalarField& da();
//- Return the distance field
const volScalarField& d();
//- Return the gradient of the eikonal equation
tmp<volVectorField> gradEikonal();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "adjointMeshMovementSolverIncompressible.H"
#include "subCycleTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(adjointMeshMovementSolver, 0);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void adjointMeshMovementSolver::read()
{
nLaplaceIters_ = dict_.lookupOrDefault<label>("iters", 1000);
tolerance_ = dict_.lookupOrDefault<scalar>("tolerance", 1e-6);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
adjointMeshMovementSolver::adjointMeshMovementSolver
(
const fvMesh& mesh,
const dictionary& dict,
Foam::incompressible::adjointSensitivity& adjointSensitivity,
const labelList& sensitivityPatchIDs,
const autoPtr<adjointEikonalSolver>& adjointEikonalSolverPtr
)
:
mesh_(mesh),
dict_(dict.subOrEmptyDict("adjointMeshMovementSolver")),
adjointSensitivity_(adjointSensitivity),
sensitivityPatchIDs_(sensitivityPatchIDs),
nLaplaceIters_(-1),
tolerance_(-1),
ma_
(
variablesSet::autoCreateMeshMovementField
(
mesh,
"ma",
dimensionSet(pow3(dimLength/dimTime))
)
),
meshMovementSensPtr_(createZeroBoundaryPtr<vector>(mesh_)),
adjointEikonalSolverPtr_(adjointEikonalSolverPtr)
{
read();
};
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool adjointMeshMovementSolver::readDict(const dictionary& dict)
{
dict_ = dict.subOrEmptyDict("adjointMeshMovementSolver");
return true;
}
void adjointMeshMovementSolver::solve()
{
read();
// Compute source term
tmp<volVectorField> tsource
(
adjointSensitivity_.adjointMeshMovementSource()
);
volVectorField& source = tsource.ref();
if (adjointEikonalSolverPtr_.valid())
{
source -=
fvc::div(adjointEikonalSolverPtr_().getFISensitivityTerm()().T());
}
// Iterate the adjoint to the eikonal equation
for (label iter = 0; iter < nLaplaceIters_; iter++)
{
Info<< "Adjoint Mesh Movement Iteration: " << iter << endl;
fvVectorMatrix maEqn
(
fvm::laplacian(ma_)
+ source
);
maEqn.boundaryManipulate(ma_.boundaryFieldRef());
//scalar residual = max(maEqn.solve().initialResidual());
scalar residual = mag(maEqn.solve().initialResidual());
Info<< "Max ma " << gMax(mag(ma_)()) << endl;
Info<< "ExecutionTime = " << mesh_.time().elapsedCpuTime() << " s"
<< " ClockTime = " << mesh_.time().elapsedClockTime() << " s"
<< nl << endl;
// Check convergence
if (residual < tolerance_)
{
Info<< "\n***Reached adjoint mesh movement convergence limit, "
"iteration " << iter << "***\n\n";
break;
}
}
ma_.write();
}
boundaryVectorField& adjointMeshMovementSolver::meshMovementSensitivities()
{
Info<< "Calculating mesh movement sensitivities " << endl;
boundaryVectorField& meshMovementSens = meshMovementSensPtr_();
for (const label patchi : sensitivityPatchIDs_)
{
// No surface area included. Will be done by the actual sensitivity tool
meshMovementSens[patchi] = -ma_.boundaryField()[patchi].snGrad();
}
return meshMovementSens;
}
const volVectorField& adjointMeshMovementSolver::ma()
{
return ma_;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::adjointMeshMovementSolver
Description
Solver of the adjoint to the Laplace grid displacement equation
Reference:
\verbatim
Kavvadias, I., Papoutsis-Kiachagias, E., & Giannakoglou, K. (2015).
On the proper treatment of grid sensitivities in continuous adjoint
methods for shape optimization.
Journal of Computational Physics, 301, 118.
http://doi.org/10.1016/j.jcp.2015.08.012
\endverbatim
SourceFiles
adjointMeshMovementSolver.C
\*---------------------------------------------------------------------------*/
#ifndef adjointMeshMovementSolverIncompressible_H
#define adjointMeshMovementSolverIncompressible_H
#include "adjointSensitivityIncompressible.H"
#include "adjointEikonalSolverIncompressible.H"
#include "createZeroField.H"
#include "boundaryFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class adjointMeshMovementSolver Declaration
\*---------------------------------------------------------------------------*/
class adjointMeshMovementSolver
{
protected:
// Protected data
const fvMesh& mesh_;
dictionary dict_;
Foam::incompressible::adjointSensitivity& adjointSensitivity_;
const labelList& sensitivityPatchIDs_;
label nLaplaceIters_;
scalar tolerance_;
volVectorField ma_;
//- Wall face sens w.r.t.(x, y.z) //wall face sens w.r.t. (x,y.z)
autoPtr<boundaryVectorField> meshMovementSensPtr_;
const autoPtr<adjointEikonalSolver>& adjointEikonalSolverPtr_;
//- Read options each time a new solution is found
void read();
private:
// Private Member Functions
//- Disallow default bitwise copy construct
adjointMeshMovementSolver(const adjointMeshMovementSolver&) = delete;
//- Disallow default bitwise assignment
void operator=(const adjointMeshMovementSolver&) = delete;
public:
//- Runtime type information
TypeName("adjointMeshMovementSolver");
// Constructors
//- Construct from components
adjointMeshMovementSolver
(
const fvMesh& mesh,
const dictionary& dict,
Foam::incompressible::adjointSensitivity& adjointSensitivity,
const labelList& sensitivityPatchIDs,
const autoPtr<adjointEikonalSolver>& adjointEikonalSolverPtr
);
//- Destructor
virtual ~adjointMeshMovementSolver() = default;
// Member Functions
//- Read dict if changed
virtual bool readDict(const dictionary& dict);
//- Calculate the adjoint distance field
void solve();
//- Return the sensitivity term depending on da
boundaryVectorField& meshMovementSensitivities();
//- Return the adjoint distance field
const volVectorField& ma();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,341 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "runTimeSelectionTables.H"
#include "adjointSensitivityIncompressible.H"
#include "boundaryAdjointContribution.H"
#include "incompressibleAdjointSolver.H"
#include "wallFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(adjointSensitivity, 0);
defineRunTimeSelectionTable(adjointSensitivity, dictionary);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
adjointSensitivity::adjointSensitivity
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
)
:
sensitivity(mesh, dict, objectiveManager.adjointSolverName()),
primalVars_(primalVars),
adjointVars_(adjointVars),
objectiveManager_(objectiveManager),
fvOptionsAdjoint_(fvOptionsAdjoint)
{}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
autoPtr<adjointSensitivity> adjointSensitivity::New
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
)
{
const word sensitivityType(dict.get<word>("type"));
Info<< "adjointSensitivity type : " << sensitivityType << endl;
auto cstrIter = dictionaryConstructorTablePtr_->cfind(sensitivityType);
if (!cstrIter.found())
{
FatalIOErrorInFunction(dict)
<< "Unknown adjointSensitivity type " << sensitivityType
<< nl << nl
<< "Valid adjointSensitivity types are :" << nl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalIOError);
}
return autoPtr<adjointSensitivity>
(
cstrIter()
(
mesh,
dict,
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
void adjointSensitivity::write(const word& baseName)
{
sensitivity::write(baseName);
}
tmp<volTensorField> adjointSensitivity::computeGradDxDbMultiplier()
{
// Term depending on the adjoint turbulence model
autoPtr<incompressibleAdjoint::adjointRASModel>& adjointRAS
(
adjointVars_.adjointTurbulence()
);
tmp<volTensorField> tturbulenceTerm(adjointRAS->FISensitivityTerm());
volTensorField& turbulenceTerm = tturbulenceTerm.ref();
// nu effective
tmp<volScalarField> tnuEff(adjointRAS->nuEff());
const volScalarField& nuEff = tnuEff();
tmp<volTensorField> tflowTerm
(
new volTensorField
(
IOobject
(
"flowTerm",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedTensor(sqr(dimLength)/pow3(dimTime), Zero)
)
);
volTensorField& flowTerm = tflowTerm.ref();
const volScalarField& p = primalVars_.p();
const volVectorField& U = primalVars_.U();
const volScalarField& pa = adjointVars_.pa();
const volVectorField& Ua = adjointVars_.Ua();
volTensorField gradU(fvc::grad(U));
volTensorField gradUa(fvc::grad(Ua));
// Explicitly correct the boundary gradient to get rid of
// the tangential component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
gradU.boundaryFieldRef()[patchI] =
nf*U.boundaryField()[patchI].snGrad();
//gradUa.boundaryField()[patchI] =
// nf*Ua.boundaryField()[patchI].snGrad();
}
}
volTensorField stress(nuEff*(gradU + T(gradU)));
autoPtr<volVectorField> stressXPtr
(
createZeroFieldPtr<vector>(mesh_, "stressX", stress.dimensions())
);
autoPtr<volVectorField> stressYPtr
(
createZeroFieldPtr<vector>(mesh_, "stressY", stress.dimensions())
);
autoPtr<volVectorField> stressZPtr
(
createZeroFieldPtr<vector>(mesh_, "stressZ", stress.dimensions())
);
stressXPtr().replace(0, stress.component(0));
stressXPtr().replace(1, stress.component(1));
stressXPtr().replace(2, stress.component(2));
stressYPtr().replace(0, stress.component(3));
stressYPtr().replace(1, stress.component(4));
stressYPtr().replace(2, stress.component(5));
stressZPtr().replace(0, stress.component(6));
stressZPtr().replace(1, stress.component(7));
stressZPtr().replace(2, stress.component(8));
volTensorField gradStressX(fvc::grad(stressXPtr()));
volTensorField gradStressY(fvc::grad(stressYPtr()));
volTensorField gradStressZ(fvc::grad(stressZPtr()));
// Contribution from objective functions and constraints
volTensorField objectiveContributions
(
IOobject
(
"objectiveContributions",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedTensor(sqr(dimLength)/pow3(dimTime), Zero)
);
PtrList<objective>& functions(objectiveManager_.getObjectiveFunctions());
forAll(functions, funcI)
{
objectiveContributions +=
functions[funcI].weight()
*functions[funcI].gradDxDbMultiplier();
}
// Note:
// term4 (Ua & grad(stress)) is numerically tricky. Its div leads to third
// order spatial derivs in E-SI based computations Applying the product
// derivative rule (putting Ua inside the grad) gives better results in
// NACA0012, SA, WF. However, the original formulation should be kept at
// the boundary in order to respect the Ua boundary conditions (necessary
// for E-SI to give the same sens as FI). A mixed approach is hence
// followed
volTensorField term4
(
- nuEff*(gradUa & (gradU + T(gradU)))
+ fvc::grad(nuEff * Ua & (gradU + T(gradU)))
);
forAll(mesh_.boundary(), pI)
{
if (!isA<coupledFvPatch>(mesh_.boundary()[pI]))
{
term4.boundaryFieldRef()[pI] =
Ua.component(0)().boundaryField()[pI]
*gradStressX.boundaryField()[pI]
+ Ua.component(1)().boundaryField()[pI]
*gradStressY.boundaryField()[pI]
+ Ua.component(2)().boundaryField()[pI]
*gradStressZ.boundaryField()[pI];
}
}
const autoPtr<ATCModel>& ATCModel =
mesh_.lookupObject<incompressibleAdjointSolver>
(
objectiveManager_.adjointSolverName()
).getATCModel();
// Compute dxdb multiplier
flowTerm =
// Term 1, ATC
ATCModel->getFISensitivityTerm()
// Term 2
- fvc::grad(p) * Ua
// Term 3
- nuEff*(gradU & (gradUa + T(gradUa)))
// Term 4
+ term4
// Term 5
+ (pa * gradU)
// Term 6, from the adjoint turbulence model
+ turbulenceTerm.T()
// Term 7, term from objective functions
+ objectiveContributions;
// Correct boundary conditions for the flow term.
// Needed since the div of this term is often used
forAll(mesh_.boundary(), pI)
{
const fvPatch& patch = mesh_.boundary()[pI];
bool isSensPatch(false);
forAll(sensitivityPatchIDs_, pJ)
{
label patchJ = sensitivityPatchIDs_[pJ];
if (patchJ == pI)
{
isSensPatch = true;
break;
}
}
if (!isSensPatch && !isA<coupledFvPatch>(patch))
{
flowTerm.boundaryFieldRef()[pI] =
tensorField(patch.size(), tensor::zero);
}
}
flowTerm.correctBoundaryConditions();
return (tflowTerm);
}
tmp<volVectorField> adjointSensitivity::adjointMeshMovementSource()
{
tmp<volTensorField> tgradDxDbMult = computeGradDxDbMultiplier();
volTensorField& gradDxDbMult = tgradDxDbMult.ref();
tmp<volVectorField> tadjointMeshMovementSource
(
new volVectorField
(
IOobject
(
"adjointMeshMovementSource",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh_,
dimensionedVector(gradDxDbMult.dimensions()/dimLength, Zero)
)
);
volVectorField& source = tadjointMeshMovementSource.ref();
source -= fvc::div(gradDxDbMult.T());
return (tadjointMeshMovementSource);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,195 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::adjointSensitivity
Description
Abstract base class for adjoint-based sensitivities in incompressible flows
Reference:
\verbatim
For the FI and ESI formulations
Kavvadias, I., Papoutsis-Kiachagias, E., & Giannakoglou, K. (2015).
On the proper treatment of grid sensitivities in continuous adjoint
methods for shape optimization.
Journal of Computational Physics, 301, 118.
http://doi.org/10.1016/j.jcp.2015.08.012
For the SI formulation
Papoutsis-Kiachagias, E. M., & Giannakoglou, K. C. (2014).
Continuous Adjoint Methods for Turbulent Flows, Applied to Shape
and Topology Optimization: Industrial Applications.
Archives of Computational Methods in Engineering, 23(2), 255299.
http://doi.org/10.1007/s11831-014-9141-9
\endverbatim
SourceFiles
adjointSensitivity.C
\*---------------------------------------------------------------------------*/
#ifndef adjointSensitivityIncompressible_H
#define adjointSensitivityIncompressible_H
#include "sensitivity.H"
#include "incompressibleVars.H"
#include "incompressibleAdjointVars.H"
#include "fvOptionAdjointList.H"
#include "wallFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class adjointSensitivity Declaration
\*---------------------------------------------------------------------------*/
class adjointSensitivity
:
public sensitivity
{
protected:
// Protected data
incompressibleVars& primalVars_;
incompressibleAdjointVars& adjointVars_;
objectiveManager& objectiveManager_;
fv::optionAdjointList& fvOptionsAdjoint_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
adjointSensitivity(const adjointSensitivity&) = delete;
//- Disallow default bitwise assignment
void operator=(const adjointSensitivity&) = delete;
public:
//- Runtime type information
TypeName("adjointSensitivity");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
adjointSensitivity,
dictionary,
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
),
(
mesh,
dict,
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
)
);
// Constructors
//- Construct from components
adjointSensitivity
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
);
// Selectors
//- Return a reference to the selected turbulence model
static autoPtr<adjointSensitivity> New
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
);
//- Destructor
virtual ~adjointSensitivity() = default;
// Member Functions
//- Calculates and returns sensitivity fields.
// Used with optimisation libraries
virtual const scalarField& calculateSensitivities() = 0;
//- Write sensitivity fields.
// If valid, copies boundaryFields to volFields and writes them.
// Virtual to be reimplemented by control points-based methods
// (Bezier, RBF) which do not need to write fields
virtual void write(const word& baseName = word::null);
//- Compute the volTensorField multiplying grad(dxdb) for
//- the volume-based approach to compute shape sensitivity derivatives
tmp<volTensorField> computeGradDxDbMultiplier();
//- Compute source term for adjoint mesh movement equation
tmp<volVectorField> adjointMeshMovementSource();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,142 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "sensitivityMultipleIncompressible.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(sensitivityMultiple, 0);
addToRunTimeSelectionTable
(
adjointSensitivity,
sensitivityMultiple,
dictionary
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
sensitivityMultiple::sensitivityMultiple
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
)
:
adjointSensitivity
(
mesh,
dict,
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
),
sensTypes_(dict.subDict("sensTypes").toc()),
sens_(sensTypes_.size()),
derivatives_(0)
{
forAll(sensTypes_, sI)
{
sens_.set
(
sI,
adjointSensitivity::New
(
mesh,
dict.subDict("sensTypes").subDict(sensTypes_[sI]),
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
)
);
}
};
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool sensitivityMultiple::readDict(const dictionary& dict)
{
if (sensitivity::readDict(dict))
{
forAll(sens_, sI)
{
sens_[sI].readDict
(
dict.subDict("sensTypes").subDict(sensTypes_[sI])
);
}
return true;
}
return false;
}
const scalarField& sensitivityMultiple::calculateSensitivities()
{
forAll(sens_, sI)
{
Info<< "Computing sensitivities " << sensTypes_[sI] << endl;
sens_[sI].calculateSensitivities();
}
write(type());
return (derivatives_);
}
void sensitivityMultiple::write(const word& baseName)
{
forAll(sens_, sI)
{
sens_[sI].write(sensTypes_[sI]);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::sensitivityMultiple
Description
Calculation of adjoint based sensitivities of multiple types
SourceFiles
sensitivityMultiple.C
\*---------------------------------------------------------------------------*/
#ifndef sensitivityMultipleIncompressible_H
#define sensitivityMultipleIncompressible_H
#include "adjointSensitivityIncompressible.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class sensitivityMultiple Declaration
\*---------------------------------------------------------------------------*/
class sensitivityMultiple
:
public adjointSensitivity
{
protected:
// Protected data
wordList sensTypes_;
PtrList<adjointSensitivity> sens_;
scalarField derivatives_;
private:
// Private Member Functions
//- Disallow default bitwise copy construct
sensitivityMultiple(const sensitivityMultiple&) = delete;
//- Disallow default bitwise assignment
void operator=(const sensitivityMultiple&) = delete;
public:
//- Runtime type information
TypeName("multiple");
// Constructors
//- Construct from components
sensitivityMultiple
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
);
//- Destructor
virtual ~sensitivityMultiple() = default;
// Member Functions
//- Read dict if changed
virtual bool readDict(const dictionary& dict);
//- Calculates sensitivities at wall surface points
const scalarField& calculateSensitivities();
//- Write sensitivities to file
virtual void write(const word& baseName = word::null);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,712 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "sensitivitySurfaceIncompressible.H"
#include "PrimitivePatchInterpolation.H"
#include "syncTools.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(sensitivitySurface, 0);
addToRunTimeSelectionTable
(
adjointSensitivity,
sensitivitySurface,
dictionary
);
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
void sensitivitySurface::read()
{
includeSurfaceArea_ =
dict().lookupOrDefault<bool>("includeSurfaceArea", true);
includePressureTerm_ =
dict().lookupOrDefault<bool>("includePressure", true);
includeGradStressTerm_ =
dict().lookupOrDefault<bool>("includeGradStressTerm", true);
includeTransposeStresses_ =
dict().lookupOrDefault<bool>("includeTransposeStresses", true);
includeDivTerm_ = dict().lookupOrDefault<bool>("includeDivTerm", false);
includeDistance_ =
dict().lookupOrDefault<bool>
(
"includeDistance",
adjointVars_.adjointTurbulence().ref().includeDistance()
);
includeMeshMovement_ =
dict().lookupOrDefault<bool>("includeMeshMovement", true);
includeObjective_ =
dict().lookupOrDefault<bool>("includeObjectiveContribution", true);
writeGeometricInfo_ =
dict().lookupOrDefault<bool>("writeGeometricInfo", false);
// Allocate new solvers if necessary
if (includeDistance_ && eikonalSolver_.empty())
{
eikonalSolver_.reset
(
new adjointEikonalSolver
(
mesh_,
dict_,
primalVars_.RASModelVariables(),
adjointVars_.adjointTurbulence(),
sensitivityPatchIDs_
)
);
}
if (includeMeshMovement_ && meshMovementSolver_.empty())
{
meshMovementSolver_.reset
(
new adjointMeshMovementSolver
(
mesh_,
dict_,
*this,
sensitivityPatchIDs_,
eikonalSolver_
)
);
}
}
void sensitivitySurface::addGeometricSens()
{
if (includeObjective_)
{
// Grab objective refs
PtrList<objective>& functions
(objectiveManager_.getObjectiveFunctions());
// Compute sens for all points in parameterized patches.
// Interfacing points will be accumulated later
autoPtr<pointBoundaryVectorField> pointSensdSdb
(
createZeroBoundaryPointFieldPtr<vector>(mesh_)
);
autoPtr<pointBoundaryVectorField> pointSensdndb
(
createZeroBoundaryPointFieldPtr<vector>(mesh_)
);
// Geometric (or "direct") sensitivities are better computed directly
// on the points
forAll(sensitivityPatchIDs_, pI)
{
const label patchI = sensitivityPatchIDs_[pI];
const fvPatch& patch = mesh_.boundary()[patchI];
vectorField nf(patch.nf());
// point sens result for patch
vectorField& patchdSdb = pointSensdSdb()[patchI];
vectorField& patchdndb = pointSensdndb()[patchI];
vectorField dSdbMultiplierTot(patch.size(), vector::zero);
vectorField dndbMultiplierTot(patch.size(), vector::zero);
forAll(functions, funcI)
{
dSdbMultiplierTot +=
functions[funcI].weight()
*functions[funcI].dSdbMultiplier(patchI);
dndbMultiplierTot +=
functions[funcI].weight()
*functions[funcI].dndbMultiplier(patchI);
}
// Correspondance of local point addressing to global point
// addressing
const labelList& meshPoints = patch.patch().meshPoints();
// List with mesh faces. Global addressing
const faceList& faces = mesh_.faces();
// Each local patch point belongs to these local patch faces
// (local numbering)
const labelListList& patchPointFaces = patch.patch().pointFaces();
// index of first face in patch
const label patchStartIndex = patch.start();
// geometry differentiation engine
deltaBoundary dBoundary(mesh_);
// Loop over patch points.
// Collect contributions from each boundary face this point
// belongs to
forAll(meshPoints, ppI)
{
const labelList& pointFaces = patchPointFaces[ppI];
forAll(pointFaces, pfI)
{
label localFaceIndex = pointFaces[pfI];
label globalFaceIndex = patchStartIndex + localFaceIndex;
const face& faceI = faces[globalFaceIndex];
// Point coordinates. All indices in global numbering
pointField p(faceI.points(mesh_.points()));
tensorField p_d(faceI.size(), tensor::zero);
forAll(faceI, facePointI)
{
if (faceI[facePointI] == meshPoints[ppI])
{
p_d[facePointI] = tensor::I;
}
}
tensorField deltaNormals =
dBoundary.makeFaceCentresAndAreas_d(p, p_d);
// Element [1] is the variation in the (dimensional) normal
const tensor& deltaSf = deltaNormals[1];
patchdSdb[ppI] +=
dSdbMultiplierTot[localFaceIndex] & deltaSf;
// Element [2] is the variation in the unit normal
const tensor& deltaNf = deltaNormals[2];
patchdndb[ppI] +=
dndbMultiplierTot[localFaceIndex] & deltaNf;
}
}
}
// Do parallel communications to avoid wrong values at processor
// boundaries
vectorField dSdbGlobal(mesh_.nPoints(), vector::zero);
vectorField dndbGlobal(mesh_.nPoints(), vector::zero);
forAll(sensitivityPatchIDs_, pI)
{
const label patchI = sensitivityPatchIDs_[pI];
const labelList& meshPoints =
mesh_.boundaryMesh()[patchI].meshPoints();
forAll(meshPoints, ppI)
{
const label globaPointI = meshPoints[ppI];
dSdbGlobal[globaPointI] += pointSensdSdb()[patchI][ppI];
dndbGlobal[globaPointI] += pointSensdndb()[patchI][ppI];
}
}
// Accumulate over processors
syncTools::syncPointList
(
mesh_, dSdbGlobal, plusEqOp<vector>(), vector::zero
);
syncTools::syncPointList
(
mesh_, dndbGlobal, plusEqOp<vector>(), vector::zero
);
// Transfer back to local fields and map to faces
forAll(sensitivityPatchIDs_, pI)
{
const label patchI = sensitivityPatchIDs_[pI];
const fvPatch& patch = mesh_.boundary()[patchI];
const labelList& meshPoints = patch.patch().meshPoints();
const scalarField& magSf = patch.magSf();
pointSensdSdb()[patchI].map(dSdbGlobal, meshPoints);
pointSensdndb()[patchI].map(dndbGlobal, meshPoints);
// Map dSf/dx and dnf/dx term from points to faces. Ideally, all
// sensitivities should be computed at points rather than faces.
PrimitivePatchInterpolation<polyPatch> patchInter(patch.patch());
vectorField dSdbFace
(
patchInter.pointToFaceInterpolate(pointSensdSdb()[patchI])
);
// dSdb already contains the face area. Divide with it to make it
// compatible with the rest of the terms
dSdbFace /= magSf;
tmp<vectorField> tdndbFace =
patchInter.pointToFaceInterpolate(pointSensdndb()[patchI]);
const vectorField& dndbFace = tdndbFace();
// Add to sensitivity fields
wallFaceSensVecPtr_()[patchI] += dSdbFace + dndbFace;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
sensitivitySurface::sensitivitySurface
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
)
:
adjointSensitivity
(
mesh,
dict,
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
),
derivatives_(0),
includeSurfaceArea_(false),
includePressureTerm_(false),
includeGradStressTerm_(false),
includeTransposeStresses_(false),
includeDivTerm_(false),
includeDistance_(false),
includeMeshMovement_(false),
includeObjective_(false),
writeGeometricInfo_(false),
eikonalSolver_(nullptr),
meshMovementSolver_(nullptr),
nfOnPatchPtr_(nullptr),
SfOnPatchPtr_(nullptr),
CfOnPatchPtr_(nullptr)
{
read();
// Allocate boundary field pointer
wallFaceSensVecPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
wallFaceSensNormalPtr_.reset(createZeroBoundaryPtr<scalar>(mesh_));
wallFaceSensNormalVecPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
// Allocate fields to contain geometric info
if (writeGeometricInfo_)
{
nfOnPatchPtr_.reset
(
new volVectorField
(
IOobject
(
"nfOnPatch",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
vector::zero
)
);
SfOnPatchPtr_.reset
(
new volVectorField
(
IOobject
(
"SfOnPatch",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
vector::zero
)
);
CfOnPatchPtr_.reset
(
new volVectorField
(
IOobject
(
"CfOnPatch",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
vector::zero
)
);
}
// Allocate appropriate space for the sensitivity field
computeDerivativesSize();
};
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool sensitivitySurface::readDict(const dictionary& dict)
{
if (sensitivity::readDict(dict))
{
if (eikonalSolver_.valid())
{
eikonalSolver_().readDict(dict);
}
if (meshMovementSolver_.valid())
{
meshMovementSolver_().readDict(dict);
}
return true;
}
return false;
}
void sensitivitySurface::computeDerivativesSize()
{
label nFaces(0);
forAll(sensitivityPatchIDs_, pI)
{
const label patchI = sensitivityPatchIDs_[pI];
nFaces += mesh_.boundary()[patchI].size();
}
derivatives_.setSize(nFaces);
}
const scalarField& sensitivitySurface::calculateSensitivities()
{
// Grab references
const volScalarField& p = primalVars_.p();
const volVectorField& U = primalVars_.U();
const volScalarField& pa = adjointVars_.pa();
const volVectorField& Ua = adjointVars_.Ua();
autoPtr<incompressibleAdjoint::adjointRASModel>& adjointTurbulence =
adjointVars_.adjointTurbulence();
// Restore to zero
derivatives_ = Zero;
// Update geometric fields for use by external users
if (writeGeometricInfo_)
{
forAll(sensitivityPatchIDs_, pI)
{
const label patchI = sensitivityPatchIDs_[pI];
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
const vectorField& Sf = patch.Sf();
const vectorField& Cf = patch.Cf();
nfOnPatchPtr_().boundaryFieldRef()[patchI] = nf;
SfOnPatchPtr_().boundaryFieldRef()[patchI] = Sf;
CfOnPatchPtr_().boundaryFieldRef()[patchI] = Cf;
}
}
Info<< " Calculating auxilary quantities " << endl;
// Fields needed to calculate adjoint sensitivities
const autoPtr<incompressible::RASModelVariables>&
turbVars = primalVars_.RASModelVariables();
const singlePhaseTransportModel& lamTransp = primalVars_.laminarTransport();
volScalarField nuEff(lamTransp.nu() + turbVars->nutRef());
volTensorField gradUa(fvc::grad(Ua));
volTensorField gradU(fvc::grad(U));
// Explicitly correct the boundary gradient to get rid of the tangential
// component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
gradU.boundaryFieldRef()[patchI] =
nf*U.boundaryField()[patchI].snGrad();
}
}
// Auxiliary terms
volVectorField gradp(fvc::grad(p));
volTensorField stress(nuEff*(gradU + T(gradU)));
autoPtr<volVectorField> stressXPtr
(
createZeroFieldPtr<vector>(mesh_, "stressX", stress.dimensions())
);
autoPtr<volVectorField> stressYPtr
(
createZeroFieldPtr<vector>(mesh_, "stressY", stress.dimensions())
);
autoPtr<volVectorField> stressZPtr
(
createZeroFieldPtr<vector>(mesh_, "stressZ", stress.dimensions())
);
stressXPtr().replace(0, stress.component(0));
stressXPtr().replace(1, stress.component(1));
stressXPtr().replace(2, stress.component(2));
stressYPtr().replace(0, stress.component(3));
stressYPtr().replace(1, stress.component(4));
stressYPtr().replace(2, stress.component(5));
stressZPtr().replace(0, stress.component(6));
stressZPtr().replace(1, stress.component(7));
stressZPtr().replace(2, stress.component(8));
volTensorField gradStressX(fvc::grad(stressXPtr()));
volTensorField gradStressY(fvc::grad(stressYPtr()));
volTensorField gradStressZ(fvc::grad(stressZPtr()));
// Solve extra equations if necessary
autoPtr<boundaryVectorField> distanceSensPtr(nullptr);
if (includeDistance_)
{
eikonalSolver_->solve();
distanceSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
const boundaryVectorField& sens =
eikonalSolver_->distanceSensitivities();
for (const label patchI : sensitivityPatchIDs_)
{
distanceSensPtr()[patchI] = sens[patchI];
}
}
autoPtr<boundaryVectorField> meshMovementSensPtr(nullptr);
if (includeMeshMovement_)
{
meshMovementSolver_->solve();
meshMovementSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
const boundaryVectorField& sens =
meshMovementSolver_->meshMovementSensitivities();
for (const label patchI : sensitivityPatchIDs_)
{
meshMovementSensPtr()[patchI] = sens[patchI];
}
}
// Terms from the adjoint turbulence model
const boundaryVectorField& adjointTMsensitivities =
adjointTurbulence->wallShapeSensitivities();
Info<< " Calculating adjoint sensitivity. " << endl;
// Sensitivities do not include locale surface area by default.
// Part of the sensitivities that multiplies dxFace/db
for (const label patchI : sensitivityPatchIDs_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
// Includes spurious tangential gradU part. Deprecated
/*
vectorField stressAndPressureTerm =
(
- (
Ua.boundaryField()[patchI].snGrad()
+ (gradUa.boundaryField()[patchI] & nf)
) * nuEff.boundaryField()[patchI]
+ pa.boundaryField()[patchI] *nf
) & gradU.boundaryField()[patchI].T();
*/
// Adjoint stress term
vectorField stressTerm
(
- (
Ua.boundaryField()[patchI].snGrad()
& U.boundaryField()[patchI].snGrad()
)
* nuEff.boundaryField()[patchI]
* nf
);
if (includeTransposeStresses_)
{
stressTerm -=
nuEff.boundaryField()[patchI]
* (
// Note: in case of laminar or low-Re flows,
// includes a spurious tangential gradUa component
// (gradUa.boundaryField()[patchI] & nf)
((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
& U.boundaryField()[patchI].snGrad()
)
* nf;
}
if (includeDivTerm_)
{
stressTerm +=
scalar(1./3.)*nuEff.boundaryField()[patchI]
* (
((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
& U.boundaryField()[patchI].snGrad()
)
* nf;
}
vectorField gradStressTerm(patch.size(), vector::zero);
if (includeGradStressTerm_)
{
// Terms corresponding to contributions from converting delta to
// thetas are added through the corresponding adjoint boundary
// conditions instead of grabing contributions from the objective
// function. Useful to have a unified formulation for low- and
// high-re meshes
const fvPatchVectorField& Uab = Ua.boundaryField()[patchI];
gradStressTerm = - ((Uab & nf)*gradp.boundaryField()[patchI]);
gradStressTerm +=
(
Uab.component(0) * gradStressX.boundaryField()[patchI]
+ Uab.component(1) * gradStressY.boundaryField()[patchI]
+ Uab.component(2) * gradStressZ.boundaryField()[patchI]
) & nf;
}
// Adjoint pressure terms
vectorField pressureTerm(patch.size(), vector::zero);
if (includePressureTerm_)
{
pressureTerm =
(
(nf*pa.boundaryField()[patchI])
& U.boundaryField()[patchI].snGrad()
)* nf;
}
// Distance related terms
vectorField distanceTerm(pressureTerm.size(), vector::zero);
if (includeDistance_)
{
distanceTerm = distanceSensPtr()[patchI];
}
// Mesh movement related terms
vectorField meshMovementTerm(pressureTerm.size(), vector::zero);
if (includeMeshMovement_)
{
meshMovementTerm = meshMovementSensPtr()[patchI];
}
PtrList<objective>& functions
(objectiveManager_.getObjectiveFunctions());
// Term from objectives including x directly (e.g. moments)
vectorField dxdbMultiplierTot(pressureTerm.size(), vector::zero);
if (includeObjective_)
{
forAll(functions, funcI)
{
dxdbMultiplierTot +=
functions[funcI].weight()
* (
functions[funcI].dxdbDirectMultiplier(patchI)
);
}
}
// Fill in sensitivity fields
wallFaceSensVecPtr_()[patchI] =
stressTerm
+ gradStressTerm
+ pressureTerm
+ distanceTerm
+ meshMovementTerm
+ adjointTMsensitivities[patchI]
+ dxdbMultiplierTot;
}
// Add the sensitivity part corresponding to changes of the normal vector
// Computed at points and mapped to faces
addGeometricSens();
// Project to normal face vector
label nPassedFaces(0);
for (const label patchI : sensitivityPatchIDs_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf(patch.nf());
const vectorField& nf = tnf();
const scalarField& magSf = patch.magSf();
if (includeSurfaceArea_)
{
wallFaceSensVecPtr_()[patchI] *= magSf;
}
wallFaceSensNormalPtr_()[patchI] = wallFaceSensVecPtr_()[patchI] & nf;
wallFaceSensNormalVecPtr_()[patchI] =
wallFaceSensNormalPtr_()[patchI] * nf;
forAll(patch, fI)
{
derivatives_[nPassedFaces + fI]
= wallFaceSensNormalPtr_()[patchI][fI];
}
nPassedFaces += patch.size();
}
// Write sens fields
write(type());
return (derivatives_);
}
autoPtr<adjointEikonalSolver>& sensitivitySurface::getAdjointEikonalSolver()
{
return eikonalSolver_;
}
void sensitivitySurface::write(const word& baseName)
{
// Determine suffix for fields holding the sens
if (includeMeshMovement_)
{
surfaceFieldSuffix_ = word("ESI");
}
else
{
surfaceFieldSuffix_ = word("SI");
}
adjointSensitivity::write();
if (writeGeometricInfo_)
{
nfOnPatchPtr_().write();
SfOnPatchPtr_().write();
CfOnPatchPtr_().write();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
} // End namespace incompressible
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::sensitivitySurface
Description
Calculation of adjoint based sensitivities at wall faces
SourceFiles
sensitivitySurface.C
\*---------------------------------------------------------------------------*/
#ifndef sensitivitySurfaceIncompressible_H
#define sensitivitySurfaceIncompressible_H
#include "adjointSensitivityIncompressible.H"
#include "adjointEikonalSolverIncompressible.H"
#include "adjointMeshMovementSolverIncompressible.H"
#include "deltaBoundary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class sensitivitySurface Declaration
\*---------------------------------------------------------------------------*/
class sensitivitySurface
:
public adjointSensitivity
{
protected:
// Protected data
//- Scalar normal sens
scalarField derivatives_;
//- Include surface area in sens computation
bool includeSurfaceArea_;
//- Include the adjoint pressure term in sens computation
bool includePressureTerm_;
//- Include the term containing the grad of the stress at the boundary
bool includeGradStressTerm_;
//- Include the transpose part of the adjoint stresses
bool includeTransposeStresses_;
//- Include the term from the deviatoric part of the stresses
bool includeDivTerm_;
//- Include distance variation in sens computation
bool includeDistance_;
//- Include mesh movement variation in sens computation
bool includeMeshMovement_;
//- Include terms directly emerging from the objective function
bool includeObjective_;
//- Write geometric info for use by external programs
bool writeGeometricInfo_;
autoPtr<adjointEikonalSolver> eikonalSolver_;
autoPtr<adjointMeshMovementSolver> meshMovementSolver_;
// Export face normal and face centre for use by external users
autoPtr<volVectorField> nfOnPatchPtr_;
autoPtr<volVectorField> SfOnPatchPtr_;
autoPtr<volVectorField> CfOnPatchPtr_;
// Protected Member Functions
//- Read controls and update solver pointers if necessary
void read();
//- Add sensitivities from dSd/db and dnf/db computed at points and
//- mapped to faces
void addGeometricSens();
private:
// Private Member Functions
//- Disallow default bitwise copy construct
sensitivitySurface(const sensitivitySurface&) = delete;
//- Disallow default bitwise assignment
void operator=(const sensitivitySurface&) = delete;
public:
//- Runtime type information
TypeName("surface");
// Constructors
//- Construct from components
sensitivitySurface
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
);
//- Destructor
virtual ~sensitivitySurface() = default;
// Member Functions
//- Read dict if changed
virtual bool readDict(const dictionary& dict);
//- Compute the number of faces on sensitivityPatchIDs_
void computeDerivativesSize();
//- Calculates sensitivities at wall surface points
const scalarField& calculateSensitivities();
//- Get adjoint eikonal solver
autoPtr<adjointEikonalSolver>& getAdjointEikonalSolver();
virtual void write(const word& baseName = word::null);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,674 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "sensitivitySurfacePointsIncompressible.H"
#include "addToRunTimeSelectionTable.H"
#include "syncTools.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(sensitivitySurfacePoints, 0);
addToRunTimeSelectionTable
(
adjointSensitivity,
sensitivitySurfacePoints,
dictionary
);
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
void sensitivitySurfacePoints::read()
{
includeSurfaceArea_ =
dict().lookupOrDefault<bool>("includeSurfaceArea", false);
includePressureTerm_ =
dict().lookupOrDefault<bool>("includePressure", true);
includeGradStressTerm_ =
dict().lookupOrDefault<bool>("includeGradStressTerm", true);
includeTransposeStresses_ =
dict().lookupOrDefault<bool>("includeTransposeStresses", true);
includeDivTerm_ =
dict().lookupOrDefault<bool>("includeDivTerm", false);
includeDistance_ =
dict().lookupOrDefault<bool>
(
"includeDistance",
adjointVars_.adjointTurbulence().ref().includeDistance()
);
includeMeshMovement_ =
dict().lookupOrDefault<bool>("includeMeshMovement", true);
includeObjective_ =
dict().lookupOrDefault<bool>("includeObjectiveContribution", true);
// Allocate new solvers if necessary
if (includeDistance_ && eikonalSolver_.empty())
{
eikonalSolver_.reset
(
new adjointEikonalSolver
(
mesh_,
dict(),
primalVars_.RASModelVariables(),
adjointVars_.adjointTurbulence(),
sensitivityPatchIDs_
)
);
}
if (includeMeshMovement_ && meshMovementSolver_.empty())
{
meshMovementSolver_.reset
(
new adjointMeshMovementSolver
(
mesh_,
dict(),
*this,
sensitivityPatchIDs_,
eikonalSolver_
)
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
sensitivitySurfacePoints::sensitivitySurfacePoints
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
)
:
adjointSensitivity
(
mesh,
dict,
primalVars,
adjointVars,
objectiveManager,
fvOptionsAdjoint
),
derivatives_(0),
includeSurfaceArea_(false),
includePressureTerm_(false),
includeGradStressTerm_(false),
includeTransposeStresses_(false),
includeDivTerm_(false),
includeDistance_(false),
includeMeshMovement_(false),
includeObjective_(false),
eikonalSolver_(nullptr),
meshMovementSolver_(nullptr)
{
read();
// Allocate boundary field pointer
wallPointSensVecPtr_.reset(createZeroBoundaryPointFieldPtr<vector>(mesh_));
wallPointSensNormalPtr_.reset
(
createZeroBoundaryPointFieldPtr<scalar>(mesh_)
);
wallPointSensNormalVecPtr_.reset
(
createZeroBoundaryPointFieldPtr<vector>(mesh_)
);
// Allocate appropriate space for sensitivities
label nTotalPoints(0);
for (const label patchI : sensitivityPatchIDs_)
{
label nPoints = mesh_.boundaryMesh()[patchI].nPoints();
nTotalPoints += returnReduce(nPoints, sumOp<label>());
}
// Derivatives for all (x,y,z) components of the displacement are kept
derivatives_ = scalarField(3*nTotalPoints, Zero);
};
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool sensitivitySurfacePoints::readDict(const dictionary& dict)
{
if (sensitivity::readDict(dict))
{
if (eikonalSolver_.valid())
{
eikonalSolver_().readDict(dict);
}
if (meshMovementSolver_.valid())
{
meshMovementSolver_().readDict(dict);
}
return true;
}
return false;
}
const scalarField& sensitivitySurfacePoints::calculateSensitivities()
{
// Grab references
const volScalarField& p = primalVars_.p();
const volVectorField& U = primalVars_.U();
const volScalarField& pa = adjointVars_.pa();
const volVectorField& Ua = adjointVars_.Ua();
autoPtr<incompressibleAdjoint::adjointRASModel>& adjointTurbulence =
adjointVars_.adjointTurbulence();
// Restore to zero
derivatives_ = Zero;
forAll(mesh_.boundary(), patchI)
{
wallPointSensVecPtr_()[patchI] = vector::zero;
wallPointSensNormalPtr_()[patchI] = Zero;
wallPointSensNormalVecPtr_()[patchI] = vector::zero;
}
Info<< " Calculating auxilary quantities " << endl;
// Fields needed to calculate adjoint sensitivities
volScalarField nuEff(adjointTurbulence->nuEff());
volTensorField gradUa(fvc::grad(Ua));
volTensorField gradU(fvc::grad(U));
// Explicitly correct the boundary gradient to get rid of the
// tangential component
forAll(mesh_.boundary(), patchI)
{
const fvPatch& patch = mesh_.boundary()[patchI];
if (isA<wallFvPatch>(patch))
{
tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
const vectorField& nf = tnf();
gradU.boundaryFieldRef()[patchI] =
nf*U.boundaryField()[patchI].snGrad();
}
}
// Auxiliary terms
volVectorField gradp(fvc::grad(p));
volTensorField stress(nuEff*(gradU + T(gradU)));
autoPtr<volVectorField> stressXPtr
(
createZeroFieldPtr<vector>(mesh_, "stressX", stress.dimensions())
);
autoPtr<volVectorField> stressYPtr
(
createZeroFieldPtr<vector>(mesh_, "stressY", stress.dimensions())
);
autoPtr<volVectorField> stressZPtr
(
createZeroFieldPtr<vector>(mesh_, "stressZ", stress.dimensions())
);
stressXPtr().replace(0, stress.component(0));
stressXPtr().replace(1, stress.component(1));
stressXPtr().replace(2, stress.component(2));
stressYPtr().replace(0, stress.component(3));
stressYPtr().replace(1, stress.component(4));
stressYPtr().replace(2, stress.component(5));
stressZPtr().replace(0, stress.component(6));
stressZPtr().replace(1, stress.component(7));
stressZPtr().replace(2, stress.component(8));
volTensorField gradStressX(fvc::grad(stressXPtr()));
volTensorField gradStressY(fvc::grad(stressYPtr()));
volTensorField gradStressZ(fvc::grad(stressZPtr()));
// solve extra equations if necessary
autoPtr<boundaryVectorField> distanceSensPtr(nullptr);
if (includeDistance_)
{
eikonalSolver_->solve();
distanceSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
const boundaryVectorField& sens =
eikonalSolver_->distanceSensitivities();
for (const label patchI : sensitivityPatchIDs_)
{
distanceSensPtr()[patchI] = sens[patchI];
}
}
autoPtr<boundaryVectorField> meshMovementSensPtr(nullptr);
if (includeMeshMovement_)
{
meshMovementSolver_->solve();
meshMovementSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
const boundaryVectorField& sens =
meshMovementSolver_->meshMovementSensitivities();
for (const label patchI : sensitivityPatchIDs_)
{
meshMovementSensPtr()[patchI] = sens[patchI];
}
}
// Terms from the adjoint turbulence model
const boundaryVectorField& adjointTMsensitivities =
adjointTurbulence->wallShapeSensitivities();
// Objective references
PtrList<objective>& functions(objectiveManager_.getObjectiveFunctions());
Info<< " Calculating adjoint sensitivity. " << endl;
// The face-based part of the sensitivities, i.e. terms that multiply
// dxFace/dxPoint. Sensitivities DO include locale surface area, to get
// the correct weighting from the contributions of various faces.
// Normalized at the end.
autoPtr<boundaryVectorField> wallFaceSens
(
createZeroBoundaryPtr<vector>(mesh_)
);
for (const label patchI : sensitivityPatchIDs_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
tmp<vectorField> tnf = patch.nf();
const vectorField& nf = tnf();
const scalarField& magSf = patch.magSf();
// Adjoint stress term
// vectorField stressTerm
// (
// -(nf & DUa.boundaryField()[patchI])
// *nuEff.boundaryField()[patchI]
// & gradU.boundaryField()[patchI].T();
// )
vectorField stressTerm
(
- (
Ua.boundaryField()[patchI].snGrad()
& U.boundaryField()[patchI].snGrad()
)
* nuEff.boundaryField()[patchI]
* nf
);
vectorField gradStressTerm(patch.size(), vector::zero);
if (includeGradStressTerm_)
{
// Terms corresponding to contributions from converting delta to
// thetas are added through the corresponding adjoint boundary
// conditions instead of grabing contributions from the objective
// function. Useful to have a unified formulation for low- and
// high-re meshes
const fvPatchVectorField& Uab = Ua.boundaryField()[patchI];
gradStressTerm = (-((Uab & nf)*gradp.boundaryField()[patchI]));
gradStressTerm +=
(
Uab.component(0)*gradStressX.boundaryField()[patchI]
+ Uab.component(1)*gradStressY.boundaryField()[patchI]
+ Uab.component(2)*gradStressZ.boundaryField()[patchI]
) & nf;
}
if (includeTransposeStresses_)
{
stressTerm -=
nuEff.boundaryField()[patchI]
*(
// Note: in case of laminar or low-Re flows,
// includes a spurious tangential gradUa component
// (gradUa.boundaryField()[patchI] & nf)
((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
& U.boundaryField()[patchI].snGrad()
)
* nf;
}
if (includeDivTerm_)
{
stressTerm +=
scalar(1./3.)*nuEff.boundaryField()[patchI]
* (
((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
& U.boundaryField()[patchI].snGrad()
)
*nf;
}
// Adjoint pressure terms
vectorField pressureTerm(patch.size(), vector::zero);
if (includePressureTerm_)
{
pressureTerm =
(
(nf * pa.boundaryField()[patchI])
& U.boundaryField()[patchI].snGrad()
)
*nf;
}
// Distance related terms
vectorField distanceTerm(pressureTerm.size(), vector::zero);
if (includeDistance_)
{
distanceTerm = distanceSensPtr()[patchI];
}
// Mesh movement related terms
vectorField meshMovementTerm(pressureTerm.size(), vector::zero);
if (includeMeshMovement_)
{
meshMovementTerm = meshMovementSensPtr()[patchI];
}
vectorField dxdbMultiplierTot
(
mesh_.boundary()[patchI].size(), vector::zero
);
if (includeObjective_)
{
// Term from objectives multiplying dxdb
forAll(functions, funcI)
{
dxdbMultiplierTot +=
functions[funcI].weight()
* functions[funcI].dxdbDirectMultiplier(patchI);
}
}
// Fill in dxFace/dxPoint multiplier.
// Missing geometric contributions which are directly computed on the
// points
wallFaceSens()[patchI] =
stressTerm
+ gradStressTerm
+ pressureTerm
+ distanceTerm
+ meshMovementTerm
+ adjointTMsensitivities[patchI]
+ dxdbMultiplierTot;
wallFaceSens()[patchI] *= magSf;
}
// polyPatch::pointNormals will give the wrong result for points
// belonging to multiple patches or patch-processorPatch intersections.
// Keeping a mesh-wide field to allow easy reduction using syncTools.
// A bit expensive? Better way?
vectorField pointNormals(mesh_.nPoints(), vector::zero);
scalarField pointMagSf(mesh_.nPoints(), Zero);
// Geometric (or "direct") sensitivities are better computed directly on
// the points. Compute them and add the ones that depend on dxFace/dxPoint
for (const label patchI : sensitivityPatchIDs_)
{
const fvPatch& patch = mesh_.boundary()[patchI];
const scalarField& magSf = patch.magSf();
vectorField nf(patch.nf());
// Point sens result for patch
vectorField& pointPatchSens = wallPointSensVecPtr_()[patchI];
// Face sens for patch
const vectorField& facePatchSens = wallFaceSens()[patchI];
vectorField dSdbMultiplierTot(patch.size(), vector::zero);
vectorField dndbMultiplierTot(patch.size(), vector::zero);
forAll(functions, funcI)
{
dSdbMultiplierTot +=
functions[funcI].weight() //includes surface by itself
*functions[funcI].dSdbMultiplier(patchI);
dndbMultiplierTot +=
functions[funcI].weight()
*functions[funcI].dndbMultiplier(patchI)
*magSf;
}
// Correspondance of local point addressing to global point addressing
const labelList& meshPoints = patch.patch().meshPoints();
// List with mesh faces. Global addressing
const faceList& faces = mesh_.faces();
// Each local patch point belongs to these local patch faces
// (local numbering)
const labelListList& patchPointFaces = patch.patch().pointFaces();
// Index of first face in patch
const label patchStartIndex = patch.start();
// Geometry differentiation engine
deltaBoundary dBoundary(mesh_);
// Loop over patch points.
// Collect contributions from each boundary face this point belongs to
forAll(meshPoints, ppI)
{
const labelList& pointFaces = patchPointFaces[ppI];
forAll(pointFaces, pfI)
{
label localFaceIndex = pointFaces[pfI];
label globalFaceIndex = patchStartIndex + localFaceIndex;
const face& faceI = faces[globalFaceIndex];
// Point coordinates. All indices in global numbering
pointField p(faceI.points(mesh_.points()));
tensorField p_d(faceI.size(), tensor::zero);
forAll(faceI, facePointI)
{
if (faceI[facePointI] == meshPoints[ppI])
{
p_d[facePointI] = tensor::I;
}
}
tensorField deltaNormals =
dBoundary.makeFaceCentresAndAreas_d(p, p_d);
// Element [0] is the variation in the face center
// (dxFace/dxPoint)
const tensor& deltaCf = deltaNormals[0];
pointPatchSens[ppI] += facePatchSens[localFaceIndex] & deltaCf;
// Term multiplying d(Sf)/d(point displacement) and
// d(nf)/d(point displacement)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (includeObjective_)
{
// Element [1] is the variation in the (dimensional) normal
const tensor& deltaSf = deltaNormals[1];
pointPatchSens[ppI] +=
dSdbMultiplierTot[localFaceIndex] & deltaSf;
// Element [2] is the variation in the unit normal
const tensor& deltaNf = deltaNormals[2];
pointPatchSens[ppI] +=
dndbMultiplierTot[localFaceIndex] & deltaNf;
}
// Accumulate information for point normals
pointNormals[meshPoints[ppI]] += nf[localFaceIndex];
pointMagSf[meshPoints[ppI]] += magSf[localFaceIndex];
}
}
}
// Do parallel communications to avoid wrong values at processor boundaries
// - global field for accumulation
vectorField pointSensGlobal(mesh_.nPoints(), vector::zero);
for (const label patchI : sensitivityPatchIDs_)
{
const labelList& meshPoints = mesh_.boundaryMesh()[patchI].meshPoints();
forAll(meshPoints, ppI)
{
const label globaPointI = meshPoints[ppI];
pointSensGlobal[globaPointI] +=
wallPointSensVecPtr_()[patchI][ppI];
}
}
// Accumulate dJ/dx_i, pointNormals and pointFaces number
syncTools::syncPointList
(
mesh_,
pointSensGlobal,
plusEqOp<vector>(),
vector::zero
);
syncTools::syncPointList
(
mesh_,
pointNormals,
plusEqOp<vector>(),
vector::zero
);
syncTools::syncPointList
(
mesh_,
pointMagSf,
plusEqOp<scalar>(),
scalar(0)
);
// Transfer back to local fields
for (const label patchI : sensitivityPatchIDs_)
{
const labelList& meshPoints =
mesh_.boundaryMesh()[patchI].meshPoints();
wallPointSensVecPtr_()[patchI].map(pointSensGlobal, meshPoints);
}
// Compute normal sens and append to return field
label nPassedDVs(0);
for (const label patchI : sensitivityPatchIDs_)
{
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
List<scalarField> procPatchSens(Pstream::nProcs());
//if (patch.size()>0)
{
const labelList& meshPoints = patch.meshPoints();
// avoid storing unit point normals in the global list since we
// might divide multiple times with the number of faces belonging
// to the point. Instead do the division locally, per patch use
vectorField patchPointNormals(pointNormals, meshPoints);
patchPointNormals /= mag(patchPointNormals) + VSMALL;
if (!includeSurfaceArea_)
{
wallPointSensVecPtr_()[patchI] /=
scalarField(pointMagSf, meshPoints);
}
wallPointSensNormalPtr_()[patchI] =
wallPointSensVecPtr_()[patchI]
& patchPointNormals;
wallPointSensNormalVecPtr_()[patchI] =
wallPointSensNormalPtr_()[patchI]
*patchPointNormals;
// 1. Gather sens from all processors for this patch and communicate
// them back. Potentially large memory overhead but the rest of the
// code structure assumes that all procs know all sensitivity
// derivatives
//
// 2. Transfer vectorial sensitivities to scalarField.
// Needed since the normal point vector is wrongly computed at patch
// boundaries and cannot be used to reconstruct a vectorial movement
// from just its normal component
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procPatchSens[Pstream::myProcNo()].setSize
(
3*wallPointSensNormalVecPtr_()[patchI].size()
);
scalarField& patchScalarSens = procPatchSens[Pstream::myProcNo()];
forAll(wallPointSensNormalVecPtr_()[patchI], ptI)
{
patchScalarSens[3*ptI] =
wallPointSensNormalVecPtr_()[patchI][ptI].x();
patchScalarSens[3*ptI + 1] =
wallPointSensNormalVecPtr_()[patchI][ptI].y();
patchScalarSens[3*ptI + 2] =
wallPointSensNormalVecPtr_()[patchI][ptI].z();
}
Pstream::gatherList(procPatchSens);
Pstream::scatterList(procPatchSens);
forAll(procPatchSens, procI)
{
const scalarField& procSens = procPatchSens[procI];
forAll(procSens, dvI)
{
derivatives_[nPassedDVs + dvI] = procSens[dvI];
}
nPassedDVs += procSens.size();
}
}
}
// Write sens fields
write(type());
return (derivatives_);
}
void sensitivitySurfacePoints::write(const word& baseName)
{
//determine suffix for fields holding the sens
if (includeMeshMovement_)
{
surfaceFieldSuffix_ = "ESI";
}
else
{
surfaceFieldSuffix_ = "SI";
}
adjointSensitivity::write();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
} // End namespace incompressible
// ************************************************************************* //

View File

@ -0,0 +1,161 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::incompressible::sensitivitySurfacePoints
Description
Calculation of adjoint based sensitivities at wall points
SourceFiles
sensitivitySurfacePoints.C
\*---------------------------------------------------------------------------*/
#ifndef sensitivitySurfacePointsIncompressible_H
#define sensitivitySurfacePointsIncompressible_H
#include "adjointSensitivityIncompressible.H"
#include "adjointEikonalSolverIncompressible.H"
#include "adjointMeshMovementSolverIncompressible.H"
#include "deltaBoundary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace incompressible
{
/*---------------------------------------------------------------------------*\
Class sensitivitySurfacePoints Declaration
\*---------------------------------------------------------------------------*/
class sensitivitySurfacePoints
:
public adjointSensitivity
{
protected:
// Protected data
//- Scalar normal sens
scalarField derivatives_;
//- Include surface area in sens computation
bool includeSurfaceArea_;
//- Include the adjoint pressure term in sens computation
bool includePressureTerm_;
//- Include the term containing the grad of the stress at the boundary
bool includeGradStressTerm_;
//- Include the transpose part of the adjoint stresses
bool includeTransposeStresses_;
//- Include the term from the deviatoric part of the stresses
bool includeDivTerm_;
//- Include distance variation in sens computation
bool includeDistance_;
//- Include mesh movement variation in sens computation
bool includeMeshMovement_;
//- Include terms directly emerging from the objective function
bool includeObjective_;
autoPtr<adjointEikonalSolver> eikonalSolver_;
autoPtr<adjointMeshMovementSolver> meshMovementSolver_;
// Protected Member Functions
//- Read controls and update solver pointers if necessary
void read();
private:
// Private Member Functions
//- Disallow default bitwise copy construct
sensitivitySurfacePoints(const sensitivitySurfacePoints&) = delete;
//- Disallow default bitwise assignment
void operator=(const sensitivitySurfacePoints&) = delete;
public:
//- Runtime type information
TypeName("surfacePoints");
// Constructors
//- Construct from components
sensitivitySurfacePoints
(
const fvMesh& mesh,
const dictionary& dict,
incompressibleVars& primalVars,
incompressibleAdjointVars& adjointVars,
objectiveManager& objectiveManager,
fv::optionAdjointList& fvOptionsAdjoint
);
//- Destructor
virtual ~sensitivitySurfacePoints() = default;
// Member Functions
//- Read dict if changed
virtual bool readDict(const dictionary& dict);
//- Calculates sensitivities at wall surface points
const scalarField& calculateSensitivities();
virtual void write(const word& baseName = word::null);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace incompressible
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More