mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
CONTRIB: New adjoint optimisation and tools
A set of libraries and executables creating a workflow for performing gradient-based optimisation loops. The main executable (adjointOptimisationFoam) solves the flow (primal) equations, followed by the adjoint equations and, eventually, the computation of sensitivity derivatives. Current functionality supports the solution of the adjoint equations for incompressible turbulent flows, including the adjoint to the Spalart-Allmaras turbulence model and the adjoint to the nutUSpaldingWallFunction, [1], [2]. Sensitivity derivatives are computed with respect to the normal displacement of boundary wall nodes/faces (the so-called sensitivity maps) following the Enhanced Surface Integrals (E-SI) formulation, [3]. The software was developed by PCOpt/NTUA and FOSS GP, with contributions from Dr. Evangelos Papoutsis-Kiachagias, Konstantinos Gkaragounis, Professor Kyriakos Giannakoglou, Andy Heather and contributions in earlier version from Dr. Ioannis Kavvadias, Dr. Alexandros Zymaris, Dr. Dimitrios Papadimitriou [1] A.S. Zymaris, D.I. Papadimitriou, K.C. Giannakoglou, and C. Othmer. Continuous adjoint approach to the Spalart-Allmaras turbulence model for incompressible flows. Computers & Fluids, 38(8):1528–1538, 2009. [2] E.M. Papoutsis-Kiachagias and K.C. Giannakoglou. Continuous adjoint methods for turbulent flows, applied to shape and topology optimization: Industrial applications. 23(2):255–299, 2016. [3] I.S. Kavvadias, E.M. Papoutsis-Kiachagias, and K.C. Giannakoglou. On the proper treatment of grid sensitivities in continuous adjoint methods for shape optimization. Journal of Computational Physics, 301:1–18, 2015. Integration into the official OpenFOAM release by OpenCFD
This commit is contained in:
committed by
Andrew Heather
parent
56547863c1
commit
ecc1fb5efb
@ -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()
|
||||
{
|
||||
rm -rf Ensight EnSight ensightWrite insitu VTK > /dev/null 2>&1
|
||||
@ -87,6 +94,7 @@ cleanCase()
|
||||
cleanTimeDirectories
|
||||
cleanPostProcessing
|
||||
cleanDynamicCode
|
||||
cleanOptimisation
|
||||
|
||||
rm -rf processor* > /dev/null 2>&1
|
||||
rm -rf TDAC > /dev/null 2>&1
|
||||
|
||||
@ -107,6 +107,7 @@ wmake $targetType rigidBodyDynamics
|
||||
wmake $targetType rigidBodyMeshMotion
|
||||
wmake $targetType semiPermeableBaffle
|
||||
wmake $targetType atmosphericModels
|
||||
wmake $targetType optimisation/adjointOptimisation/adjoint
|
||||
|
||||
phaseSystemModels/Allwmake $targetType $*
|
||||
|
||||
|
||||
@ -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