mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'integration-adjoint' into 'develop'
Integration adjoint See merge request Development/OpenFOAM-plus!269
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
adjointOptimisationFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/adjointOptimisationFoam
|
||||
@ -0,0 +1,21 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fvOptions/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lfvOptions \
|
||||
-lmeshTools \
|
||||
-lsampling \
|
||||
-lturbulenceModels \
|
||||
-lincompressibleTurbulenceModels \
|
||||
-lincompressibleTransportModels \
|
||||
-ladjointOptimisation
|
||||
@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
| Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
| Copyright (C) 2013-2019 FOSS GP
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
adjointOptimisation
|
||||
|
||||
Description
|
||||
An automated adjoint-based optimisation loop. Supports multiple types
|
||||
of optimisation (shape, topology etc)
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "optimisationManager.H"
|
||||
#include "primalSolver.H"
|
||||
#include "adjointSolverManager.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
#include "createFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
for (om++; !om.end(); om++)
|
||||
{
|
||||
Info<< "* * * * * * * * * * * * * * * * * * *" << endl;
|
||||
Info<< "Time = " << runTime.timeName() << endl;
|
||||
Info<< "* * * * * * * * * * * * * * * * * * *" << endl;
|
||||
|
||||
if (om.update())
|
||||
{
|
||||
// Update design variables and solve all primal equations
|
||||
om.updateDesignVariables();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Solve all primal equations
|
||||
om.solvePrimalEquations();
|
||||
}
|
||||
|
||||
// Update primal-based quantities of the adjoint solvers
|
||||
om.updatePrimalBasedQuantities();
|
||||
|
||||
// Solve all adjoint equations
|
||||
om.solveAdjointEquations();
|
||||
|
||||
// Compute all sensitivities
|
||||
om.computeSensitivities();
|
||||
}
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,6 @@
|
||||
// Construct optimisation manager
|
||||
autoPtr<optimisationManager> optManagerPtr
|
||||
(
|
||||
optimisationManager::New(mesh)
|
||||
);
|
||||
optimisationManager& om = optManagerPtr();
|
||||
@ -0,0 +1,3 @@
|
||||
computeSensitivities.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/computeSensitivities
|
||||
@ -0,0 +1,23 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fvOptions/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lfvOptions \
|
||||
-lmeshTools \
|
||||
-lsampling \
|
||||
-lturbulenceModels \
|
||||
-lincompressibleTransportModels \
|
||||
-lincompressibleTurbulenceModels \
|
||||
-lfileFormats \
|
||||
-lsurfMesh \
|
||||
-ladjointOptimisation
|
||||
@ -0,0 +1,76 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
| Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
| Copyright (C) 2013-2019 FOSS GP
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
computeSensitivities
|
||||
|
||||
Description
|
||||
Computes the sensitivities wrt what is defined in the optimisationDict
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "optimisationManager.H"
|
||||
#include "primalSolver.H"
|
||||
#include "adjointSolver.H"
|
||||
#include "incompressibleVars.H"
|
||||
#include "incompressibleAdjointVars.H"
|
||||
#include "adjointBoundaryCondition.H"
|
||||
#include "adjointSolverManager.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
#include "createFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
forAll(adjointSolverManagers, amI)
|
||||
{
|
||||
PtrList<adjointSolver>& adjointSolvers =
|
||||
adjointSolverManagers[amI].adjointSolvers();
|
||||
forAll(adjointSolvers, asI)
|
||||
{
|
||||
adjointSolvers[asI].getObjectiveManager().updateAndWrite();
|
||||
adjointSolvers[asI].computeObjectiveSensitivities();
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,9 @@
|
||||
// Construct optimisation manager
|
||||
autoPtr<optimisationManager> optManagerPtr
|
||||
(
|
||||
optimisationManager::New(mesh)
|
||||
);
|
||||
optimisationManager& om = optManagerPtr();
|
||||
|
||||
PtrList<adjointSolverManager>& adjointSolverManagers =
|
||||
om.adjointSolverManagers();
|
||||
@ -73,6 +73,13 @@ cleanSnappyFiles()
|
||||
}
|
||||
|
||||
|
||||
cleanOptimisation()
|
||||
{
|
||||
rm -rf optimisation
|
||||
rm -rf constant/controlPoints
|
||||
}
|
||||
|
||||
|
||||
cleanPostProcessing()
|
||||
{
|
||||
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