mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'integration-adjoint' into 'develop'
Integration adjoint See merge request Development/OpenFOAM-plus!269
This commit is contained in:
@ -0,0 +1,3 @@
|
|||||||
|
adjointOptimisationFoam.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/adjointOptimisationFoam
|
||||||
@ -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
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
// Construct optimisation manager
|
||||||
|
autoPtr<optimisationManager> optManagerPtr
|
||||||
|
(
|
||||||
|
optimisationManager::New(mesh)
|
||||||
|
);
|
||||||
|
optimisationManager& om = optManagerPtr();
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
computeSensitivities.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/computeSensitivities
|
||||||
@ -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
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
// Construct optimisation manager
|
||||||
|
autoPtr<optimisationManager> optManagerPtr
|
||||||
|
(
|
||||||
|
optimisationManager::New(mesh)
|
||||||
|
);
|
||||||
|
optimisationManager& om = optManagerPtr();
|
||||||
|
|
||||||
|
PtrList<adjointSolverManager>& adjointSolverManagers =
|
||||||
|
om.adjointSolverManagers();
|
||||||
@ -73,6 +73,13 @@ cleanSnappyFiles()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cleanOptimisation()
|
||||||
|
{
|
||||||
|
rm -rf optimisation
|
||||||
|
rm -rf constant/controlPoints
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cleanPostProcessing()
|
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
|
||||||
|
|||||||
@ -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 $*
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
116
src/optimisation/adjointOptimisation/adjoint/Make/files
Normal file
116
src/optimisation/adjointOptimisation/adjoint/Make/files
Normal 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
|
||||||
25
src/optimisation/adjointOptimisation/adjoint/Make/options
Normal file
25
src/optimisation/adjointOptimisation/adjoint/Make/options
Normal 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
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1 @@
|
|||||||
|
fv::IOoptionListAdjoint fvOptionsAdjoint(mesh);
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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, 1–18.
|
||||||
|
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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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, 1–18.
|
||||||
|
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), 255–299.
|
||||||
|
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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
Reference in New Issue
Block a user