mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: New adjont shape optimisation functionality
The adjoint library is enhanced with new functionality enabling automated shape optimisation loops. A parameterisation scheme based on volumetric B-Splines is introduced, the control points of which act as the design variables in the optimisation loop [1, 2]. The control points of the volumetric B-Splines boxes can be defined in either Cartesian or cylindrical coordinates. The entire loop (solution of the flow and adjoint equations, computation of sensitivity derivatives, update of the design variables and mesh) is run within adjointOptimisationFoam. A number of methods to update the design variables are implemented, including popular Quasi-Newton methods like BFGS and methods capable of handling constraints like loop using the SQP or constraint projection. The software was developed by PCOpt/NTUA and FOSS GP, with contributions from Dr. Evangelos Papoutsis-Kiachagias, Konstantinos Gkaragounis, Professor Kyriakos Giannakoglou, Andy Heather [1] E.M. Papoutsis-Kiachagias, N. Magoulas, J. Mueller, C. Othmer, K.C. Giannakoglou: 'Noise Reduction in Car Aerodynamics using a Surrogate Objective Function and the Continuous Adjoint Method with Wall Functions', Computers & Fluids, 122:223-232, 2015 [2] E. M. Papoutsis-Kiachagias, V. G. Asouti, K. C. Giannakoglou, K. Gkagkas, S. Shimokawa, E. Itakura: ‘Multi-point aerodynamic shape optimization of cars based on continuous adjoint’, Structural and Multidisciplinary Optimization, 59(2):675–694, 2019
This commit is contained in:
committed by
Andrew Heather
parent
eb4fec371a
commit
b863254308
@ -55,10 +55,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
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
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
cumulativeDisplacement.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/cumulativeDisplacement
|
||||
@ -0,0 +1,11 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicFvMesh \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,16 @@
|
||||
pointField points0
|
||||
(
|
||||
pointIOField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"points",
|
||||
mesh.time().constant(),
|
||||
polyMesh::meshSubDir,
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -0,0 +1,161 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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
|
||||
cumulativeDisplacement
|
||||
|
||||
Description
|
||||
Computes and writes the difference between the mesh points in each time
|
||||
instance and the ones in the constant folder. Additionally, the projection
|
||||
of this difference to the normal point vectors of the initial mesh is also
|
||||
written
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "emptyFvPatch.H"
|
||||
#include "coupledFvPatch.H"
|
||||
#include "pointMesh.H"
|
||||
#include "pointPatchField.H"
|
||||
#include "pointPatchFieldsFwd.H"
|
||||
#include "syncTools.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
timeSelector::addOptions();
|
||||
|
||||
#include "addRegionOption.H"
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
#include "createNamedMesh.H"
|
||||
#include "createFields.H"
|
||||
|
||||
// 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);
|
||||
for (const fvPatch& patch : mesh.boundary())
|
||||
{
|
||||
// Each local patch point belongs to these local patch faces.
|
||||
// Local numbering
|
||||
const labelListList& patchPointFaces = patch.patch().pointFaces();
|
||||
if (!isA<coupledFvPatch>(patch) && !isA<emptyFvPatch>(patch))
|
||||
{
|
||||
const labelList& meshPoints = patch.patch().meshPoints();
|
||||
const vectorField nf(patch.nf());
|
||||
forAll(meshPoints, ppI)
|
||||
{
|
||||
const labelList& pointFaces = patchPointFaces[ppI];
|
||||
forAll(pointFaces, pfI)
|
||||
{
|
||||
const label& localFaceIndex = pointFaces[pfI];
|
||||
pointNormals[meshPoints[ppI]] += nf[localFaceIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sum from all processors
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh, pointNormals, plusEqOp<vector>(), vector::zero
|
||||
);
|
||||
pointNormals /= mag(pointNormals) + VSMALL;
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
Info<< "Time = " << runTime.timeName() << endl;
|
||||
mesh.readUpdate();
|
||||
|
||||
const pointMesh& pMesh(pointMesh::New(mesh));
|
||||
// Point displacement projected to the
|
||||
// unit point normal of the initial geometry
|
||||
pointScalarField normalDisplacement
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"normalDisplacement",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
pMesh,
|
||||
dimensionedScalar(dimless, Zero)
|
||||
);
|
||||
// Point displacement as a vector
|
||||
pointVectorField displacement
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"displacement",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
pMesh,
|
||||
dimensionedVector(dimless, Zero)
|
||||
);
|
||||
|
||||
Info<< "Calculating cumulative mesh movement for time "
|
||||
<< runTime.timeName() << endl;
|
||||
// Normal displacement
|
||||
const pointField& meshPoints = mesh.points();
|
||||
forAll(mesh.boundary(), pI)
|
||||
{
|
||||
const polyPatch& patch = mesh.boundaryMesh()[pI];
|
||||
const labelList& localPoints = patch.meshPoints();
|
||||
forAll(localPoints, ppI)
|
||||
{
|
||||
label pointI = localPoints[ppI];
|
||||
normalDisplacement[pointI] =
|
||||
(meshPoints[pointI] - points0[pointI])
|
||||
& pointNormals[pointI];
|
||||
}
|
||||
}
|
||||
normalDisplacement.write();
|
||||
// Vectorial displacement
|
||||
displacement.primitiveFieldRef() = meshPoints - points0;
|
||||
displacement.write();
|
||||
}
|
||||
|
||||
// Print execution time
|
||||
mesh.time().printExecutionTime(Info);
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
writeActiveDesignVariables.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/writeActiveDesignVariables
|
||||
@ -0,0 +1,14 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/cfdTools \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-lfvOptions \
|
||||
-ldynamicMesh \
|
||||
-lfvMotionSolvers \
|
||||
-ladjointOptimisation
|
||||
@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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
|
||||
writeActiveDesignVariables
|
||||
|
||||
Description
|
||||
Writes the active design variables based on the selected parameterisation
|
||||
scheme, as read from the meshMovement part of optimisationDict.
|
||||
Keeps a back-up of the original optimisationDict in
|
||||
system/optimisationDict.org, as comments in the dict will be lost.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "optMeshMovement.H"
|
||||
#include "updateMethod.H"
|
||||
#include "OFstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
IOdictionary optDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"optimisationDict",
|
||||
mesh.time().caseSystem(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
// Back-up old optimisationDict, to maintain potential comments in it
|
||||
if (Pstream::master())
|
||||
{
|
||||
cp(optDict.objectPath(), optDict.objectPath() + ".org");
|
||||
}
|
||||
|
||||
// Construct mesh movement object and grab active design variables
|
||||
// Will exit with error if not implemented for this type
|
||||
const dictionary& movementDict =
|
||||
optDict.subDict("optimisation").subDict("meshMovement");
|
||||
// Empty patch list will do
|
||||
labelList patchIDs(0);
|
||||
autoPtr<optMeshMovement> movementPtr
|
||||
(optMeshMovement::New(mesh, movementDict, patchIDs));
|
||||
const labelList activeDesignVariables =
|
||||
movementPtr().getActiveDesignVariables();
|
||||
|
||||
// Construct update method to grab the type
|
||||
dictionary& updateMethodDict =
|
||||
optDict.subDict("optimisation").subDict("updateMethod");
|
||||
autoPtr<updateMethod> updMethod(updateMethod::New(mesh, updateMethodDict));
|
||||
|
||||
// Add to appropriate dictionary (creates it if it does not exist)
|
||||
dictionary& coeffsDict = updateMethodDict.subDictOrAdd(updMethod().type());
|
||||
coeffsDict.add<labelList>
|
||||
(
|
||||
"activeDesignVariables",
|
||||
activeDesignVariables,
|
||||
true
|
||||
);
|
||||
|
||||
// Write modified dictionary
|
||||
optDict.regIOobject::writeObject
|
||||
(
|
||||
IOstream::ASCII,
|
||||
IOstream::currentVersion,
|
||||
IOstream::UNCOMPRESSED,
|
||||
true
|
||||
);
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
writeMorpherCPs.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/writeMorpherCPs
|
||||
@ -0,0 +1,13 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/cfdTools \
|
||||
-I$(LIB_SRC)/optimisation/adjointOptimisation/adjoint/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-lfvOptions \
|
||||
-ldynamicMesh \
|
||||
-lfvMotionSolvers \
|
||||
-ladjointOptimisation
|
||||
@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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
|
||||
writeMorpherCPs
|
||||
|
||||
Description
|
||||
Writes the NURBS3DVolume control points corresponding to dynamicMeshDict
|
||||
to csv files. Parametric coordinates are not computed.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "NURBS3DVolume.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
IOdictionary dict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
const dictionary& coeffDict =
|
||||
dict.subDict("volumetricBSplinesMotionSolverCoeffs");
|
||||
|
||||
wordList controlBoxes(coeffDict.get<wordList>("controlBoxes"));
|
||||
|
||||
forAll(controlBoxes, iNURB)
|
||||
{
|
||||
// Creating an object writes the control points in the
|
||||
// constructor
|
||||
NURBS3DVolume::New
|
||||
(
|
||||
coeffDict.subDict(controlBoxes[iNURB]),
|
||||
mesh,
|
||||
false // do not compute parametric coordinates
|
||||
);
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -52,6 +52,9 @@ pointCells::pointCells
|
||||
:
|
||||
zeroATCcells(mesh, dict)
|
||||
{
|
||||
boolList isZeroed(mesh_.nCells(), false);
|
||||
labelList zeroedIDs(mesh_.nCells(), -1);
|
||||
label i(0);
|
||||
forAll(mesh_.boundary(), patchI)
|
||||
{
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
@ -65,7 +68,14 @@ pointCells::pointCells
|
||||
for (const label pointI : meshPoints)
|
||||
{
|
||||
const labelList& pointCells = mesh_.pointCells()[pointI];
|
||||
zeroATCcells_.append(pointCells);
|
||||
for (const label cellI : pointCells)
|
||||
{
|
||||
if (!isZeroed[cellI])
|
||||
{
|
||||
zeroedIDs[i++] = cellI;
|
||||
isZeroed[cellI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,14 +86,22 @@ pointCells::pointCells
|
||||
if (zoneID != -1)
|
||||
{
|
||||
const labelList& zoneCells = mesh_.cellZones()[zoneID];
|
||||
zeroATCcells_.append(zoneCells);
|
||||
for (const label cellI : zoneCells)
|
||||
{
|
||||
if (!isZeroed[cellI])
|
||||
{
|
||||
zeroedIDs[i++] = cellI;
|
||||
isZeroed[cellI] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
zeroedIDs.setSize(i);
|
||||
zeroATCcells_ = zeroedIDs;
|
||||
|
||||
label size = zeroATCcells_.size();
|
||||
reduce(size, sumOp<label>());
|
||||
Info<< "Zeroing ATC on "<< size << " cells" << nl << endl;
|
||||
*/
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -16,6 +16,7 @@ solvers/variablesSet/incompressibleAdjoint/incompressibleAdjointVars.C
|
||||
solvers/solverControl/solverControl/solverControl.C
|
||||
solvers/solverControl/SIMPLEControl/SIMPLEControl/SIMPLEControl.C
|
||||
solvers/solverControl/SIMPLEControl/singleRun/SIMPLEControlSingleRun.C
|
||||
solvers/solverControl/SIMPLEControl/optimisation/SIMPLEControlOpt.C
|
||||
|
||||
/* SOLVERS */
|
||||
solvers/solver/solver.C
|
||||
@ -52,6 +53,8 @@ objectives/incompressible/objectiveIncompressible/objectiveIncompressible.C
|
||||
objectives/incompressible/objectiveForce/objectiveForce.C
|
||||
objectives/incompressible/objectiveMoment/objectiveMoment.C
|
||||
objectives/incompressible/objectivePtLosses/objectivePtLosses.C
|
||||
objectives/incompressible/objectiveForceTarget/objectiveForceTarget.C
|
||||
objectives/incompressible/objectivePartialVolume/objectivePartialVolume.C
|
||||
|
||||
/* OBJECTIVE MANAGER*/
|
||||
objectiveManager/objectiveManager/objectiveManager.C
|
||||
@ -87,8 +90,39 @@ adjointBoundaryConditions/adjointOutletVelocityFlux/adjointOutletVelocityFluxFvP
|
||||
/* DELTA BOUNDARY */
|
||||
deltaBoundary/deltaBoundary.C
|
||||
|
||||
/* NURBS */
|
||||
NURBS=parameterization/NURBS
|
||||
$(NURBS)/NURBSbasis/NURBSbasis.C
|
||||
$(NURBS)/NURBS3DCurve/NURBS3DCurve.C
|
||||
$(NURBS)/NURBS3DSurface/NURBS3DSurface.C
|
||||
$(NURBS)/NURBS3DVolume/NURBS3DVolume/NURBS3DVolume.C
|
||||
$(NURBS)/NURBS3DVolume/cartesian/NURBS3DVolumeCartesian.C
|
||||
$(NURBS)/NURBS3DVolume/cylindrical/NURBS3DVolumeCylindrical.C
|
||||
$(NURBS)/NURBS3DVolume/volBSplinesBase/volBSplinesBase.C
|
||||
|
||||
/* BEZIER */
|
||||
parameterization/Bezier/Bezier.C
|
||||
|
||||
/* MOTION SOLVERS */
|
||||
dynamicMesh/motionSolver/volumetricBSplinesMotionSolver/volumetricBSplinesMotionSolver.C
|
||||
dynamicMesh/motionSolver/elasticityMotionSolver/elasticityMotionSolver.C
|
||||
dynamicMesh/motionSolver/laplacianMotionSolver/laplacianMotionSolver.C
|
||||
|
||||
/* DISPLACEMENT METHOD */
|
||||
displacementMethod/displacementMethod/displacementMethod.C
|
||||
displacementMethod/displacementMethodvolumetricBSplinesMotionSolver/displacementMethodvolumetricBSplinesMotionSolver.C
|
||||
displacementMethod/displacementMethoddisplacementLaplacian/displacementMethoddisplacementLaplacian.C
|
||||
displacementMethod/displacementMethodvelocityLaplacian/displacementMethodvelocityLaplacian.C
|
||||
displacementMethod/displacementMethodelasticityMotionSolver/displacementMethodelasticityMotionSolver.C
|
||||
displacementMethod/displacementMethodlaplacianMotionSolver/displacementMethodlaplacianMotionSolver.C
|
||||
|
||||
/* INTERPOLATION SCHEMES */
|
||||
interpolation/pointVolInterpolation/pointVolInterpolation.C
|
||||
|
||||
|
||||
/* ADJOINT SENSITIVITY */
|
||||
optimisation/adjointSensitivity/sensitivity/sensitivity.C
|
||||
optimisation/adjointSensitivity/shapeSensitivitiesBase/shapeSensitivitiesBase.C
|
||||
incoSens=optimisation/adjointSensitivity/incompressible
|
||||
$(incoSens)/adjointSensitivity/adjointSensitivityIncompressible.C
|
||||
$(incoSens)/adjointEikonalSolver/adjointEikonalSolverIncompressible.C
|
||||
@ -96,21 +130,49 @@ $(incoSens)/adjointMeshMovementSolver/adjointMeshMovementSolverIncompressible.C
|
||||
$(incoSens)/sensitivitySurface/sensitivitySurfaceIncompressible.C
|
||||
$(incoSens)/sensitivitySurfacePoints/sensitivitySurfacePointsIncompressible.C
|
||||
$(incoSens)/sensitivityMultiple/sensitivityMultipleIncompressible.C
|
||||
$(incoSens)/SIBase/SIBaseIncompressible.C
|
||||
$(incoSens)/FIBase/FIBaseIncompressible.C
|
||||
$(incoSens)/sensitivityVolBSplines/sensitivityVolBSplinesIncompressible.C
|
||||
$(incoSens)/sensitivityVolBSplinesFI/sensitivityVolBSplinesFIIncompressible.C
|
||||
$(incoSens)/sensitivityBezier/sensitivityBezierIncompressible.C
|
||||
$(incoSens)/sensitivityBezierFI/sensitivityBezierFIIncompressible.C
|
||||
|
||||
/* LINE SEARCH */
|
||||
optimisation/lineSearch/lineSearch/lineSearch.C
|
||||
optimisation/lineSearch/ArmijoConditions/ArmijoConditions.C
|
||||
optimisation/lineSearch/stepUpdate/stepUpdate/stepUpdate.C
|
||||
optimisation/lineSearch/stepUpdate/bisection/bisection.C
|
||||
optimisation/lineSearch/stepUpdate/quadratic/quadratic.C
|
||||
|
||||
/* UPDATE METHOD */
|
||||
optimisation/updateMethod/updateMethod/updateMethod.C
|
||||
optimisation/updateMethod/constrainedOptimisationMethod/constrainedOptimisationMethod.C
|
||||
updateMethod=optimisation/updateMethod/
|
||||
$(updateMethod)/updateMethod/updateMethod.C
|
||||
$(updateMethod)/constrainedOptimisationMethod/constrainedOptimisationMethod.C
|
||||
$(updateMethod)/steepestDescent/steepestDescent.C
|
||||
$(updateMethod)/BFGS/BFGS.C
|
||||
$(updateMethod)/DBFGS/DBFGS.C
|
||||
$(updateMethod)/LBFGS/LBFGS.C
|
||||
$(updateMethod)/SR1/SR1.C
|
||||
$(updateMethod)/conjugateGradient/conjugateGradient.C
|
||||
$(updateMethod)/constraintProjection/constraintProjection.C
|
||||
$(updateMethod)/SQP/SQP.C
|
||||
|
||||
/* OPT MESH MOVEMENT */
|
||||
optMeshMovement=optimisation/optMeshMovement
|
||||
$(optMeshMovement)/optMeshMovement/optMeshMovement.C
|
||||
$(optMeshMovement)/optMeshMovementVolumetricBSplines/optMeshMovementVolumetricBSplines.C
|
||||
$(optMeshMovement)/optMeshMovementVolumetricBSplinesExternalMotionSolver/optMeshMovementVolumetricBSplinesExternalMotionSolver.C
|
||||
$(optMeshMovement)/optMeshMovementBezier/optMeshMovementBezier.C
|
||||
$(optMeshMovement)/optMeshMovementNULL/optMeshMovementNULL.C
|
||||
|
||||
/* OPTIMIZATION TYPE */
|
||||
incoOptType=optimisation/optimisationType/incompressible
|
||||
$(incoOptType)/optimisationType/optimisationTypeIncompressible.C
|
||||
$(incoOptType)/shapeOptimisation/shapeOptimisationIncompressible.C
|
||||
|
||||
/* OPTIMIZATION MANAGER */
|
||||
optimisation/optimisationManager/optimisationManager/optimisationManager.C
|
||||
optimisation/optimisationManager/singleRun/singleRun.C
|
||||
optimisation/optimisationManager/steadyOptimisation/steadyOptimisation.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libadjointOptimisation
|
||||
|
||||
@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(displacementMethod, 0);
|
||||
defineRunTimeSelectionTable(displacementMethod, dictionary);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::displacementMethod::displacementMethod
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
patchIDs_(patchIDs),
|
||||
motionPtr_(motionSolver::New(mesh_)),
|
||||
maxDisplacement_(SMALL)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::displacementMethod> Foam::displacementMethod::New
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
{
|
||||
// To ensure that displacement method has the same
|
||||
// type as the motion solver, construct it based on its name
|
||||
IOdictionary dynamicMeshDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
word motionSolverName(dynamicMeshDict.get<word>("solver"));
|
||||
word modelType("displacementMethod" + motionSolverName);
|
||||
|
||||
Info<< "displacementMethod type : " << modelType << endl;
|
||||
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalIOErrorInLookup
|
||||
(
|
||||
dynamicMeshDict,
|
||||
"solver",
|
||||
modelType,
|
||||
*dictionaryConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
return autoPtr<displacementMethod>(cstrIter()(mesh, patchIDs));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::displacementMethod::boundControlField(vectorField& controlField)
|
||||
{
|
||||
// Does nothing in base
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::motionSolver>& Foam::displacementMethod::getMotionSolver()
|
||||
{
|
||||
return motionPtr_;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::displacementMethod::getMaxDisplacement() const
|
||||
{
|
||||
return maxDisplacement_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::displacementMethod::update()
|
||||
{
|
||||
scalar timeBef = mesh_.time().elapsedCpuTime();
|
||||
|
||||
// Compute max mesh movement
|
||||
tmp<pointField> tnewPoints = motionPtr_->newPoints();
|
||||
Info<< "Max mesh movement magnitude "
|
||||
<< gMax(mag(tnewPoints() - mesh_.points())) << endl;
|
||||
|
||||
// Update mesh as in dynamicFvMesh
|
||||
mesh_.movePoints(tnewPoints());
|
||||
scalar timeAft = mesh_.time().elapsedCpuTime();
|
||||
Info<< "Mesh movement took " << timeAft - timeBef << " seconds" << endl;
|
||||
mesh_.moving(false);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,171 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethod
|
||||
|
||||
Description
|
||||
Abstract base class for displacement methods, which are a set or
|
||||
wrapper classes allowing to change the driving force of mesh motion solvers
|
||||
|
||||
SourceFiles
|
||||
displacementMethod.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethod_H
|
||||
#define displacementMethod_H
|
||||
|
||||
#include "fvm.H"
|
||||
#include "fvc.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
#include "motionSolver.H"
|
||||
#include "volPointInterpolation.H"
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethod Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
fvMesh& mesh_;
|
||||
|
||||
//- IDs of the patches to be moved
|
||||
const labelList& patchIDs_;
|
||||
|
||||
autoPtr<motionSolver> motionPtr_;
|
||||
|
||||
scalar maxDisplacement_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethod(const displacementMethod&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const displacementMethod&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethod");
|
||||
|
||||
|
||||
// Declare run-time constructor selection table
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
displacementMethod,
|
||||
dictionary,
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
),
|
||||
(mesh, patchIDs)
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethod
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Return a reference to the selected turbulence model
|
||||
static autoPtr<displacementMethod> New
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethod() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
virtual void setMotionField(const pointVectorField& pointMovement) = 0;
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
virtual void setMotionField(const volVectorField& cellMovement) = 0;
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
virtual void setControlField(const vectorField& controlField) = 0;
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
virtual void setControlField(const scalarField& controlField) = 0;
|
||||
|
||||
//- Bound control field in certain directions etc. For methods working
|
||||
//- with parameters (RBF etc)
|
||||
//- does nothing by default
|
||||
virtual void boundControlField(vectorField& controlField);
|
||||
|
||||
//- Get access to motionSolver
|
||||
autoPtr<motionSolver>& getMotionSolver();
|
||||
|
||||
//- Get max displacement
|
||||
scalar getMaxDisplacement() const;
|
||||
|
||||
//- Update mesh
|
||||
void update();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,192 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethoddisplacementLaplacian.H"
|
||||
#include "displacementLaplacianFvMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(displacementMethoddisplacementLaplacian, 1);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
displacementMethod,
|
||||
displacementMethoddisplacementLaplacian,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
displacementMethoddisplacementLaplacian::displacementMethoddisplacementLaplacian
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
displacementMethod(mesh, patchIDs),
|
||||
pointDisplacement_
|
||||
(
|
||||
refCast<displacementLaplacianFvMotionSolver>
|
||||
(
|
||||
motionPtr_()
|
||||
).pointDisplacement()
|
||||
),
|
||||
cellDisplacement_
|
||||
(
|
||||
refCast<displacementLaplacianFvMotionSolver>
|
||||
(
|
||||
motionPtr_()
|
||||
).cellDisplacement()
|
||||
),
|
||||
/*
|
||||
// Getting a reference from the database is dangerous since multiple
|
||||
// fields with the same name might be registered
|
||||
pointDisplacement_
|
||||
(
|
||||
const_cast<pointVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<pointVectorField>("pointDisplacement")
|
||||
)
|
||||
),
|
||||
cellDisplacement_
|
||||
(
|
||||
const_cast<volVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<volVectorField>("cellDisplacement")
|
||||
)
|
||||
),
|
||||
*/
|
||||
resetFields_
|
||||
(
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::AUTO_WRITE,
|
||||
false
|
||||
)
|
||||
).subDict("displacementLaplacianCoeffs").lookupOrDefault<bool>
|
||||
(
|
||||
"resetFields",
|
||||
true
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void displacementMethoddisplacementLaplacian::setMotionField
|
||||
(
|
||||
const pointVectorField& pointMovement
|
||||
)
|
||||
{
|
||||
Info<< "Reseting mesh motion fields to zero " << endl;
|
||||
|
||||
if (resetFields_)
|
||||
{
|
||||
pointDisplacement_.primitiveFieldRef() = vector::zero;
|
||||
cellDisplacement_.primitiveFieldRef() = vector::zero;
|
||||
cellDisplacement_.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
// Set boundary mesh movement and calculate
|
||||
// max current boundary displacement
|
||||
for (label patchI : patchIDs_)
|
||||
{
|
||||
// Set boundary field. Needed for the motionSolver class
|
||||
pointDisplacement_.boundaryFieldRef()[patchI] ==
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()();
|
||||
|
||||
// Set boundary field values as seen from the internalField!
|
||||
// Needed for determining the max displacement
|
||||
pointDisplacement_.boundaryFieldRef()[patchI].setInInternalField
|
||||
(
|
||||
pointDisplacement_.primitiveFieldRef(),
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()()
|
||||
);
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag
|
||||
(
|
||||
pointDisplacement_.boundaryField()[patchI].
|
||||
patchInternalField()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displacementMethoddisplacementLaplacian::setMotionField
|
||||
(
|
||||
const volVectorField& cellMovement
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethoddisplacementLaplacian::setControlField
|
||||
(
|
||||
const vectorField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethoddisplacementLaplacian::setControlField
|
||||
(
|
||||
const scalarField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethoddisplacementLaplacian
|
||||
|
||||
Description
|
||||
Wrapper class for the displacementLaplacian motion solver
|
||||
|
||||
SourceFiles
|
||||
displacementMethoddisplacementLaplacian.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethoddisplacementLaplacian_H
|
||||
#define displacementMethoddisplacementLaplacian_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethoddisplacementLaplacian Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethoddisplacementLaplacian
|
||||
:
|
||||
public displacementMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
pointVectorField& pointDisplacement_;
|
||||
|
||||
volVectorField& cellDisplacement_;
|
||||
|
||||
bool resetFields_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethoddisplacementLaplacian
|
||||
(
|
||||
const displacementMethoddisplacementLaplacian&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const displacementMethoddisplacementLaplacian&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethoddisplacementLaplacian");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethoddisplacementLaplacian
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethoddisplacementLaplacian() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const pointVectorField& pointMovement);
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const volVectorField& cellMovement);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const vectorField& controlField);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const scalarField& controlField);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,215 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethodelasticityMotionSolver.H"
|
||||
#include "elasticityMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(displacementMethodelasticityMotionSolver, 1);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
displacementMethod,
|
||||
displacementMethodelasticityMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
displacementMethodelasticityMotionSolver::
|
||||
displacementMethodelasticityMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
displacementMethod(mesh, patchIDs),
|
||||
pointMotionU_(refCast<elasticityMotionSolver>(motionPtr_()).pointMotionU()),
|
||||
cellMotionU_(refCast<elasticityMotionSolver>(motionPtr_()).cellMotionU()),
|
||||
/*
|
||||
// Getting a reference from the database is dangerous since multiple
|
||||
// fields with the same name might be registered
|
||||
pointMotionU_
|
||||
(
|
||||
const_cast<pointVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<pointVectorField>("pointMotionU")
|
||||
)
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
const_cast<volVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<volVectorField>("cellMotionU")
|
||||
)
|
||||
)
|
||||
*/
|
||||
resetFields_
|
||||
(
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::AUTO_WRITE,
|
||||
false
|
||||
)
|
||||
).subDict("elasticityMotionSolverCoeffs").lookupOrDefault<bool>
|
||||
(
|
||||
"resetFields",
|
||||
true
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void displacementMethodelasticityMotionSolver::setMotionField
|
||||
(
|
||||
const pointVectorField& pointMovement
|
||||
)
|
||||
{
|
||||
if (resetFields_)
|
||||
{
|
||||
pointMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
maxDisplacement_ = SMALL;
|
||||
|
||||
// Update the boundary conditions of the pointField in order to make
|
||||
// sure that the boundary will move according to the initial BCs
|
||||
// without the interferance of the volPointInterpolation in the elasticityMotionSolver
|
||||
for (label patchI : patchIDs_)
|
||||
{
|
||||
// Set boundary field. Needed for the motionSolver class
|
||||
pointMotionU_.boundaryFieldRef()[patchI] ==
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()();
|
||||
|
||||
// Set boundary field values as seen from the internalField!
|
||||
// Needed for determining the max displacement
|
||||
pointMotionU_.boundaryFieldRef()[patchI].setInInternalField
|
||||
(
|
||||
pointMotionU_.primitiveFieldRef(),
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()()
|
||||
);
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag
|
||||
(
|
||||
pointMotionU_.boundaryField()[patchI].
|
||||
patchInternalField()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// update the volField boundary conditions, used for the elasticity PDEs solution
|
||||
const pointField& points = mesh_.points();
|
||||
for (label patchI : patchIDs_)
|
||||
{
|
||||
const polyPatch& patch = mesh_.boundaryMesh()[patchI];
|
||||
fvPatchVectorField& bField = cellMotionU_.boundaryFieldRef()[patchI];
|
||||
forAll(patch, fI)
|
||||
{
|
||||
bField[fI] = patch[fI].average(points, pointMovement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodelasticityMotionSolver::setMotionField
|
||||
(
|
||||
const volVectorField& cellMovement
|
||||
)
|
||||
{
|
||||
auto cellMotionUbf = cellMotionU_.boundaryFieldRef();
|
||||
|
||||
// Set boundary mesh movement and calculate
|
||||
// max current boundary displacement
|
||||
forAll(patchIDs_, pI)
|
||||
{
|
||||
label patchI = patchIDs_[pI];
|
||||
|
||||
// Set boundary field. Needed for the motionSolver class
|
||||
cellMotionUbf[patchI] == cellMovement.boundaryField()[patchI];
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag(cellMotionUbf[patchI])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodelasticityMotionSolver::setControlField
|
||||
(
|
||||
const vectorField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodelasticityMotionSolver::setControlField
|
||||
(
|
||||
const scalarField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,132 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethodelasticityMotionSolver
|
||||
|
||||
Description
|
||||
Wrapper class for the elasticityMotionSolver motion solver
|
||||
|
||||
SourceFiles
|
||||
displacementMethodelasticityMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethodelasticityMotionSolver_H
|
||||
#define displacementMethodelasticityMotionSolver_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethodelasticityMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethodelasticityMotionSolver
|
||||
:
|
||||
public displacementMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
pointVectorField& pointMotionU_;
|
||||
|
||||
volVectorField& cellMotionU_;
|
||||
|
||||
bool resetFields_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethodelasticityMotionSolver
|
||||
(
|
||||
const displacementMethodelasticityMotionSolver&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=
|
||||
(
|
||||
const displacementMethodelasticityMotionSolver&
|
||||
) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethodelasticityMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethodelasticityMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethodelasticityMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const pointVectorField& pointMovement);
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const volVectorField& cellMovement);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const vectorField& controlField);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const scalarField& controlField);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethodlaplacianMotionSolver.H"
|
||||
#include "laplacianMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(displacementMethodlaplacianMotionSolver, 1);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
displacementMethod,
|
||||
displacementMethodlaplacianMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
displacementMethodlaplacianMotionSolver::displacementMethodlaplacianMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
displacementMethod(mesh, patchIDs),
|
||||
pointMotionU_(refCast<laplacianMotionSolver>(motionPtr_()).pointMotionU()),
|
||||
cellMotionU_(refCast<laplacianMotionSolver>(motionPtr_()).cellMotionU()),
|
||||
/*
|
||||
// getting a reference from the database is dangerous since multiple
|
||||
// fields with the same name might be registered
|
||||
pointMotionU_
|
||||
(
|
||||
const_cast<pointVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<pointVectorField>("pointMotionU")
|
||||
)
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
const_cast<volVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<volVectorField>("cellMotionU")
|
||||
)
|
||||
),
|
||||
*/
|
||||
resetFields_
|
||||
(
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::AUTO_WRITE,
|
||||
false
|
||||
)
|
||||
).subDict("laplacianMotionSolverCoeffs").lookupOrDefault<bool>
|
||||
(
|
||||
"resetFields",
|
||||
true
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void displacementMethodlaplacianMotionSolver::setMotionField
|
||||
(
|
||||
const pointVectorField& pointMovement
|
||||
)
|
||||
{
|
||||
if (resetFields_)
|
||||
{
|
||||
pointMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
// Set boundary mesh movement and calculate
|
||||
// max current boundary displacement
|
||||
for (label patchI : patchIDs_)
|
||||
{
|
||||
// Set boundary field. Needed for the motionSolver class
|
||||
pointMotionU_.boundaryFieldRef()[patchI] ==
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()();
|
||||
|
||||
// Set boundary field values as seen from the internalField!
|
||||
// Needed for determining the max displacement
|
||||
pointMotionU_.boundaryFieldRef()[patchI].setInInternalField
|
||||
(
|
||||
pointMotionU_.primitiveFieldRef(),
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()()
|
||||
);
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag
|
||||
(
|
||||
pointMotionU_.boundaryField()[patchI].
|
||||
patchInternalField()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodlaplacianMotionSolver::setMotionField
|
||||
(
|
||||
const volVectorField& cellMovement
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
/*
|
||||
// Set boundary mesh movement and calculate max current boundary
|
||||
// displacement
|
||||
forAll(patchIDs_, pI)
|
||||
{
|
||||
label patchI = patchIDs_[pI];
|
||||
cellMotionU_.boundaryField()[patchI] ==
|
||||
cellMovement.boundaryField()[patchI];
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag(cellMovement.boundaryField()[patchI])
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodlaplacianMotionSolver::setControlField
|
||||
(
|
||||
const vectorField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodlaplacianMotionSolver::setControlField
|
||||
(
|
||||
const scalarField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,129 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethodlaplacianMotionSolver
|
||||
|
||||
Description
|
||||
Wrapper class for the velocityLaplacian motion solver
|
||||
|
||||
SourceFiles
|
||||
displacementMethodlaplacianMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethodlaplacianMotionSolver_H
|
||||
#define displacementMethodlaplacianMotionSolver_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethodlaplacianMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethodlaplacianMotionSolver
|
||||
:
|
||||
public displacementMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
pointVectorField& pointMotionU_;
|
||||
|
||||
volVectorField& cellMotionU_;
|
||||
|
||||
bool resetFields_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethodlaplacianMotionSolver
|
||||
(
|
||||
const displacementMethodlaplacianMotionSolver&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const displacementMethodlaplacianMotionSolver&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethodlaplacianMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethodlaplacianMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethodlaplacianMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const pointVectorField& pointMovement);
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const volVectorField& cellMovement);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const vectorField& controlField);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const scalarField& controlField);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,207 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethodvelocityLaplacian.H"
|
||||
#include "velocityLaplacianFvMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(displacementMethodvelocityLaplacian, 1);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
displacementMethod,
|
||||
displacementMethodvelocityLaplacian,
|
||||
dictionary
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
displacementMethodvelocityLaplacian::displacementMethodvelocityLaplacian
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
displacementMethod(mesh, patchIDs),
|
||||
pointMotionU_
|
||||
(
|
||||
refCast<velocityLaplacianFvMotionSolver>(motionPtr_()).pointMotionU()
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
refCast<velocityLaplacianFvMotionSolver>(motionPtr_()).cellMotionU()
|
||||
),
|
||||
/*
|
||||
// Getting a reference from the database is dangerous since multiple
|
||||
// fields with the same name might be registered
|
||||
pointMotionU_
|
||||
(
|
||||
const_cast<pointVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<pointVectorField>("pointMotionU")
|
||||
)
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
const_cast<volVectorField&>
|
||||
(
|
||||
mesh_.lookupObject<volVectorField>("cellMotionU")
|
||||
)
|
||||
),
|
||||
*/
|
||||
resetFields_
|
||||
(
|
||||
IOdictionary
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dynamicMeshDict",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::AUTO_WRITE,
|
||||
false
|
||||
)
|
||||
).subDict("velocityLaplacianCoeffs").lookupOrDefault<bool>
|
||||
(
|
||||
"resetFields",
|
||||
true
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void displacementMethodvelocityLaplacian::setMotionField
|
||||
(
|
||||
const pointVectorField& pointMovement
|
||||
)
|
||||
{
|
||||
if (resetFields_)
|
||||
{
|
||||
pointMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.primitiveFieldRef() = vector::zero;
|
||||
cellMotionU_.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
// Set boundary mesh movement and calculate
|
||||
// max current boundary displacement
|
||||
for (label patchI : patchIDs_)
|
||||
{
|
||||
// Set boundary field. Needed for the motionSolver class
|
||||
pointMotionU_.boundaryFieldRef()[patchI] ==
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()();
|
||||
|
||||
// Set boundary field values as seen from the internalField!
|
||||
// Needed for determining the max displacement
|
||||
pointMotionU_.boundaryFieldRef()[patchI].setInInternalField
|
||||
(
|
||||
pointMotionU_.primitiveFieldRef(),
|
||||
pointMovement.boundaryField()[patchI].patchInternalField()()
|
||||
);
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag
|
||||
(
|
||||
pointMotionU_.boundaryField()[patchI].
|
||||
patchInternalField()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvelocityLaplacian::setMotionField
|
||||
(
|
||||
const volVectorField& cellMovement
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
|
||||
/*
|
||||
// Set boundary mesh movement and calculate max current boundary
|
||||
// displacement
|
||||
forAll(patchIDs_, pI)
|
||||
{
|
||||
label patchI = patchIDs_[pI];
|
||||
cellMotionU_.boundaryField()[patchI] ==
|
||||
cellMovement.boundaryField()[patchI];
|
||||
|
||||
// Find max value
|
||||
maxDisplacement_ =
|
||||
max
|
||||
(
|
||||
maxDisplacement_,
|
||||
gMax
|
||||
(
|
||||
mag(cellMovement.boundaryField()[patchI])
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvelocityLaplacian::setControlField
|
||||
(
|
||||
const vectorField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvelocityLaplacian::setControlField
|
||||
(
|
||||
const scalarField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,130 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethodvelocityLaplacian
|
||||
|
||||
Description
|
||||
Wrapper class for the velocityLaplacian motion solver
|
||||
|
||||
SourceFiles
|
||||
displacementMethodvelocityLaplacian.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethodvelocityLaplacian_H
|
||||
#define displacementMethodvelocityLaplacian_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethodvelocityLaplacian Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethodvelocityLaplacian
|
||||
:
|
||||
public displacementMethod
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
pointVectorField& pointMotionU_;
|
||||
|
||||
volVectorField& cellMotionU_;
|
||||
|
||||
bool resetFields_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethodvelocityLaplacian
|
||||
(
|
||||
const displacementMethodvelocityLaplacian&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const displacementMethodvelocityLaplacian&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethodvelocityLaplacian");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethodvelocityLaplacian
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethodvelocityLaplacian() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const pointVectorField& pointMovement);
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const volVectorField& cellMovement);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const vectorField& controlField);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const scalarField& controlField);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,119 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "displacementMethodvolumetricBSplinesMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(displacementMethodvolumetricBSplinesMotionSolver, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
displacementMethod,
|
||||
displacementMethodvolumetricBSplinesMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
displacementMethodvolumetricBSplinesMotionSolver::
|
||||
displacementMethodvolumetricBSplinesMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
displacementMethod(mesh, patchIDs)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void displacementMethodvolumetricBSplinesMotionSolver::setMotionField
|
||||
(
|
||||
const pointVectorField& pointMovement
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvolumetricBSplinesMotionSolver::setMotionField
|
||||
(
|
||||
const volVectorField& cellMovement
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvolumetricBSplinesMotionSolver::setControlField
|
||||
(
|
||||
const vectorField& controlField
|
||||
)
|
||||
{
|
||||
// refCast motionSolver to volumetricBSplinesMotionSolver in order to pass
|
||||
// control points movement. Safe since the motionSolver can only be an
|
||||
// volumetricBSplinesMotionSolver
|
||||
refCast<volumetricBSplinesMotionSolver>
|
||||
(motionPtr_()).setControlPointsMovement(controlField);
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvolumetricBSplinesMotionSolver::setControlField
|
||||
(
|
||||
const scalarField& controlField
|
||||
)
|
||||
{
|
||||
NotImplemented;
|
||||
}
|
||||
|
||||
|
||||
void displacementMethodvolumetricBSplinesMotionSolver::boundControlField
|
||||
(
|
||||
vectorField& controlField
|
||||
)
|
||||
{
|
||||
// refCast motionSolver to volumetricBSplinesMotionSolver in order to bound
|
||||
// control points movement. Safe since the motionSolver can only be an
|
||||
// volumetricBSplinesMotionSolver
|
||||
refCast<volumetricBSplinesMotionSolver>
|
||||
(motionPtr_()).boundControlPointsMovement(controlField);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::displacementMethodvolumetricBSplinesMotionSolver
|
||||
|
||||
Description
|
||||
Wrapper class for the volumetricBSplinesMotionSolver motion solver
|
||||
|
||||
SourceFiles
|
||||
displacementMethodvolumetricBSplinesMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef displacementMethodvolumetricBSplinesMotionSolver_H
|
||||
#define displacementMethodvolumetricBSplinesMotionSolver_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
#include "volumetricBSplinesMotionSolver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class displacementMethodvolumetricBSplinesMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class displacementMethodvolumetricBSplinesMotionSolver
|
||||
:
|
||||
public displacementMethod
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
displacementMethodvolumetricBSplinesMotionSolver
|
||||
(
|
||||
const displacementMethodvolumetricBSplinesMotionSolver&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=
|
||||
(
|
||||
const displacementMethodvolumetricBSplinesMotionSolver&
|
||||
) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("displacementMethodvolumetricBSplinesMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
displacementMethodvolumetricBSplinesMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~displacementMethodvolumetricBSplinesMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const pointVectorField& pointMovement);
|
||||
|
||||
//- Set motion filed related to model based on given motion
|
||||
void setMotionField(const volVectorField& cellMovement);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const vectorField& controlField);
|
||||
|
||||
//- Set control field as a vectorField. For methods working with
|
||||
//- parameters (RBF etc)
|
||||
void setControlField(const scalarField& controlField);
|
||||
|
||||
//- Bound control field in certain directions etc. For methods working
|
||||
//- with parameters (RBF etc)
|
||||
void boundControlField(vectorField& controlField);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,271 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "elasticityMotionSolver.H"
|
||||
#include "motionInterpolation.H"
|
||||
#include "wallDist.H"
|
||||
#include "fixedValuePointPatchFields.H"
|
||||
#include "fvMatrices.H"
|
||||
#include "fvcDiv.H"
|
||||
#include "fvmDiv.H"
|
||||
#include "fvmDiv.H"
|
||||
#include "fvmLaplacian.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(elasticityMotionSolver, 1);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
motionSolver,
|
||||
elasticityMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::elasticityMotionSolver::setBoundaryConditions()
|
||||
{
|
||||
// Adjust boundary conditions based on the steps to be executed
|
||||
forAll(pointMotionU_.boundaryField(), patchI)
|
||||
{
|
||||
pointPatchVectorField& pointBCs =
|
||||
pointMotionU_.boundaryFieldRef()[patchI];
|
||||
if (isA<fixedValuePointPatchVectorField>(pointBCs))
|
||||
{
|
||||
auto& fixedValueBCs =
|
||||
refCast<fixedValuePointPatchVectorField>(pointBCs);
|
||||
fixedValueBCs == fixedValueBCs/scalar(nSteps_);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy boundary conditions to internalField
|
||||
// Needed for interpolation to faces
|
||||
pointMotionU_.boundaryFieldRef().updateCoeffs();
|
||||
|
||||
// Interpolate boundary conditions from points to faces
|
||||
forAll(cellMotionU_.boundaryField(), pI)
|
||||
{
|
||||
fvPatchVectorField& bField = cellMotionU_.boundaryFieldRef()[pI];
|
||||
if (isA<fixedValueFvPatchVectorField>(bField))
|
||||
{
|
||||
const pointField& points = fvMesh_.points();
|
||||
const polyPatch& patch = mesh().boundaryMesh()[pI];
|
||||
forAll(bField, fI)
|
||||
{
|
||||
bField[fI] = patch[fI].average(points, pointMotionU_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::elasticityMotionSolver::elasticityMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
)
|
||||
:
|
||||
motionSolver(mesh, dict, typeName),
|
||||
fvMesh_
|
||||
(
|
||||
const_cast<fvMesh&>
|
||||
(
|
||||
refCast<const fvMesh>(mesh)
|
||||
)
|
||||
),
|
||||
pointMotionU_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointMotionU",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
pointMesh::New(mesh),
|
||||
dimensionedVector(dimless, Zero),
|
||||
fixedValuePointPatchVectorField::typeName
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellMotionU",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
fvMesh_,
|
||||
dimensionedVector
|
||||
(
|
||||
"cellMotionU",
|
||||
pointMotionU_.dimensions(),
|
||||
vector::zero
|
||||
),
|
||||
pointMotionU_.boundaryField().types()
|
||||
),
|
||||
interpolationPtr_
|
||||
(
|
||||
coeffDict().found("interpolation")
|
||||
? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
|
||||
: motionInterpolation::New(fvMesh_)
|
||||
),
|
||||
E_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mu",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
fvMesh_,
|
||||
dimensionedScalar(dimless, Zero),
|
||||
zeroGradientFvPatchScalarField::typeName
|
||||
),
|
||||
exponent_(this->coeffDict().get<scalar>("exponent")),
|
||||
nSteps_(this->coeffDict().get<label>("steps")),
|
||||
nIters_(this->coeffDict().get<label>("iters")),
|
||||
tolerance_(this->coeffDict().get<scalar>("tolerance"))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::pointField> Foam::elasticityMotionSolver::curPoints() const
|
||||
{
|
||||
tmp<pointField> tnewPoints(new pointField(mesh().points()));
|
||||
|
||||
return tnewPoints;
|
||||
}
|
||||
|
||||
|
||||
void Foam::elasticityMotionSolver::solve()
|
||||
{
|
||||
// Re-init to zero
|
||||
cellMotionU_.primitiveFieldRef() = vector::zero;
|
||||
|
||||
// Adjust boundary conditions based on the number of steps to be executed
|
||||
// and interpolate to faces
|
||||
setBoundaryConditions();
|
||||
|
||||
// Solve the elasticity equations in a stepped manner
|
||||
for (label istep = 0; istep < nSteps_; ++istep)
|
||||
{
|
||||
Info<< "Step " << istep << endl;
|
||||
|
||||
// Update diffusivity
|
||||
const scalarField& vols = mesh().cellVolumes();
|
||||
E_.primitiveFieldRef() = 1./pow(vols, exponent_);
|
||||
E_.correctBoundaryConditions();
|
||||
|
||||
for (label iter = 0; iter < nIters_; ++iter)
|
||||
{
|
||||
Info<< "Iteration " << iter << endl;
|
||||
cellMotionU_.storePrevIter();
|
||||
fvVectorMatrix dEqn
|
||||
(
|
||||
fvm::laplacian(2*E_, cellMotionU_)
|
||||
+ fvc::div(2*E_*T(fvc::grad(cellMotionU_)))
|
||||
- fvc::div(E_*fvc::div(cellMotionU_)*tensor::I)
|
||||
);
|
||||
|
||||
scalar residual = mag(dEqn.solve().initialResidual());
|
||||
cellMotionU_.relax();
|
||||
|
||||
// Print execution time
|
||||
fvMesh_.time().printExecutionTime(Info);
|
||||
|
||||
// Check convergence
|
||||
if (residual < tolerance_)
|
||||
{
|
||||
Info<< "\n***Reached mesh movement convergence limit for step "
|
||||
<< istep
|
||||
<< " iteration " << iter << "***\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate from cells to points
|
||||
interpolationPtr_->interpolate(cellMotionU_, pointMotionU_);
|
||||
vectorField newPoints
|
||||
(
|
||||
mesh().points() + pointMotionU_.primitiveFieldRef()
|
||||
);
|
||||
|
||||
// Move points and check mesh
|
||||
fvMesh_.movePoints(newPoints);
|
||||
fvMesh_.checkMesh(true);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< " Writing new mesh points " << endl;
|
||||
pointIOField points
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"points",
|
||||
mesh().pointsInstance(),
|
||||
mesh().meshSubDir,
|
||||
mesh(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh().points()
|
||||
);
|
||||
points.write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::elasticityMotionSolver::movePoints(const pointField&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
void Foam::elasticityMotionSolver::updateMesh(const mapPolyMesh&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::elasticityMotionSolver
|
||||
|
||||
Description
|
||||
Mesh deformation based on the linear elasticity equations.
|
||||
The boundary displacement is set as a boundary condition
|
||||
on the pointMotionU field.
|
||||
|
||||
Reference:
|
||||
\verbatim
|
||||
Dwight, R. P., (2009).
|
||||
Robust Mesh Deformation using the Linear Elasticity Equations.
|
||||
Computational Fluid Dynamics 2006, 401-406.
|
||||
Springer Berlin Heidelberg.
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
elasticityMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef elasticityMotionSolver_H
|
||||
#define elasticityMotionSolver_H
|
||||
|
||||
#include "motionSolver.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward class declarations
|
||||
class motionInterpolation;
|
||||
class mapPolyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class elasticityMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class elasticityMotionSolver
|
||||
:
|
||||
public motionSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Since the mesh deformation is broken down to multiple steps,
|
||||
//- mesh points need to be moved here.
|
||||
//- Hence, the non-const mesh reference
|
||||
fvMesh& fvMesh_;
|
||||
pointVectorField pointMotionU_;
|
||||
volVectorField cellMotionU_;
|
||||
|
||||
//- Interpolation used to transfer cell displacement to the points
|
||||
autoPtr<motionInterpolation> interpolationPtr_;
|
||||
|
||||
//- Inverse cell volume diffusivity
|
||||
volScalarField E_;
|
||||
|
||||
//- Exponent to stiffen highly morphed cells
|
||||
scalar exponent_;
|
||||
|
||||
//- Intermidiate steps to solve the PDEs
|
||||
label nSteps_;
|
||||
|
||||
//- Number of laplacian iterations per solution step
|
||||
label nIters_;
|
||||
|
||||
//- Residual threshold
|
||||
scalar tolerance_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set boundary condtions of cellMotionU based on pointMotionU.
|
||||
// Avoiding the use of the cellMotionFvPatchField bc
|
||||
// due to the use of the registry in order to grab pointMotionU, which
|
||||
// may give problems if multiple objects of this class are constructed
|
||||
// at the same time
|
||||
void setBoundaryConditions();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
elasticityMotionSolver(const elasticityMotionSolver&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const elasticityMotionSolver&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("elasticityMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh and dictionary
|
||||
elasticityMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~elasticityMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Get const and non-const references to pointMotionU
|
||||
inline pointVectorField& pointMotionU();
|
||||
inline const pointVectorField& pointMotionU() const;
|
||||
|
||||
//- Get const and non-const references to cellMotionU
|
||||
inline volVectorField& cellMotionU();
|
||||
inline const volVectorField& cellMotionU() const;
|
||||
|
||||
//- Return point location. Mesh is actually moved in solve()
|
||||
virtual tmp<pointField> curPoints() const;
|
||||
|
||||
//- Solve for motion.
|
||||
// Does the actual mesh displacement here, since it is broken down
|
||||
// into multiple steps
|
||||
virtual void solve();
|
||||
|
||||
//- Update local data for geometry changes
|
||||
virtual void movePoints(const pointField&);
|
||||
|
||||
//- Update the mesh corresponding to given map
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "elasticityMotionSolverI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,60 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 Foam::pointVectorField& Foam::elasticityMotionSolver::pointMotionU()
|
||||
{
|
||||
return pointMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::pointVectorField&
|
||||
Foam::elasticityMotionSolver::pointMotionU() const
|
||||
{
|
||||
return pointMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::volVectorField& Foam::elasticityMotionSolver::cellMotionU()
|
||||
{
|
||||
return cellMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::volVectorField&
|
||||
Foam::elasticityMotionSolver::cellMotionU() const
|
||||
{
|
||||
return cellMotionU_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -0,0 +1,189 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "laplacianMotionSolver.H"
|
||||
#include "motionInterpolation.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "fvmLaplacian.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(laplacianMotionSolver, 1);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
motionSolver,
|
||||
laplacianMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::laplacianMotionSolver::setBoundaryConditions()
|
||||
{
|
||||
pointMotionU_.boundaryFieldRef().updateCoeffs();
|
||||
auto& cellMotionUbf = cellMotionU_.boundaryFieldRef();
|
||||
|
||||
forAll(cellMotionU_.boundaryField(), pI)
|
||||
{
|
||||
fvPatchVectorField& bField = cellMotionUbf[pI];
|
||||
if (isA<fixedValueFvPatchVectorField>(bField))
|
||||
{
|
||||
const pointField& points = fvMesh_.points();
|
||||
const polyPatch& patch = fvMesh_.boundaryMesh()[pI];
|
||||
forAll(bField, fI)
|
||||
{
|
||||
bField[fI] = patch[fI].average(points, pointMotionU_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::laplacianMotionSolver::laplacianMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
)
|
||||
:
|
||||
motionSolver(mesh, dict, typeName),
|
||||
fvMotionSolver(mesh),
|
||||
pointMotionU_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointMotionU",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
pointMesh::New(mesh),
|
||||
dimensionedVector(dimless, Zero),
|
||||
fixedValuePointPatchVectorField::typeName
|
||||
),
|
||||
cellMotionU_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellMotionU",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
fvMesh_,
|
||||
dimensionedVector
|
||||
(
|
||||
"cellMotionU",
|
||||
pointMotionU_.dimensions(),
|
||||
vector::zero
|
||||
),
|
||||
pointMotionU_.boundaryField().types()
|
||||
),
|
||||
interpolationPtr_
|
||||
(
|
||||
coeffDict().found("interpolation")
|
||||
? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
|
||||
: motionInterpolation::New(fvMesh_)
|
||||
),
|
||||
nIters_(this->coeffDict().get<label>("iters")),
|
||||
tolerance_(this->coeffDict().get<scalar>("tolerance"))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::pointField> Foam::laplacianMotionSolver::curPoints() const
|
||||
{
|
||||
interpolationPtr_->interpolate
|
||||
(
|
||||
cellMotionU_,
|
||||
pointMotionU_
|
||||
);
|
||||
|
||||
tmp<vectorField> tcurPoints
|
||||
(
|
||||
fvMesh_.points() + pointMotionU_.internalField()
|
||||
);
|
||||
|
||||
twoDCorrectPoints(tcurPoints.ref());
|
||||
|
||||
return tcurPoints;
|
||||
}
|
||||
|
||||
|
||||
void Foam::laplacianMotionSolver::solve()
|
||||
{
|
||||
setBoundaryConditions();
|
||||
|
||||
// Iteratively solve the Laplace equation, to account for non-orthogonality
|
||||
for (label iter = 0; iter < nIters_; ++iter)
|
||||
{
|
||||
Info<< "Iteration " << iter << endl;
|
||||
fvVectorMatrix dEqn
|
||||
(
|
||||
fvm::laplacian(cellMotionU_)
|
||||
);
|
||||
|
||||
scalar residual = mag(dEqn.solve().initialResidual());
|
||||
|
||||
// Print execution time
|
||||
fvMesh_.time().printExecutionTime(Info);
|
||||
|
||||
// Check convergence
|
||||
if (residual < tolerance_)
|
||||
{
|
||||
Info<< "\n***Reached mesh movement convergence limit at"
|
||||
<< " iteration " << iter << "***\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::laplacianMotionSolver::movePoints(const pointField&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
void Foam::laplacianMotionSolver::updateMesh(const mapPolyMesh&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::laplacianMotionSolver
|
||||
|
||||
Description
|
||||
Similar to velocityLaplacian but iteratively solves the mesh displacement
|
||||
PDEs to account for non-orthogonality.
|
||||
The boundary displacement is set as a boundary condition
|
||||
on pointMotionU; the latter is generated automatically if not found.
|
||||
Assumes uniform diffusivity
|
||||
|
||||
SourceFiles
|
||||
laplacianMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef laplacianMotionSolver_H
|
||||
#define laplacianMotionSolver_H
|
||||
|
||||
#include "velocityMotionSolver.H"
|
||||
#include "fvMotionSolver.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "polyMesh.H"
|
||||
#include "pointMesh.H"
|
||||
#include "pointPatchField.H"
|
||||
#include "pointPatchFieldsFwd.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward class declarations
|
||||
class motionInterpolation;
|
||||
class mapPolyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class laplacianMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class laplacianMotionSolver
|
||||
:
|
||||
public motionSolver,
|
||||
public fvMotionSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
mutable pointVectorField pointMotionU_;
|
||||
volVectorField cellMotionU_;
|
||||
|
||||
//- Interpolation used to transfer cell displacement to the points
|
||||
autoPtr<motionInterpolation> interpolationPtr_;
|
||||
|
||||
//- Number of laplacian iterations per solution step
|
||||
label nIters_;
|
||||
|
||||
//- Residual threshold
|
||||
scalar tolerance_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set boundary condtions of cellMotionU based on pointMotionU.
|
||||
// Avoiding the use of the cellMotionFvPatchField bc
|
||||
// due to the use of the registry in order to grab pointMotionU, which
|
||||
// may give problems if multiple objects of this class are constructed
|
||||
// at the same time
|
||||
void setBoundaryConditions();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
laplacianMotionSolver(const laplacianMotionSolver&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const laplacianMotionSolver&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("laplacianMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh and dictionary
|
||||
laplacianMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~laplacianMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Get const and non-const references to pointMotionU
|
||||
inline pointVectorField& pointMotionU();
|
||||
inline const pointVectorField& pointMotionU() const;
|
||||
|
||||
//- Get const and non-const references to cellMotionU
|
||||
inline volVectorField& cellMotionU();
|
||||
inline const volVectorField& cellMotionU() const;
|
||||
|
||||
//- Return point location obtained from the current motion field
|
||||
virtual tmp<pointField> curPoints() const;
|
||||
|
||||
//- Solve for motion
|
||||
virtual void solve();
|
||||
|
||||
//- Update local data for geometry changes
|
||||
virtual void movePoints(const pointField&);
|
||||
|
||||
//- Update the mesh corresponding to given map
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "laplacianMotionSolverI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 Foam::pointVectorField& Foam::laplacianMotionSolver::pointMotionU()
|
||||
{
|
||||
return pointMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::pointVectorField&
|
||||
Foam::laplacianMotionSolver::pointMotionU() const
|
||||
{
|
||||
return pointMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::volVectorField& Foam::laplacianMotionSolver::cellMotionU()
|
||||
{
|
||||
return cellMotionU_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::volVectorField&
|
||||
Foam::laplacianMotionSolver::cellMotionU() const
|
||||
{
|
||||
return cellMotionU_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
|
||||
@ -0,0 +1,154 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "volumetricBSplinesMotionSolver.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(volumetricBSplinesMotionSolver, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
motionSolver,
|
||||
volumetricBSplinesMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::volumetricBSplinesMotionSolver::volumetricBSplinesMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
)
|
||||
:
|
||||
motionSolver(mesh, dict, typeName),
|
||||
volBSplinesBase_
|
||||
(
|
||||
const_cast<volBSplinesBase&>
|
||||
(
|
||||
volBSplinesBase::New(refCast<fvMesh>(const_cast<polyMesh&>(mesh)))
|
||||
)
|
||||
),
|
||||
controlPointsMovement_
|
||||
(
|
||||
volBSplinesBase_.getTotalControlPointsNumber(),
|
||||
vector::zero
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::pointField>
|
||||
Foam::volumetricBSplinesMotionSolver::curPoints() const
|
||||
{
|
||||
tmp<vectorField> tPointMovement(new vectorField(mesh().points()));
|
||||
vectorField& pointMovement = tPointMovement.ref();
|
||||
|
||||
label pastControlPoints(0);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
const label nb = boxes[iNURB].getControlPoints().size();
|
||||
vectorField localControlPointsMovement(nb, vector::zero);
|
||||
|
||||
forAll(localControlPointsMovement, iCP)
|
||||
{
|
||||
localControlPointsMovement[iCP] =
|
||||
controlPointsMovement_[pastControlPoints + iCP];
|
||||
}
|
||||
|
||||
tmp<vectorField>
|
||||
partialMovement
|
||||
(
|
||||
boxes[iNURB].computeNewPoints
|
||||
(
|
||||
localControlPointsMovement
|
||||
)
|
||||
);
|
||||
|
||||
pointMovement += partialMovement() - mesh().points();
|
||||
|
||||
pastControlPoints += nb;
|
||||
}
|
||||
|
||||
return tPointMovement;
|
||||
}
|
||||
|
||||
|
||||
void Foam::volumetricBSplinesMotionSolver::solve()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
void Foam::volumetricBSplinesMotionSolver::movePoints(const pointField&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
void Foam::volumetricBSplinesMotionSolver::updateMesh(const mapPolyMesh&)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
void Foam::volumetricBSplinesMotionSolver::setControlPointsMovement
|
||||
(
|
||||
const vectorField& controlPointsMovement
|
||||
)
|
||||
{
|
||||
if (controlPointsMovement_.size() != controlPointsMovement.size())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempting to replace controlPointsMovement with a set of "
|
||||
<< "different size"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
controlPointsMovement_ = controlPointsMovement;
|
||||
}
|
||||
|
||||
|
||||
void Foam::volumetricBSplinesMotionSolver::boundControlPointsMovement
|
||||
(
|
||||
vectorField& controlPointsMovement
|
||||
)
|
||||
{
|
||||
volBSplinesBase_.boundControlPointsMovement(controlPointsMovement);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::volumetricBSplinesMotionSolver
|
||||
|
||||
Description
|
||||
A mesh motion solver based on volumetric B-Splines
|
||||
|
||||
SourceFiles
|
||||
volumetricBSplinesMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef volumetricBSplinesMotionSolver_H
|
||||
#define volumetricBSplinesMotionSolver_H
|
||||
|
||||
#include "motionSolver.H"
|
||||
#include "volBSplinesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class mapPolyMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class volumetricBSplinesMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class volumetricBSplinesMotionSolver
|
||||
:
|
||||
public motionSolver
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to the underlaying volumetric B-Splines base
|
||||
volBSplinesBase& volBSplinesBase_;
|
||||
|
||||
//- Movement of the control points
|
||||
vectorField controlPointsMovement_;
|
||||
|
||||
//- Number of control boxes
|
||||
wordList controlBoxes_;
|
||||
|
||||
//- List with volumetric B-splines boxes. No overlapping is supported
|
||||
mutable List<autoPtr<NURBS3DVolume>> volume_;
|
||||
|
||||
//- Number of control boxes
|
||||
label nBoxes_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
volumetricBSplinesMotionSolver
|
||||
(
|
||||
const volumetricBSplinesMotionSolver&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const volumetricBSplinesMotionSolver&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplinesMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh and dictionary
|
||||
volumetricBSplinesMotionSolver
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const IOdictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~volumetricBSplinesMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return point location obtained from the current motion field
|
||||
virtual tmp<pointField> curPoints() const;
|
||||
|
||||
//- Solve for motion/ Does nothing
|
||||
virtual void solve();
|
||||
|
||||
//- Update local data for geometry changes
|
||||
virtual void movePoints(const pointField&);
|
||||
|
||||
//- Update the mesh corresponding to given map
|
||||
virtual void updateMesh(const mapPolyMesh&);
|
||||
|
||||
//- Set control points movement
|
||||
void setControlPointsMovement(const vectorField& controlPointsMovement);
|
||||
|
||||
//- Bound control points movement
|
||||
void boundControlPointsMovement(vectorField& controlPointsMovement);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) Wikki Ltd
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "pointVolInterpolation.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "emptyFvPatch.H"
|
||||
#include "globalMeshData.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::pointVolInterpolation::interpolate
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& pf,
|
||||
GeometricField<Type, fvPatchField, volMesh>& vf
|
||||
) const
|
||||
{
|
||||
DebugInFunction
|
||||
<< "interpolating field from points to cells"
|
||||
<< endl;
|
||||
|
||||
const FieldField<Field, scalar>& weights = volWeights();
|
||||
const labelListList& cellPoints = vf.mesh().cellPoints();
|
||||
|
||||
// Multiply pointField by weighting factor matrix to create volField
|
||||
forAll(cellPoints, cellI)
|
||||
{
|
||||
vf[cellI] = pTraits<Type>::zero;
|
||||
|
||||
const labelList& curCellPoints = cellPoints[cellI];
|
||||
|
||||
forAll(curCellPoints, cellPointI)
|
||||
{
|
||||
vf[cellI] +=
|
||||
weights[cellI][cellPointI]*pf[curCellPoints[cellPointI]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Interpolate patch values: over-ride the internal values for the points
|
||||
// on the patch with the interpolated point values from the faces
|
||||
const fvBoundaryMesh& bm = vMesh().boundary();
|
||||
|
||||
const PtrList<primitivePatchInterpolation>& pi = patchInterpolators();
|
||||
forAll(bm, patchI)
|
||||
{
|
||||
// If the patch is empty, skip it
|
||||
if (bm[patchI].type() != emptyFvPatch::typeName)
|
||||
{
|
||||
vf.boundaryFieldRef()[patchI] =
|
||||
pi[patchI].pointToFaceInterpolate
|
||||
(
|
||||
pf.boundaryField()[patchI].patchInternalField()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
vf.correctBoundaryConditions();
|
||||
|
||||
DebugInFunction
|
||||
<< "finished interpolating field from points to cells"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::pointVolInterpolation::interpolate
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& pf
|
||||
) const
|
||||
{
|
||||
// Construct tmp<pointField>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf
|
||||
(
|
||||
new GeometricField<Type, fvPatchField, volMesh>
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointVolInterpolate(" + pf.name() + ')',
|
||||
pf.instance(),
|
||||
pf.db()
|
||||
),
|
||||
vMesh(),
|
||||
pf.dimensions()
|
||||
)
|
||||
);
|
||||
|
||||
// Perform interpolation
|
||||
interpolate(pf, tvf.ref());
|
||||
|
||||
return tvf;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::pointVolInterpolation::interpolate
|
||||
(
|
||||
const tmp<GeometricField<Type, pointPatchField, pointMesh>>& tpf
|
||||
) const
|
||||
{
|
||||
// Construct tmp<volField>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>> tvf =
|
||||
interpolate(tpf());
|
||||
tpf.clear();
|
||||
return tvf;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,225 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) Wikki Ltd
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "pointVolInterpolation.H"
|
||||
#include "fvMesh.H"
|
||||
#include "pointFields.H"
|
||||
#include "volFields.H"
|
||||
#include "emptyFvPatch.H"
|
||||
#include "SubField.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "globalMeshData.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(pointVolInterpolation, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::pointVolInterpolation::makeWeights() const
|
||||
{
|
||||
if (volWeightsPtr_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "weighting factors already calculated"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "pointVolInterpolation::makeWeights() : "
|
||||
<< "constructing weighting factors"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const pointField& points = vMesh().points();
|
||||
const labelListList& cellPoints = vMesh().cellPoints();
|
||||
const vectorField& cellCentres = vMesh().cellCentres();
|
||||
|
||||
// Allocate storage for weighting factors
|
||||
volWeightsPtr_ = new FieldField<Field, scalar>(cellCentres.size());
|
||||
FieldField<Field, scalar>& weightingFactors = *volWeightsPtr_;
|
||||
|
||||
forAll(weightingFactors, pointi)
|
||||
{
|
||||
weightingFactors.set
|
||||
(
|
||||
pointi,
|
||||
new scalarField(cellPoints[pointi].size())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Calculate inverse distances between points and cell centres
|
||||
// and store in weighting factor array
|
||||
forAll(cellCentres, cellI)
|
||||
{
|
||||
const labelList& curCellPoints = cellPoints[cellI];
|
||||
|
||||
forAll(curCellPoints, cellPointI)
|
||||
{
|
||||
weightingFactors[cellI][cellPointI] = 1.0/
|
||||
mag
|
||||
(
|
||||
cellCentres[cellI] - points[curCellPoints[cellPointI]]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
scalarField pointVolSumWeights(cellCentres.size(), Zero);
|
||||
|
||||
// Calculate weighting factors using inverse distance weighting
|
||||
forAll(cellCentres, cellI)
|
||||
{
|
||||
const labelList& curCellPoints = cellPoints[cellI];
|
||||
|
||||
forAll(curCellPoints, cellPointI)
|
||||
{
|
||||
pointVolSumWeights[cellI] += weightingFactors[cellI][cellPointI];
|
||||
}
|
||||
}
|
||||
|
||||
forAll(cellCentres, cellI)
|
||||
{
|
||||
const labelList& curCellPoints = cellPoints[cellI];
|
||||
|
||||
forAll(curCellPoints, cellPointI)
|
||||
{
|
||||
weightingFactors[cellI][cellPointI] /= pointVolSumWeights[cellI];
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "pointVolInterpolation::makeWeights() : "
|
||||
<< "finished constructing weighting factors"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do what is neccessary if the mesh has changed topology
|
||||
void Foam::pointVolInterpolation::clearAddressing() const
|
||||
{
|
||||
deleteDemandDrivenData(patchInterpolatorsPtr_);
|
||||
}
|
||||
|
||||
|
||||
// Do what is neccessary if the mesh has moved
|
||||
void Foam::pointVolInterpolation::clearGeom() const
|
||||
{
|
||||
deleteDemandDrivenData(volWeightsPtr_);
|
||||
}
|
||||
|
||||
|
||||
const Foam::PtrList<Foam::primitivePatchInterpolation>&
|
||||
Foam::pointVolInterpolation::patchInterpolators() const
|
||||
{
|
||||
if (!patchInterpolatorsPtr_)
|
||||
{
|
||||
const fvBoundaryMesh& bdry = vMesh().boundary();
|
||||
|
||||
patchInterpolatorsPtr_ =
|
||||
new PtrList<primitivePatchInterpolation>(bdry.size());
|
||||
|
||||
forAll(bdry, patchI)
|
||||
{
|
||||
patchInterpolatorsPtr_->set
|
||||
(
|
||||
patchI,
|
||||
new primitivePatchInterpolation(bdry[patchI].patch())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return *patchInterpolatorsPtr_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::pointVolInterpolation::pointVolInterpolation
|
||||
(
|
||||
const pointMesh& pm,
|
||||
const fvMesh& vm
|
||||
)
|
||||
:
|
||||
pointMesh_(pm),
|
||||
fvMesh_(vm),
|
||||
volWeightsPtr_(nullptr),
|
||||
patchInterpolatorsPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::pointVolInterpolation::~pointVolInterpolation()
|
||||
{
|
||||
clearAddressing();
|
||||
clearGeom();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// Return point weights
|
||||
const Foam::FieldField<Foam::Field, Foam::scalar>&
|
||||
Foam::pointVolInterpolation::volWeights() const
|
||||
{
|
||||
// If weighting factor array not present then construct
|
||||
if (!volWeightsPtr_)
|
||||
{
|
||||
makeWeights();
|
||||
}
|
||||
|
||||
return *volWeightsPtr_;
|
||||
}
|
||||
|
||||
|
||||
// Do what is neccessary if the mesh has moved
|
||||
void Foam::pointVolInterpolation::updateTopology()
|
||||
{
|
||||
clearAddressing();
|
||||
clearGeom();
|
||||
}
|
||||
|
||||
|
||||
// Do what is neccessary if the mesh has moved
|
||||
bool Foam::pointVolInterpolation::movePoints()
|
||||
{
|
||||
clearGeom();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) Wikki Ltd
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::pointVolInterpolation
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
pointVolInterpolation.C
|
||||
pointVolInterpolate.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef pointVolInterpolation_H
|
||||
#define pointVolInterpolation_H
|
||||
|
||||
#include "primitiveFieldsFwd.H"
|
||||
#include "primitivePatchInterpolation.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "pointFieldsFwd.H"
|
||||
#include "scalarList.H"
|
||||
#include "tmp.H"
|
||||
#include "className.H"
|
||||
#include "FieldFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
class fvMesh;
|
||||
class pointMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class pointVolInterpolation Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class pointVolInterpolation
|
||||
{
|
||||
// Private data
|
||||
|
||||
const pointMesh& pointMesh_;
|
||||
const fvMesh& fvMesh_;
|
||||
|
||||
//- Interpolation scheme weighting factor array.
|
||||
mutable FieldField<Field, scalar>* volWeightsPtr_;
|
||||
|
||||
//- Primitive patch interpolators
|
||||
mutable PtrList<primitivePatchInterpolation>* patchInterpolatorsPtr_;
|
||||
|
||||
|
||||
// Private member functions
|
||||
|
||||
//- Return patch interpolators
|
||||
const PtrList<primitivePatchInterpolation>& patchInterpolators() const;
|
||||
|
||||
//- Construct point weighting factors
|
||||
void makeWeights() const;
|
||||
|
||||
//- Clear addressing
|
||||
void clearAddressing() const;
|
||||
|
||||
//- Clear geometry
|
||||
void clearGeom() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const pointMesh& pMesh() const
|
||||
{
|
||||
return pointMesh_;
|
||||
}
|
||||
|
||||
const fvMesh& vMesh() const
|
||||
{
|
||||
return fvMesh_;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Declare name of the class and it's debug switch
|
||||
ClassName("pointVolInterpolation");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Constructor given pointMesh and fvMesh.
|
||||
pointVolInterpolation(const pointMesh&, const fvMesh&);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~pointVolInterpolation();
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return reference to weights arrays.
|
||||
// This also constructs the weighting factors if neccessary.
|
||||
const FieldField<Field, scalar>& volWeights() const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Update mesh topology using the morph engine
|
||||
void updateTopology();
|
||||
|
||||
//- Correct weighting factors for moving mesh.
|
||||
bool movePoints();
|
||||
|
||||
|
||||
// Interpolation functions
|
||||
|
||||
//- Interpolate from pointField to volField
|
||||
// using inverse distance weighting
|
||||
template<class Type>
|
||||
void interpolate
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>&,
|
||||
GeometricField<Type, fvPatchField, volMesh>&
|
||||
) const;
|
||||
|
||||
//- Interpolate pointField returning volField
|
||||
// using inverse distance weighting
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>> interpolate
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>&
|
||||
) const;
|
||||
|
||||
//- Interpolate tmp<pointField> returning volField
|
||||
// using inverse distance weighting
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>> interpolate
|
||||
(
|
||||
const tmp<GeometricField<Type, pointPatchField, pointMesh>>&
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "pointVolInterpolate.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -171,12 +171,40 @@ void objectiveManager::update()
|
||||
}
|
||||
|
||||
|
||||
void objectiveManager::updateOrNullify()
|
||||
{
|
||||
//- Update contributions to adjoint if true, otherwise return nulls
|
||||
for (objective& obj : objectives_)
|
||||
{
|
||||
if (obj.isWithinIntegrationTime())
|
||||
{
|
||||
obj.update();
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.nullify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void objectiveManager::incrementIntegrationTimes(const scalar timeSpan)
|
||||
{
|
||||
// Update start and end integration times by adding the timeSpan
|
||||
// of the optimisation cycle
|
||||
for (objective& obj : objectives_)
|
||||
{
|
||||
obj.incrementIntegrationTimes(timeSpan);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scalar objectiveManager::print()
|
||||
{
|
||||
scalar objValue(Zero);
|
||||
for (objective& obj : objectives_)
|
||||
{
|
||||
scalar cost = obj.J();
|
||||
scalar cost = obj.JCycle();
|
||||
scalar weight = obj.weight();
|
||||
objValue += weight*cost;
|
||||
|
||||
@ -236,6 +264,21 @@ const word& objectiveManager::primalSolverName() const
|
||||
}
|
||||
|
||||
|
||||
void objectiveManager::checkIntegrationTimes() const
|
||||
{
|
||||
for (const objective& obj : objectives_)
|
||||
{
|
||||
if (!obj.hasIntegrationStartTime() || !obj.hasIntegrationEndTime())
|
||||
{
|
||||
FatalErrorInFunction()
|
||||
<< "Objective function " << obj.objectiveName()
|
||||
<< " does not have a defined integration start or end time "
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -136,6 +136,12 @@ public:
|
||||
//- Update objective function related values
|
||||
void update();
|
||||
|
||||
//- Update contributions to adjoint if true, otherwise return nulls
|
||||
void updateOrNullify();
|
||||
|
||||
//- Increment integration times by the optimisation cycle time-span
|
||||
void incrementIntegrationTimes(const scalar timeSpan);
|
||||
|
||||
//- Print to screen
|
||||
scalar print();
|
||||
|
||||
@ -161,6 +167,9 @@ public:
|
||||
//- Return name of the primalSolver
|
||||
const word& primalSolverName() const;
|
||||
|
||||
//- Check integration times for unsteady runs
|
||||
void checkIntegrationTimes() const;
|
||||
|
||||
//- Add contribution to adjoint momentum PDEs
|
||||
virtual void addUaEqnSource(fvVectorMatrix& UaEqn) = 0;
|
||||
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "objectiveForceTarget.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IOmanip.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace objectives
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(objectiveForceTarget, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
objectiveIncompressible,
|
||||
objectiveForceTarget,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
objectiveForceTarget::objectiveForceTarget
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName,
|
||||
const word& primalSolverName
|
||||
)
|
||||
:
|
||||
objectiveForce(mesh, dict, adjointSolverName, primalSolverName),
|
||||
force_(Zero),
|
||||
target_(dict.get<scalar>("target"))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
scalar objectiveForceTarget::J()
|
||||
{
|
||||
force_ = objectiveForce::J();
|
||||
J_ = force_ - target_;
|
||||
return J_;
|
||||
}
|
||||
|
||||
|
||||
void objectiveForceTarget::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(3) << "#" << " "
|
||||
<< setw(width) << "J" << " "
|
||||
<< setw(width) << "Force" << " "
|
||||
<< setw(width) << "Target" << endl;
|
||||
};
|
||||
|
||||
objFunctionFilePtr_()
|
||||
<< setw(3) << mesh_.time().value() << " "
|
||||
<< setw(width) << J_ << " "
|
||||
<< setw(width) << force_ << " "
|
||||
<< setw(width) << target_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace objectives
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,108 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::objectiveForceTarget
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
objectiveForceTarget.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef objectiveForceTarget_H
|
||||
#define objectiveForceTarget_H
|
||||
|
||||
#include "objectiveForce.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace objectives
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class objectiveForceTarget Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class objectiveForceTarget
|
||||
:
|
||||
public objectiveForce
|
||||
{
|
||||
// Private data
|
||||
|
||||
scalar force_;
|
||||
|
||||
scalar target_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("forceTarget");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
objectiveForceTarget
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName,
|
||||
const word& primalSolverName
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~objectiveForceTarget() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the objective function value
|
||||
scalar J();
|
||||
|
||||
//- Write objective value
|
||||
void write() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace objectives
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -63,7 +63,7 @@ objectiveIncompressible::objectiveIncompressible
|
||||
vars_
|
||||
(
|
||||
mesh.lookupObject<incompressiblePrimalSolver>(primalSolverName).
|
||||
getVars()
|
||||
getIncoVars()
|
||||
),
|
||||
|
||||
// Initialize pointers to nullptr.
|
||||
@ -421,6 +421,67 @@ void objectiveIncompressible::update()
|
||||
}
|
||||
|
||||
|
||||
void objectiveIncompressible::nullify()
|
||||
{
|
||||
if (!nullified_)
|
||||
{
|
||||
if (hasdJdv())
|
||||
{
|
||||
dJdvPtr_() == dimensionedVector(dJdvPtr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasdJdp())
|
||||
{
|
||||
dJdpPtr_() == dimensionedScalar(dJdpPtr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasdJdT())
|
||||
{
|
||||
dJdTPtr_() == dimensionedScalar(dJdTPtr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasdJdTMVar1())
|
||||
{
|
||||
dJdTMvar1Ptr_() ==
|
||||
dimensionedScalar(dJdTMvar1Ptr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasdJdTMVar2())
|
||||
{
|
||||
dJdTMvar2Ptr_() ==
|
||||
dimensionedScalar(dJdTMvar2Ptr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasBoundarydJdv())
|
||||
{
|
||||
bdJdvPtr_() == vector::zero;
|
||||
}
|
||||
if (hasBoundarydJdvn())
|
||||
{
|
||||
bdJdvnPtr_() == scalar(0);
|
||||
}
|
||||
if (hasBoundarydJdvt())
|
||||
{
|
||||
bdJdvtPtr_() == vector::zero;
|
||||
}
|
||||
if (hasBoundarydJdp())
|
||||
{
|
||||
bdJdpPtr_() == vector::zero;
|
||||
}
|
||||
if (hasBoundarydJdT())
|
||||
{
|
||||
bdJdTPtr_() == scalar(0);
|
||||
}
|
||||
if (hasBoundarydJdTMVar1())
|
||||
{
|
||||
bdJdTMvar1Ptr_() == scalar(0);
|
||||
}
|
||||
if (hasBoundarydJdTMVar2())
|
||||
{
|
||||
bdJdTMvar2Ptr_() == scalar(0);
|
||||
}
|
||||
|
||||
// Nullify geometric fields and sets nullified_ to true
|
||||
objective::nullify();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void objectiveIncompressible::write() const
|
||||
{
|
||||
objective::write();
|
||||
|
||||
@ -226,7 +226,10 @@ public:
|
||||
const boundaryScalarField& boundarydJdTMvar2();
|
||||
|
||||
//- Update objective function derivatives
|
||||
void update();
|
||||
virtual void update();
|
||||
|
||||
//- Update objective function derivatives
|
||||
virtual void nullify();
|
||||
|
||||
//- Update vol and boundary fields and derivatives
|
||||
// Do nothing in the base. The relevant ones should be overwritten
|
||||
@ -303,18 +306,18 @@ public:
|
||||
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();
|
||||
inline bool hasdJdv() const;
|
||||
inline bool hasdJdp() const;
|
||||
inline bool hasdJdT() const;
|
||||
inline bool hasdJdTMVar1() const;
|
||||
inline bool hasdJdTMVar2() const;
|
||||
inline bool hasBoundarydJdv() const;
|
||||
inline bool hasBoundarydJdvn() const;
|
||||
inline bool hasBoundarydJdvt() const;
|
||||
inline bool hasBoundarydJdp() const;
|
||||
inline bool hasBoundarydJdT() const;
|
||||
inline bool hasBoundarydJdTMVar1() const;
|
||||
inline bool hasBoundarydJdTMVar2() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -30,73 +30,73 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasdJdv()
|
||||
inline bool Foam::objectiveIncompressible::hasdJdv() const
|
||||
{
|
||||
return dJdvPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasdJdp()
|
||||
inline bool Foam::objectiveIncompressible::hasdJdp() const
|
||||
{
|
||||
return dJdpPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasdJdT()
|
||||
inline bool Foam::objectiveIncompressible::hasdJdT() const
|
||||
{
|
||||
return dJdTPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasdJdTMVar1()
|
||||
inline bool Foam::objectiveIncompressible::hasdJdTMVar1() const
|
||||
{
|
||||
return dJdTMvar1Ptr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasdJdTMVar2()
|
||||
inline bool Foam::objectiveIncompressible::hasdJdTMVar2() const
|
||||
{
|
||||
return dJdTMvar2Ptr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdv()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdv() const
|
||||
{
|
||||
return bdJdvPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdvn()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdvn() const
|
||||
{
|
||||
return bdJdvnPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdvt()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdvt() const
|
||||
{
|
||||
return bdJdvtPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdp()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdp() const
|
||||
{
|
||||
return bdJdpPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdT()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdT() const
|
||||
{
|
||||
return bdJdTPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar1()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar1() const
|
||||
{
|
||||
return bdJdTMvar1Ptr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar2()
|
||||
inline bool Foam::objectiveIncompressible::hasBoundarydJdTMVar2() const
|
||||
{
|
||||
return bdJdTMvar2Ptr_.valid();
|
||||
}
|
||||
|
||||
@ -0,0 +1,168 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "objectivePartialVolume.H"
|
||||
#include "createZeroField.H"
|
||||
#include "IOmanip.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace objectives
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(objectivePartialVolume, 1);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
objectiveIncompressible,
|
||||
objectivePartialVolume,
|
||||
dictionary
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
objectivePartialVolume::objectivePartialVolume
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName,
|
||||
const word& primalSolverName
|
||||
)
|
||||
:
|
||||
objectiveIncompressible(mesh, dict, adjointSolverName, primalSolverName),
|
||||
initVol_(Zero),
|
||||
objectivePatches_
|
||||
(
|
||||
mesh_.boundaryMesh().patchSet
|
||||
(
|
||||
wordReList(dict.get<wordRes>("patches"))
|
||||
)
|
||||
)
|
||||
{
|
||||
// Read target volume if present. Else use the current one as a target
|
||||
if (dict.found("initialVolume"))
|
||||
{
|
||||
initVol_ = dict.get<scalar>("initialVolume");
|
||||
}
|
||||
else
|
||||
{
|
||||
const scalar oneThird(1.0/3.0);
|
||||
forAllConstIters(objectivePatches_, iter)
|
||||
{
|
||||
label patchI = iter.key();
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
initVol_ -= oneThird*gSum(patch.Sf() & patch.Cf());
|
||||
}
|
||||
}
|
||||
// Allocate boundary field pointers
|
||||
bdxdbDirectMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
|
||||
bdSdbMultPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
scalar objectivePartialVolume::J()
|
||||
{
|
||||
J_ = Zero;
|
||||
const scalar oneThird(1.0/3.0);
|
||||
forAllConstIters(objectivePatches_, iter)
|
||||
{
|
||||
label patchI = iter.key();
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
J_ -= oneThird*gSum(patch.Sf() & patch.Cf());
|
||||
}
|
||||
J_ -= initVol_;
|
||||
J_ /= initVol_;
|
||||
return J_;
|
||||
}
|
||||
|
||||
|
||||
void objectivePartialVolume::update_dxdbDirectMultiplier()
|
||||
{
|
||||
const scalar oneThird(1.0/3.0);
|
||||
forAllConstIter(labelHashSet, objectivePatches_, iter)
|
||||
{
|
||||
label pI = iter.key();
|
||||
const fvPatch& patch = mesh_.boundary()[pI];
|
||||
tmp<vectorField> tnf = patch.nf();
|
||||
const vectorField& nf = tnf();
|
||||
bdxdbDirectMultPtr_()[pI] = -oneThird*nf/initVol_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void objectivePartialVolume::update_dSdbMultiplier()
|
||||
{
|
||||
const scalar oneThird(1.0/3.0);
|
||||
forAllConstIter(labelHashSet, objectivePatches_, iter)
|
||||
{
|
||||
label pI = iter.key();
|
||||
const fvPatch& patch = mesh_.boundary()[pI];
|
||||
bdSdbMultPtr_()[pI] = -oneThird*patch.Cf()/initVol_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void objectivePartialVolume::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() + 6;
|
||||
if (objFunctionFilePtr_.empty())
|
||||
{
|
||||
setObjectiveFilePtr();
|
||||
objFunctionFilePtr_() << setw(4) << "#" << " ";
|
||||
objFunctionFilePtr_() << setw(width) << "(V - VInit)/VInit" << " ";
|
||||
objFunctionFilePtr_() << setw(width) << "VInit" << endl;
|
||||
}
|
||||
|
||||
objFunctionFilePtr_() << setw(4) << mesh_.time().value() << " ";
|
||||
objFunctionFilePtr_() << setw(width) << J_ << " ";
|
||||
objFunctionFilePtr_() << setw(width) << initVol_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace objectives
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,115 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::objectivePartialVolume
|
||||
|
||||
Description
|
||||
|
||||
SourceFiles
|
||||
objectivePartialVolume.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef objectivePartialVolume_H
|
||||
#define objectivePartialVolume_H
|
||||
|
||||
#include "objectiveIncompressible.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace objectives
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class objectivePartialVolume Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class objectivePartialVolume
|
||||
:
|
||||
public objectiveIncompressible
|
||||
{
|
||||
// Private data
|
||||
|
||||
scalar initVol_;
|
||||
labelHashSet objectivePatches_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("partialVolume");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- from components
|
||||
objectivePartialVolume
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName,
|
||||
const word& primalSolverName
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~objectivePartialVolume() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the objective function value
|
||||
scalar J();
|
||||
|
||||
//- Update d (x) / db multiplier. Surface and volume-based sensitivity
|
||||
//- term
|
||||
void update_dxdbDirectMultiplier();
|
||||
|
||||
//- Update d (normal dS) / db multiplier. Surface and volume-based
|
||||
//- sensitivity term
|
||||
void update_dSdbMultiplier();
|
||||
|
||||
//- Write objective function history
|
||||
void write() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace objectivePartialVolume
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -112,11 +112,15 @@ objective::objective
|
||||
primalSolverName_(primalSolverName),
|
||||
objectiveName_(dict.dictName()),
|
||||
computeMeanFields_(false), // is reset in derived classes
|
||||
nullified_(false),
|
||||
|
||||
J_(Zero),
|
||||
JMean_(Zero),
|
||||
weight_(Zero),
|
||||
|
||||
integrationStartTimePtr_(nullptr),
|
||||
integrationEndTimePtr_(nullptr),
|
||||
|
||||
// Initialize pointers to nullptr.
|
||||
// Not all of them are required for each objective function.
|
||||
// Each child should allocate whatever is needed.
|
||||
@ -138,6 +142,37 @@ objective::objective
|
||||
meanValueFilePtr_(nullptr)
|
||||
{
|
||||
makeFolder();
|
||||
// Read integration start and end times, if present.
|
||||
// For unsteady runs only
|
||||
if (dict.found("integrationStartTime"))
|
||||
{
|
||||
integrationStartTimePtr_.reset
|
||||
(
|
||||
new scalar(dict.get<scalar>("integrationStartTime"))
|
||||
);
|
||||
}
|
||||
if (dict.found("integrationEndTime"))
|
||||
{
|
||||
integrationEndTimePtr_.reset
|
||||
(
|
||||
new scalar(dict.get<scalar>("integrationEndTime"))
|
||||
);
|
||||
}
|
||||
|
||||
// Read JMean from dictionary, if present
|
||||
IOobject headObjectiveIODict
|
||||
(
|
||||
"objectiveDict",
|
||||
mesh_.time().timeName(),
|
||||
"uniform",
|
||||
mesh_,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
if (headObjectiveIODict.typeHeaderOk<IOdictionary>(false))
|
||||
{
|
||||
JMean_ = IOdictionary(headObjectiveIODict).get<scalar>("JMean");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +222,21 @@ bool objective::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
scalar objective::JCycle() const
|
||||
{
|
||||
scalar J(J_);
|
||||
if
|
||||
(
|
||||
computeMeanFields_
|
||||
|| (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||
)
|
||||
{
|
||||
J = JMean_;
|
||||
}
|
||||
return J;
|
||||
}
|
||||
|
||||
|
||||
void objective::updateNormalizationFactor()
|
||||
{
|
||||
// Does nothing in base
|
||||
@ -210,12 +260,71 @@ void objective::accumulateJMean(solverControl& solverControl)
|
||||
}
|
||||
|
||||
|
||||
void objective::accumulateJMean()
|
||||
{
|
||||
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||
{
|
||||
const scalar time = mesh_.time().value();
|
||||
if (isWithinIntegrationTime())
|
||||
{
|
||||
const scalar dt = mesh_.time().deltaT().value();
|
||||
const scalar elapsedTime = time - integrationStartTimePtr_();
|
||||
const scalar denom = elapsedTime + dt;
|
||||
JMean_ = (JMean_*elapsedTime + J_*dt)/denom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unallocated integration start or end time"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scalar objective::weight() const
|
||||
{
|
||||
return weight_;
|
||||
}
|
||||
|
||||
|
||||
bool objective::isWithinIntegrationTime() const
|
||||
{
|
||||
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||
{
|
||||
const scalar time = mesh_.time().value();
|
||||
return
|
||||
(
|
||||
time >= integrationStartTimePtr_()
|
||||
&& time <= integrationEndTimePtr_()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unallocated integration start or end time"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void objective::incrementIntegrationTimes(const scalar timeSpan)
|
||||
{
|
||||
if (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||
{
|
||||
integrationStartTimePtr_() += timeSpan;
|
||||
integrationEndTimePtr_() += timeSpan;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unallocated integration start or end time"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const volScalarField& objective::dJdb()
|
||||
{
|
||||
if (dJdbPtr_.empty())
|
||||
@ -426,6 +535,61 @@ const volTensorField& objective::gradDxDbMultiplier()
|
||||
}
|
||||
|
||||
|
||||
void objective::nullify()
|
||||
{
|
||||
if (!nullified_)
|
||||
{
|
||||
if (hasdJdb())
|
||||
{
|
||||
dJdbPtr_() == dimensionedScalar(dJdbPtr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasBoundarydJdb())
|
||||
{
|
||||
bdJdbPtr_() == vector::zero;
|
||||
}
|
||||
if (hasdSdbMult())
|
||||
{
|
||||
bdSdbMultPtr_() == vector::zero;
|
||||
}
|
||||
if (hasdndbMult())
|
||||
{
|
||||
bdndbMultPtr_() == vector::zero;
|
||||
}
|
||||
if (hasdxdbMult())
|
||||
{
|
||||
bdxdbMultPtr_() == vector::zero;
|
||||
}
|
||||
if (hasdxdbDirectMult())
|
||||
{
|
||||
bdxdbDirectMultPtr_() == vector::zero;
|
||||
}
|
||||
if (hasBoundaryEdgeContribution())
|
||||
{
|
||||
for (Field<vectorField>& field : bEdgeContribution_())
|
||||
{
|
||||
field = vector::zero;
|
||||
}
|
||||
}
|
||||
if (hasBoundarydJdStress())
|
||||
{
|
||||
bdJdStressPtr_() == tensor::zero;
|
||||
}
|
||||
if (hasDivDxDbMult())
|
||||
{
|
||||
divDxDbMultPtr_() ==
|
||||
dimensionedScalar(divDxDbMultPtr_().dimensions(), Zero);
|
||||
}
|
||||
if (hasGradDxDbMult())
|
||||
{
|
||||
gradDxDbMultPtr_() ==
|
||||
dimensionedTensor(gradDxDbMultPtr_().dimensions(), Zero);
|
||||
}
|
||||
|
||||
nullified_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void objective::write() const
|
||||
{
|
||||
if (Pstream::master())
|
||||
@ -465,7 +629,12 @@ void objective::writeMeanValue() const
|
||||
if (Pstream::master())
|
||||
{
|
||||
// Write mean value if necessary
|
||||
if (computeMeanFields_)
|
||||
// Covers both steady and unsteady runs
|
||||
if
|
||||
(
|
||||
computeMeanFields_
|
||||
|| (hasIntegrationStartTime() && hasIntegrationEndTime())
|
||||
)
|
||||
{
|
||||
// File is opened only upon invocation of the write function
|
||||
// in order to avoid various instantiations of the same objective
|
||||
@ -479,6 +648,22 @@ void objective::writeMeanValue() const
|
||||
<< mesh_.time().value() << tab << JMean_ << endl;
|
||||
}
|
||||
}
|
||||
// Write mean value under time/uniform, to allow for lineSearch to work
|
||||
// appropriately in continuation runs, when field averaging is used
|
||||
IOdictionary objectiveDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"objectiveDict",
|
||||
mesh_.time().timeName(),
|
||||
"uniform",
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
objectiveDict.add<scalar>("JMean", JMean_);
|
||||
objectiveDict.regIOobject::write();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -69,12 +69,17 @@ protected:
|
||||
const word primalSolverName_;
|
||||
const word objectiveName_;
|
||||
bool computeMeanFields_;
|
||||
bool nullified_;
|
||||
|
||||
// Objective function value and weight
|
||||
scalar J_;
|
||||
scalar JMean_; //average value
|
||||
scalar weight_;
|
||||
|
||||
// Objective integration start and end times (for unsteady flows)
|
||||
autoPtr<scalar> integrationStartTimePtr_;
|
||||
autoPtr<scalar> integrationEndTimePtr_;
|
||||
|
||||
// Contribution to field sensitivity derivatives
|
||||
// Topology optimisation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -219,15 +224,30 @@ public:
|
||||
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Return the objective function value
|
||||
//- Return the instantaneous objective function value
|
||||
virtual scalar J() = 0;
|
||||
|
||||
//- Return the mean objective function value, if it exists,
|
||||
//- otherwise the mean one
|
||||
scalar JCycle() const;
|
||||
|
||||
//- Accumulate contribution for the mean objective value
|
||||
// For steady-state runs
|
||||
void accumulateJMean(solverControl& solverControl);
|
||||
|
||||
//- Accumulate contribution for the mean objective value
|
||||
// For unsteady runs
|
||||
void accumulateJMean();
|
||||
|
||||
//- Return the objective function weight
|
||||
scalar weight() const;
|
||||
|
||||
//- Check whether this is an objective integration time
|
||||
bool isWithinIntegrationTime() const;
|
||||
|
||||
//- Increment integration times
|
||||
void incrementIntegrationTimes(const scalar timeSpan);
|
||||
|
||||
//- Contribution to field sensitivities
|
||||
const volScalarField& dJdb();
|
||||
|
||||
@ -286,6 +306,9 @@ public:
|
||||
//- Update objective function derivatives
|
||||
virtual void update() = 0;
|
||||
|
||||
//- Nullify adjoint contributions
|
||||
virtual void nullify();
|
||||
|
||||
//- Update normalization factors, for objectives in
|
||||
//- which the factor is not known a priori
|
||||
virtual void updateNormalizationFactor();
|
||||
@ -338,16 +361,20 @@ public:
|
||||
|
||||
// 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();
|
||||
inline bool hasdJdb() const;
|
||||
inline bool hasBoundarydJdb() const;
|
||||
inline bool hasdSdbMult() const;
|
||||
inline bool hasdndbMult() const;
|
||||
inline bool hasdxdbMult() const;
|
||||
inline bool hasdxdbDirectMult() const;
|
||||
inline bool hasBoundaryEdgeContribution() const;
|
||||
inline bool hasBoundarydJdStress() const;
|
||||
inline bool hasDivDxDbMult() const;
|
||||
inline bool hasGradDxDbMult() const;
|
||||
|
||||
// Inline functions for checking whether integration times are set
|
||||
inline bool hasIntegrationStartTime() const;
|
||||
inline bool hasIntegrationEndTime() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -36,64 +36,75 @@ inline const Foam::word& Foam::objective::objectiveName() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasdJdb()
|
||||
inline bool Foam::objective::hasdJdb() const
|
||||
{
|
||||
return dJdbPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasBoundarydJdb()
|
||||
inline bool Foam::objective::hasBoundarydJdb() const
|
||||
{
|
||||
return bdJdbPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasdSdbMult()
|
||||
inline bool Foam::objective::hasdSdbMult() const
|
||||
{
|
||||
return bdSdbMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasdndbMult()
|
||||
inline bool Foam::objective::hasdndbMult() const
|
||||
{
|
||||
return bdndbMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasdxdbMult()
|
||||
inline bool Foam::objective::hasdxdbMult() const
|
||||
{
|
||||
return bdxdbMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasdxdbDirectMult()
|
||||
inline bool Foam::objective::hasdxdbDirectMult() const
|
||||
{
|
||||
return bdxdbDirectMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasBoundaryEdgeContribution()
|
||||
inline bool Foam::objective::hasBoundaryEdgeContribution() const
|
||||
{
|
||||
return bEdgeContribution_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasDivDxDbMult()
|
||||
inline bool Foam::objective::hasDivDxDbMult() const
|
||||
{
|
||||
return divDxDbMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasGradDxDbMult()
|
||||
inline bool Foam::objective::hasGradDxDbMult() const
|
||||
{
|
||||
return gradDxDbMultPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasBoundarydJdStress()
|
||||
inline bool Foam::objective::hasBoundarydJdStress() const
|
||||
{
|
||||
return bdJdStressPtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasIntegrationStartTime() const
|
||||
{
|
||||
return integrationStartTimePtr_.valid();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::objective::hasIntegrationEndTime() const
|
||||
{
|
||||
return integrationEndTimePtr_.valid();
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -0,0 +1,214 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "FIBaseIncompressible.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(FIBase, 0);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void FIBase::read()
|
||||
{
|
||||
includeDistance_ =
|
||||
dict_.lookupOrDefault<bool>
|
||||
(
|
||||
"includeDistance",
|
||||
adjointVars_.adjointTurbulence().ref().includeDistance()
|
||||
);
|
||||
|
||||
// Allocate distance solver if needed
|
||||
if (includeDistance_ && eikonalSolver_.empty())
|
||||
{
|
||||
eikonalSolver_.reset
|
||||
(
|
||||
new adjointEikonalSolver
|
||||
(
|
||||
mesh_,
|
||||
dict_,
|
||||
primalVars_.RASModelVariables(),
|
||||
adjointVars_.adjointTurbulence(),
|
||||
sensitivityPatchIDs_
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
FIBase::FIBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
adjointSensitivity
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
shapeSensitivitiesBase(mesh, dict),
|
||||
gradDxDbMult_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"gradDxDbMult",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
dimensionedTensor(sqr(dimLength)/pow3(dimTime), Zero)
|
||||
),
|
||||
divDxDbMult_(mesh_.nCells(), Zero),
|
||||
optionsDxDbMult_(mesh_.nCells(), vector::zero),
|
||||
dSfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dnfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dxdbDirectMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
|
||||
includeDistance_(false),
|
||||
eikonalSolver_(nullptr)
|
||||
{
|
||||
read();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool FIBase::readDict(const dictionary& dict)
|
||||
{
|
||||
if (sensitivity::readDict(dict))
|
||||
{
|
||||
if (eikonalSolver_.valid())
|
||||
{
|
||||
eikonalSolver_().readDict(dict);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void FIBase::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Accumulate multiplier of grad(dxdb)
|
||||
gradDxDbMult_ += computeGradDxDbMultiplier()().T()*dt;
|
||||
|
||||
// Accumulate multiplier of div(dxdb)
|
||||
PtrList<objective>& functions(objectiveManager_.getObjectiveFunctions());
|
||||
for (objective& func : functions)
|
||||
{
|
||||
divDxDbMult_ +=
|
||||
func.weight()*func.divDxDbMultiplier().primitiveField()*dt;
|
||||
}
|
||||
|
||||
// Terms from fvOptions
|
||||
for (fv::optionAdjoint& optionAdj : fvOptionsAdjoint_)
|
||||
{
|
||||
optionsDxDbMult_ +=
|
||||
optionAdj.dxdbMult(adjointVars_)().primitiveField()*dt;
|
||||
}
|
||||
|
||||
// Accumulate source for the adjoint to the eikonal equation
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->accumulateIntegrand(dt);
|
||||
}
|
||||
|
||||
// Accumulate direct sensitivities
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const scalarField magSfDt(mesh_.boundary()[patchI].magSf()*dt);
|
||||
for (objective& func : functions)
|
||||
{
|
||||
const scalar wei = func.weight();
|
||||
dSfdbMult_()[patchI] += wei*func.dSdbMultiplier(patchI)*dt;
|
||||
dnfdbMult_()[patchI] += wei*func.dndbMultiplier(patchI)*magSfDt;
|
||||
dxdbDirectMult_()[patchI] +=
|
||||
wei*func.dxdbDirectMultiplier(patchI)*magSfDt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FIBase::clearSensitivities()
|
||||
{
|
||||
gradDxDbMult_ = dimensionedTensor(gradDxDbMult_.dimensions(), Zero);
|
||||
divDxDbMult_ = Zero;
|
||||
optionsDxDbMult_ = vector::zero;
|
||||
dSfdbMult_() = vector::zero;
|
||||
dnfdbMult_() = vector::zero;
|
||||
dxdbDirectMult_() = vector::zero;
|
||||
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->reset();
|
||||
}
|
||||
|
||||
adjointSensitivity::clearSensitivities();
|
||||
shapeSensitivitiesBase::clear();
|
||||
}
|
||||
|
||||
|
||||
void FIBase::write(const word& baseName)
|
||||
{
|
||||
adjointSensitivity::write(baseName);
|
||||
shapeSensitivitiesBase::write();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,158 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::FIBase
|
||||
|
||||
Description
|
||||
Base class for Field Integral-based sensitivity derivatives
|
||||
|
||||
SourceFiles
|
||||
FIBase.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FIBaseIncompressible_H
|
||||
#define FIBaseIncompressible_H
|
||||
|
||||
#include "adjointSensitivityIncompressible.H"
|
||||
#include "shapeSensitivitiesBase.H"
|
||||
#include "adjointEikonalSolverIncompressible.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class FIBase Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class FIBase
|
||||
:
|
||||
public adjointSensitivity,
|
||||
public shapeSensitivitiesBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- grad(dx/db) multiplier
|
||||
volTensorField gradDxDbMult_;
|
||||
|
||||
//- div(dx/db) multiplier
|
||||
scalarField divDxDbMult_;
|
||||
|
||||
//- dx/db multiplier coming from fvOptions
|
||||
vectorField optionsDxDbMult_;
|
||||
|
||||
//- Fields related to direct sensitivities
|
||||
autoPtr<boundaryVectorField> dSfdbMult_;
|
||||
autoPtr<boundaryVectorField> dnfdbMult_;
|
||||
autoPtr<boundaryVectorField> dxdbDirectMult_;
|
||||
|
||||
//- Include distance variation in sens computation
|
||||
bool includeDistance_;
|
||||
|
||||
//- Adjoint eikonal equation solver
|
||||
autoPtr<adjointEikonalSolver> eikonalSolver_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Read options and update solver pointers if necessary
|
||||
void read();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
FIBase(const FIBase&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const FIBase&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplinesFI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
FIBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~FIBase() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Accumulate sensitivity integrands
|
||||
virtual void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities() = 0;
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivity fields
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "SIBaseIncompressible.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(SIBase, 0);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void SIBase::read()
|
||||
{
|
||||
surfaceSensitivity_.read();
|
||||
includeObjective_ =
|
||||
dict().lookupOrDefault<bool>("includeObjectiveContribution", true);
|
||||
|
||||
// If includeObjective is set to true both here and in the surface
|
||||
// sensitivities, set the one in the latter to false to avoid double
|
||||
// contributions
|
||||
bool surfSensIncludeObjective(surfaceSensitivity_.getIncludeObjective());
|
||||
if (includeObjective_ && surfSensIncludeObjective)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "includeObjectiveContribution set to true in both "
|
||||
<< "surfaceSensitivities and the parameterization options" << nl
|
||||
<< "This will lead to double contributions " << nl
|
||||
<< "Disabling the former"
|
||||
<< endl;
|
||||
surfaceSensitivity_.setIncludeObjective(false);
|
||||
}
|
||||
|
||||
// Make sure surface area is included in the sensitivity map
|
||||
surfaceSensitivity_.setIncludeSurfaceArea(true);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
SIBase::SIBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
adjointSensitivity
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
shapeSensitivitiesBase(mesh, dict),
|
||||
surfaceSensitivity_
|
||||
(
|
||||
mesh,
|
||||
// Ideally, subOrEmptyDict would be used.
|
||||
// Since we need a recursive search in shapeSensitivitiesBase though
|
||||
// and the dict returned by subOrEmptyDict (if found)
|
||||
// does not know its parent, optionalSubDict is used
|
||||
dict.optionalSubDict("surfaceSensitivities"),
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
dSfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dnfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dxdbDirectMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
includeObjective_(true)
|
||||
{
|
||||
read();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool SIBase::readDict(const dictionary& dict)
|
||||
{
|
||||
if (sensitivity::readDict(dict))
|
||||
{
|
||||
surfaceSensitivity_.readDict
|
||||
(
|
||||
dict.optionalSubDict("surfaceSensitivities")
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SIBase::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Accumulate multiplier of dxFace/db
|
||||
surfaceSensitivity_.accumulateIntegrand(dt);
|
||||
|
||||
// Accumulate direct sensitivities
|
||||
if (includeObjective_)
|
||||
{
|
||||
PtrList<objective>& functions
|
||||
(
|
||||
objectiveManager_.getObjectiveFunctions()
|
||||
);
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const scalarField magSfDt(mesh_.boundary()[patchI].magSf()*dt);
|
||||
for (objective& func : functions)
|
||||
{
|
||||
const scalar wei = func.weight();
|
||||
dSfdbMult_()[patchI] += wei*func.dSdbMultiplier(patchI)*dt;
|
||||
dnfdbMult_()[patchI] += wei*func.dndbMultiplier(patchI)*magSfDt;
|
||||
dxdbDirectMult_()[patchI] +=
|
||||
wei*func.dxdbDirectMultiplier(patchI)*magSfDt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SIBase::clearSensitivities()
|
||||
{
|
||||
surfaceSensitivity_.clearSensitivities();
|
||||
dSfdbMult_() = vector::zero;
|
||||
dnfdbMult_() = vector::zero;
|
||||
dxdbDirectMult_() = vector::zero;
|
||||
|
||||
adjointSensitivity::clearSensitivities();
|
||||
shapeSensitivitiesBase::clear();
|
||||
}
|
||||
|
||||
|
||||
void SIBase::write(const word& baseName)
|
||||
{
|
||||
adjointSensitivity::write(baseName);
|
||||
shapeSensitivitiesBase::write();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,148 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::SIBase
|
||||
|
||||
Description
|
||||
Base class for Surface Integral-based sensitivity derivatives
|
||||
|
||||
SourceFiles
|
||||
SIBase.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef SIBaseIncompressible_H
|
||||
#define SIBaseIncompressible_H
|
||||
|
||||
#include "adjointSensitivityIncompressible.H"
|
||||
#include "shapeSensitivitiesBase.H"
|
||||
#include "sensitivitySurfaceIncompressible.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class SIBase Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class SIBase
|
||||
:
|
||||
public adjointSensitivity,
|
||||
public shapeSensitivitiesBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Surface sensitivities
|
||||
sensitivitySurface surfaceSensitivity_;
|
||||
|
||||
//- Fields related to direct sensitivities
|
||||
autoPtr<boundaryVectorField> dSfdbMult_;
|
||||
autoPtr<boundaryVectorField> dnfdbMult_;
|
||||
autoPtr<boundaryVectorField> dxdbDirectMult_;
|
||||
|
||||
bool includeObjective_;
|
||||
|
||||
|
||||
// Protected Member Fuctions
|
||||
|
||||
//- Read options from dict
|
||||
void read();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
SIBase(const SIBase&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const SIBase&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplinesFI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
SIBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~SIBase() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Accumulate sensitivity integrands
|
||||
virtual void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities() = 0;
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivity fields.
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -115,7 +115,7 @@ adjointEikonalSolver::adjointEikonalSolver
|
||||
const dictionary& dict,
|
||||
const autoPtr<incompressible::RASModelVariables>& RASModelVars,
|
||||
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>& adjointTurbulence,
|
||||
const labelList& sensitivityPatchIDs
|
||||
const labelHashSet& sensitivityPatchIDs
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
@ -141,6 +141,19 @@ adjointEikonalSolver::adjointEikonalSolver
|
||||
dimensionedScalar(sqr(dimLength)/pow3(dimTime), Zero),
|
||||
patchTypes()
|
||||
),
|
||||
source_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"sourceEikonal",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
dimensionedScalar(dimLength/pow3(dimTime), Zero)
|
||||
),
|
||||
distanceSensPtr_(createZeroBoundaryPtr<vector>(mesh_))
|
||||
{
|
||||
read();
|
||||
@ -157,6 +170,13 @@ bool adjointEikonalSolver::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
void adjointEikonalSolver::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Accumulate integrand from the current time step
|
||||
source_ += adjointTurbulence_->distanceSensitivities()*dt;
|
||||
}
|
||||
|
||||
|
||||
void adjointEikonalSolver::solve()
|
||||
{
|
||||
read();
|
||||
@ -164,11 +184,6 @@ void adjointEikonalSolver::solve()
|
||||
// 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();
|
||||
@ -185,7 +200,7 @@ void adjointEikonalSolver::solve()
|
||||
2*fvm::div(-yPhi, da_)
|
||||
+ fvm::SuSp(-epsilon_*fvc::laplacian(d), da_)
|
||||
- epsilon_*fvm::laplacian(d, da_)
|
||||
+ source
|
||||
+ source_
|
||||
);
|
||||
|
||||
daEqn.relax();
|
||||
@ -208,6 +223,13 @@ void adjointEikonalSolver::solve()
|
||||
}
|
||||
|
||||
|
||||
void adjointEikonalSolver::reset()
|
||||
{
|
||||
source_ == dimensionedScalar(source_.dimensions(), Zero);
|
||||
distanceSensPtr_() = vector::zero;
|
||||
}
|
||||
|
||||
|
||||
boundaryVectorField& adjointEikonalSolver::distanceSensitivities()
|
||||
{
|
||||
Info<< "Calculating distance sensitivities " << endl;
|
||||
|
||||
@ -170,7 +170,7 @@ protected:
|
||||
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>&
|
||||
adjointTurbulence_;
|
||||
|
||||
const labelList& sensitivityPatchIDs_;
|
||||
const labelHashSet& sensitivityPatchIDs_;
|
||||
|
||||
label nEikonalIters_;
|
||||
|
||||
@ -182,6 +182,8 @@ protected:
|
||||
|
||||
volScalarField da_;
|
||||
|
||||
volScalarField source_;
|
||||
|
||||
//- Wall face sens w.r.t. (x,y.z)
|
||||
autoPtr<boundaryVectorField> distanceSensPtr_;
|
||||
|
||||
@ -215,7 +217,7 @@ public:
|
||||
const autoPtr<incompressible::RASModelVariables>& RASModelVars,
|
||||
autoPtr<Foam::incompressibleAdjoint::adjointRASModel>&
|
||||
adjointTurbulence,
|
||||
const labelList& sensitivityPatchIDs
|
||||
const labelHashSet& sensitivityPatchIDs
|
||||
);
|
||||
|
||||
// Destructor
|
||||
@ -228,9 +230,15 @@ public:
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Accumulate source term
|
||||
void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Calculate the adjoint distance field
|
||||
void solve();
|
||||
|
||||
//- Reset source term
|
||||
void reset();
|
||||
|
||||
//- Return the sensitivity term depending on da
|
||||
boundaryVectorField& distanceSensitivities();
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ adjointMeshMovementSolver::adjointMeshMovementSolver
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
Foam::incompressible::adjointSensitivity& adjointSensitivity,
|
||||
const labelList& sensitivityPatchIDs,
|
||||
const labelHashSet& sensitivityPatchIDs,
|
||||
const autoPtr<adjointEikonalSolver>& adjointEikonalSolverPtr
|
||||
)
|
||||
:
|
||||
@ -77,6 +77,19 @@ adjointMeshMovementSolver::adjointMeshMovementSolver
|
||||
dimensionSet(pow3(dimLength/dimTime))
|
||||
)
|
||||
),
|
||||
source_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"sourceAdjointMeshMovement",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
dimensionedVector(dimLength/pow3(dimTime), Zero)
|
||||
),
|
||||
meshMovementSensPtr_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
adjointEikonalSolverPtr_(adjointEikonalSolverPtr)
|
||||
{
|
||||
@ -94,24 +107,28 @@ bool adjointMeshMovementSolver::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
void adjointMeshMovementSolver::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Accumulate integrand from the current time step
|
||||
source_ += adjointSensitivity_.adjointMeshMovementSource()*dt;
|
||||
|
||||
// Part of the source depending on the adjoint distance can be added only
|
||||
// after solving the adjoint eikonal equation. Added in solve()
|
||||
}
|
||||
|
||||
|
||||
void adjointMeshMovementSolver::solve()
|
||||
{
|
||||
read();
|
||||
|
||||
// Compute source term
|
||||
tmp<volVectorField> tsource
|
||||
(
|
||||
adjointSensitivity_.adjointMeshMovementSource()
|
||||
);
|
||||
volVectorField& source = tsource.ref();
|
||||
|
||||
// Add source from the adjoint eikonal equation
|
||||
if (adjointEikonalSolverPtr_.valid())
|
||||
{
|
||||
source -=
|
||||
source_ -=
|
||||
fvc::div(adjointEikonalSolverPtr_().getFISensitivityTerm()().T());
|
||||
}
|
||||
|
||||
// Iterate the adjoint to the eikonal equation
|
||||
// Iterate the adjoint to the mesh movement equation
|
||||
for (label iter = 0; iter < nLaplaceIters_; iter++)
|
||||
{
|
||||
Info<< "Adjoint Mesh Movement Iteration: " << iter << endl;
|
||||
@ -119,7 +136,7 @@ void adjointMeshMovementSolver::solve()
|
||||
fvVectorMatrix maEqn
|
||||
(
|
||||
fvm::laplacian(ma_)
|
||||
+ source
|
||||
+ source_
|
||||
);
|
||||
|
||||
maEqn.boundaryManipulate(ma_.boundaryFieldRef());
|
||||
@ -145,6 +162,13 @@ void adjointMeshMovementSolver::solve()
|
||||
}
|
||||
|
||||
|
||||
void adjointMeshMovementSolver::reset()
|
||||
{
|
||||
source_ == dimensionedVector(source_.dimensions(), Zero);
|
||||
meshMovementSensPtr_() = vector::zero;
|
||||
}
|
||||
|
||||
|
||||
boundaryVectorField& adjointMeshMovementSolver::meshMovementSensitivities()
|
||||
{
|
||||
Info<< "Calculating mesh movement sensitivities " << endl;
|
||||
|
||||
@ -75,10 +75,11 @@ protected:
|
||||
const fvMesh& mesh_;
|
||||
dictionary dict_;
|
||||
Foam::incompressible::adjointSensitivity& adjointSensitivity_;
|
||||
const labelList& sensitivityPatchIDs_;
|
||||
const labelHashSet& sensitivityPatchIDs_;
|
||||
label nLaplaceIters_;
|
||||
scalar tolerance_;
|
||||
volVectorField ma_;
|
||||
volVectorField source_;
|
||||
|
||||
//- Wall face sens w.r.t.(x, y.z) //wall face sens w.r.t. (x,y.z)
|
||||
autoPtr<boundaryVectorField> meshMovementSensPtr_;
|
||||
@ -113,7 +114,7 @@ public:
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
Foam::incompressible::adjointSensitivity& adjointSensitivity,
|
||||
const labelList& sensitivityPatchIDs,
|
||||
const labelHashSet& sensitivityPatchIDs,
|
||||
const autoPtr<adjointEikonalSolver>& adjointEikonalSolverPtr
|
||||
);
|
||||
|
||||
@ -126,9 +127,15 @@ public:
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Accumulate source term
|
||||
void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Calculate the adjoint distance field
|
||||
void solve();
|
||||
|
||||
//- Reset source term
|
||||
void reset();
|
||||
|
||||
//- Return the sensitivity term depending on da
|
||||
boundaryVectorField& meshMovementSensitivities();
|
||||
|
||||
|
||||
@ -58,7 +58,8 @@ adjointSensitivity::adjointSensitivity
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
sensitivity(mesh, dict, objectiveManager.adjointSolverName()),
|
||||
sensitivity(mesh, dict),
|
||||
derivatives_(0),
|
||||
primalVars_(primalVars),
|
||||
adjointVars_(adjointVars),
|
||||
objectiveManager_(objectiveManager),
|
||||
@ -112,6 +113,24 @@ autoPtr<adjointSensitivity> adjointSensitivity::New
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
const scalarField& adjointSensitivity::calculateSensitivities()
|
||||
{
|
||||
assembleSensitivities();
|
||||
write(type());
|
||||
return derivatives_;
|
||||
}
|
||||
|
||||
|
||||
void adjointSensitivity::clearSensitivities()
|
||||
{
|
||||
derivatives_ = scalar(0);
|
||||
if (fieldSensPtr_.valid())
|
||||
{
|
||||
fieldSensPtr_().primitiveFieldRef() = scalar(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void adjointSensitivity::write(const word& baseName)
|
||||
{
|
||||
sensitivity::write(baseName);
|
||||
@ -276,29 +295,6 @@ tmp<volTensorField> adjointSensitivity::computeGradDxDbMultiplier()
|
||||
// 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);
|
||||
@ -331,6 +327,12 @@ tmp<volVectorField> adjointSensitivity::adjointMeshMovementSource()
|
||||
|
||||
source -= fvc::div(gradDxDbMult.T());
|
||||
|
||||
// Terms from fvOptions
|
||||
forAll(fvOptionsAdjoint_, oI)
|
||||
{
|
||||
source += fvOptionsAdjoint_[oI].dxdbMult(adjointVars_);
|
||||
}
|
||||
|
||||
return (tadjointMeshMovementSource);
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +83,7 @@ protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
scalarField derivatives_;
|
||||
incompressibleVars& primalVars_;
|
||||
incompressibleAdjointVars& adjointVars_;
|
||||
objectiveManager& objectiveManager_;
|
||||
@ -165,9 +166,20 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Accumulate sensitivity integrands
|
||||
// Corresponds to the flow and adjoint part of the sensitivities
|
||||
virtual void accumulateIntegrand(const scalar dt) = 0;
|
||||
|
||||
//- Assemble sensitivities
|
||||
// Adds the geometric part of the sensitivities
|
||||
virtual void assembleSensitivities() = 0;
|
||||
|
||||
//- Calculates and returns sensitivity fields.
|
||||
// Used with optimisation libraries
|
||||
virtual const scalarField& calculateSensitivities() = 0;
|
||||
virtual const scalarField& calculateSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivity fields.
|
||||
// If valid, copies boundaryFields to volFields and writes them.
|
||||
|
||||
@ -0,0 +1,245 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "sensitivityBezierIncompressible.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IOmanip.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(sensitivityBezier, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
adjointSensitivity,
|
||||
sensitivityBezier,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivityBezier::sensitivityBezier
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
SIBase
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
//Bezier_(mesh, dict), // AJH Read locally?
|
||||
Bezier_(mesh, mesh.lookupObject<IOdictionary>("optimisationDict")),
|
||||
sens_(Bezier_.nBezier(), vector::zero),
|
||||
flowSens_(Bezier_.nBezier(), vector::zero),
|
||||
dSdbSens_(Bezier_.nBezier(), vector::zero),
|
||||
dndbSens_(Bezier_.nBezier(), vector::zero),
|
||||
dxdbDirectSens_(Bezier_.nBezier(), vector::zero),
|
||||
derivativesFolder_("optimisation"/type() + "Derivatives")
|
||||
{
|
||||
derivatives_ = scalarField(3*Bezier_.nBezier(), Zero);
|
||||
// Create folder to store sensitivities
|
||||
mkDir(derivativesFolder_);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityBezier::assembleSensitivities()
|
||||
{
|
||||
// Assemble the sensitivity map
|
||||
// Solves for the post-processing equations and adds their contribution to
|
||||
// the sensitivity map
|
||||
surfaceSensitivity_.assembleSensitivities();
|
||||
|
||||
forAll(sens_, iCP)
|
||||
{
|
||||
// Face-based summation. More robust since the result is independent of
|
||||
// the number of processors (does not hold for a point-based summation)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
// Interpolate parameterization info to faces
|
||||
tmp<tensorField> tdxidXj = Bezier_.dxdbFace(patchI, iCP);
|
||||
const tensorField& dxidXj = tdxidXj();
|
||||
|
||||
// Patch sensitivity map
|
||||
const vectorField& patchSensMap =
|
||||
surfaceSensitivity_.getWallFaceSensVecBoundary()[patchI];
|
||||
flowSens_[iCP] += gSum(patchSensMap & dxidXj);
|
||||
|
||||
if (includeObjective_)
|
||||
{
|
||||
// Contribution from objective function
|
||||
// term from delta( n dS ) / delta b and
|
||||
// term from delta( n ) / delta b
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
tmp<tensorField> tdSdb
|
||||
(
|
||||
Bezier_.dndbBasedSensitivities(patchI, iCP)
|
||||
);
|
||||
const tensorField& dSdb = tdSdb();
|
||||
dSdbSens_[iCP] += gSum(dSfdbMult_()[patchI] & dSdb);
|
||||
|
||||
tmp<tensorField> tdndb
|
||||
(
|
||||
Bezier_.dndbBasedSensitivities(patchI, iCP, false)
|
||||
);
|
||||
const tensorField& dndb = tdndb();
|
||||
dndbSens_[iCP] += gSum((dnfdbMult_()[patchI] & dndb));
|
||||
|
||||
// Contribution from objective function
|
||||
// term from delta( x ) / delta b
|
||||
// Only for objectives directly including
|
||||
// x, like moments
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
dxdbDirectSens_[iCP] +=
|
||||
gSum((dxdbDirectMult_()[patchI] & dxidXj));
|
||||
}
|
||||
}
|
||||
}
|
||||
sens_ = flowSens_ + dSdbSens_ + dndbSens_ + dxdbDirectSens_;
|
||||
|
||||
// Transform sensitivities to scalarField in order to cooperate with
|
||||
// updateMethod
|
||||
label nBezier = Bezier_.nBezier();
|
||||
forAll(sens_, cpI)
|
||||
{
|
||||
derivatives_[cpI] = sens_[cpI].x();
|
||||
derivatives_[cpI + nBezier] = sens_[cpI].y();
|
||||
derivatives_[cpI + 2*nBezier] = sens_[cpI].z();
|
||||
const boolList& confineXmovement = Bezier_.confineXmovement();
|
||||
const boolList& confineYmovement = Bezier_.confineYmovement();
|
||||
const boolList& confineZmovement = Bezier_.confineZmovement();
|
||||
if (confineXmovement[cpI])
|
||||
{
|
||||
derivatives_[cpI] *= scalar(0);
|
||||
flowSens_[cpI].x() = Zero;
|
||||
dSdbSens_[cpI].x() = Zero;
|
||||
dndbSens_[cpI].x() = Zero;
|
||||
dxdbDirectSens_[cpI].x() = Zero;
|
||||
}
|
||||
if (confineYmovement[cpI])
|
||||
{
|
||||
derivatives_[cpI + nBezier] *= scalar(0);
|
||||
flowSens_[cpI].y() = Zero;
|
||||
dSdbSens_[cpI].y() = Zero;
|
||||
dndbSens_[cpI].y() = Zero;
|
||||
dxdbDirectSens_[cpI].y() = Zero;
|
||||
}
|
||||
if (confineZmovement[cpI])
|
||||
{
|
||||
derivatives_[cpI + 2*nBezier] *= scalar(0);
|
||||
flowSens_[cpI].z() = Zero;
|
||||
dSdbSens_[cpI].z() = Zero;
|
||||
dndbSens_[cpI].z() = Zero;
|
||||
dxdbDirectSens_[cpI].z() = Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivityBezier::clearSensitivities()
|
||||
{
|
||||
sens_ = vector::zero;
|
||||
flowSens_ = vector::zero;
|
||||
dSdbSens_ = vector::zero;
|
||||
dndbSens_ = vector::zero;
|
||||
dxdbDirectSens_ = vector::zero;
|
||||
|
||||
SIBase::clearSensitivities();
|
||||
}
|
||||
|
||||
|
||||
void sensitivityBezier::write(const word& baseName)
|
||||
{
|
||||
Info<< "Writing control point sensitivities to file" << endl;
|
||||
if (Pstream::master())
|
||||
{
|
||||
OFstream derivFile
|
||||
(
|
||||
derivativesFolder_/
|
||||
baseName + adjointVars_.solverName() + mesh_.time().timeName()
|
||||
);
|
||||
unsigned int widthDV = max(int(name(sens_.size()).size()), int(3));
|
||||
unsigned int width = IOstream::defaultPrecision() + 7;
|
||||
derivFile
|
||||
<< setw(widthDV) << "#dv" << " "
|
||||
<< setw(width) << "total" << " "
|
||||
<< setw(width) << "flow" << " "
|
||||
<< setw(width) << "dSdb" << " "
|
||||
<< setw(width) << "dndb" << " "
|
||||
<< setw(width) << "dxdbDirect" << endl;
|
||||
label nDV = derivatives_.size();
|
||||
label nBezier = Bezier_.nBezier();
|
||||
const boolListList& confineMovement = Bezier_.confineMovement();
|
||||
label lastActive(-1);
|
||||
for (label iDV = 0; iDV < nDV; iDV++)
|
||||
{
|
||||
label iCP = iDV%nBezier;
|
||||
label idir = iDV/nBezier;
|
||||
if (!confineMovement[idir][iCP])
|
||||
{
|
||||
if (iDV!=lastActive + 1) derivFile << "\n";
|
||||
lastActive = iDV;
|
||||
derivFile
|
||||
<< setw(widthDV) << iDV << " "
|
||||
<< setw(width) << derivatives_[iDV] << " "
|
||||
<< setw(width) << flowSens_[iCP].component(idir) << " "
|
||||
<< setw(width) << dSdbSens_[iCP].component(idir) << " "
|
||||
<< setw(width) << dndbSens_[iCP].component(idir) << " "
|
||||
<< setw(width) << dxdbDirectSens_[iCP].component(idir)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::sensitivityBezier
|
||||
|
||||
Description
|
||||
Calculation of adjoint based sensitivities for Bezier control points
|
||||
|
||||
SourceFiles
|
||||
sensitivityBezier.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef sensitivityBezierIncompressible_H
|
||||
#define sensitivityBezierIncompressible_H
|
||||
|
||||
#include "primitiveFieldsFwd.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "pointFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "SIBaseIncompressible.H"
|
||||
#include "PrimitivePatchInterpolation.H"
|
||||
#include "PrimitivePatch.H"
|
||||
#include "deltaBoundary.H"
|
||||
#include "Bezier.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class sensitivityBezier Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class sensitivityBezier
|
||||
:
|
||||
public SIBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
Bezier Bezier_;
|
||||
|
||||
vectorField sens_;
|
||||
vectorField flowSens_;
|
||||
vectorField dSdbSens_;
|
||||
vectorField dndbSens_;
|
||||
vectorField dxdbDirectSens_;
|
||||
|
||||
fileName derivativesFolder_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
sensitivityBezier(const sensitivityBezier&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const sensitivityBezier&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("Bezier");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
sensitivityBezier
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~sensitivityBezier() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivities to file
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,366 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "sensitivityBezierFIIncompressible.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IOmanip.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(sensitivityBezierFI, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
adjointSensitivity, sensitivityBezierFI, dictionary
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityBezierFI::read()
|
||||
{
|
||||
// Laplace solution controls
|
||||
const dictionary dxdbDict = dict_.subOrEmptyDict("dxdbSolver");
|
||||
meshMovementIters_ = dxdbDict.lookupOrDefault<label>("iters", 1000);
|
||||
meshMovementResidualLimit_ =
|
||||
dxdbDict.lookupOrDefault<scalar>("tolerance", 1.e-07);
|
||||
|
||||
// Read variables related to the adjoint eikonal solver
|
||||
FIBase::read();
|
||||
}
|
||||
|
||||
|
||||
tmp<volVectorField> sensitivityBezierFI::solveMeshMovementEqn
|
||||
(
|
||||
const label iCP,
|
||||
const label idir
|
||||
)
|
||||
{
|
||||
read();
|
||||
tmp<volVectorField> tm(new volVectorField("m", dxdb_));
|
||||
volVectorField& m = tm.ref();
|
||||
|
||||
// SOLVE FOR DXDB
|
||||
//~~~~~~~~~~~~~~~~
|
||||
// set boundary conditions
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
// interpolate parameterization info to faces
|
||||
tmp<vectorField> tdxidXjFace = Bezier_.dxdbFace(patchI, iCP, idir);
|
||||
const vectorField& dxidXjFace = tdxidXjFace();
|
||||
|
||||
m.boundaryFieldRef()[patchI] == dxidXjFace;
|
||||
}
|
||||
|
||||
// iterate the adjoint to the eikonal equation
|
||||
for (label iter = 0; iter < meshMovementIters_; iter++)
|
||||
{
|
||||
Info<< "Mesh Movement Propagation(direction, CP), ("
|
||||
<< idir << ", " << iCP << "), Iteration : "<< iter << endl;
|
||||
|
||||
fvVectorMatrix mEqn
|
||||
(
|
||||
fvm::laplacian(m)
|
||||
);
|
||||
|
||||
// Scalar residual = max(mEqn.solve().initialResidual());
|
||||
scalar residual = mag(mEqn.solve().initialResidual());
|
||||
|
||||
Info<< "Max dxdb " << gMax(mag(m)()) << endl;
|
||||
|
||||
mesh_.time().printExecutionTime(Info);
|
||||
|
||||
// Check convergence
|
||||
if (residual < meshMovementResidualLimit_)
|
||||
{
|
||||
Info<< "\n***Reached dxdb convergence limit, iteration " << iter
|
||||
<< "***\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tm;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivityBezierFI::sensitivityBezierFI
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
FIBase
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
//Bezier_(mesh, dict), // AJH Read locally?
|
||||
Bezier_(mesh, mesh.lookupObject<IOdictionary>("optimisationDict")),
|
||||
flowSens_(3*Bezier_.nBezier(), Zero),
|
||||
dSdbSens_(3*Bezier_.nBezier(), Zero),
|
||||
dndbSens_(3*Bezier_.nBezier(), Zero),
|
||||
dxdbDirectSens_(3*Bezier_.nBezier(), Zero),
|
||||
dVdbSens_(3*Bezier_.nBezier(), Zero),
|
||||
distanceSens_(3*Bezier_.nBezier(), Zero),
|
||||
optionsSens_(3*Bezier_.nBezier(), Zero),
|
||||
|
||||
derivativesFolder_("optimisation"/type() + "Derivatives"),
|
||||
|
||||
meshMovementIters_(-1),
|
||||
meshMovementResidualLimit_(1.e-7),
|
||||
dxdb_
|
||||
(
|
||||
variablesSet::autoCreateMeshMovementField
|
||||
(
|
||||
mesh,
|
||||
"mTilda",
|
||||
dimensionSet(dimLength)
|
||||
)
|
||||
)
|
||||
{
|
||||
read();
|
||||
|
||||
derivatives_ = scalarField(3*Bezier_.nBezier(), Zero),
|
||||
// Create folder to store sensitivities
|
||||
mkDir(derivativesFolder_);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityBezierFI::assembleSensitivities()
|
||||
{
|
||||
// Adjoint to the eikonal equation
|
||||
autoPtr<volTensorField> distanceSensPtr(nullptr);
|
||||
if (includeDistance_)
|
||||
{
|
||||
// Solver equation
|
||||
eikonalSolver_->solve();
|
||||
|
||||
// Allocate memory and compute grad(dxdb) multiplier
|
||||
distanceSensPtr.reset
|
||||
(
|
||||
createZeroFieldPtr<tensor>
|
||||
(
|
||||
mesh_,
|
||||
"distanceSensPtr",
|
||||
dimensionSet(0, 2, -3, 0, 0, 0, 0)
|
||||
)
|
||||
);
|
||||
distanceSensPtr() = eikonalSolver_->getFISensitivityTerm()().T();
|
||||
}
|
||||
|
||||
const label nBezier = Bezier_.nBezier();
|
||||
const label nDVs = 3*nBezier;
|
||||
for (label iDV = 0; iDV < nDVs; iDV++)
|
||||
{
|
||||
label iCP = iDV%nBezier;
|
||||
label idir = iDV/nBezier;
|
||||
if
|
||||
(
|
||||
(idir == 0 && Bezier_.confineXmovement()[iCP])
|
||||
|| (idir == 1 && Bezier_.confineYmovement()[iCP])
|
||||
|| (idir == 2 && Bezier_.confineZmovement()[iCP])
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flow term
|
||||
// ~~~~~~~~~~~
|
||||
// compute dxdb and its grad
|
||||
tmp<volVectorField> tm = solveMeshMovementEqn(iCP, idir);
|
||||
const volVectorField& m = tm();
|
||||
volTensorField gradDxDb(fvc::grad(m, "grad(dxdb)"));
|
||||
|
||||
flowSens_[iDV] =
|
||||
gSum
|
||||
(
|
||||
(gradDxDb.primitiveField() && gradDxDbMult_.primitiveField())
|
||||
* mesh_.V()
|
||||
);
|
||||
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
// Contribution from objective function
|
||||
// term from delta(n dS)/delta b and
|
||||
// term from delta(n)/delta b
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
tmp<vectorField> tdSdb =
|
||||
Bezier_.dndbBasedSensitivities(patchI, iCP, idir);
|
||||
const vectorField& dSdb = tdSdb();
|
||||
tmp<vectorField> tdndb =
|
||||
Bezier_.dndbBasedSensitivities(patchI, iCP, idir, false);
|
||||
const vectorField& dndb = tdndb();
|
||||
dSdbSens_[iDV] += gSum(dSfdbMult_()[patchI] & dSdb);
|
||||
dndbSens_[iDV] += gSum(dnfdbMult_()[patchI] & dndb);
|
||||
|
||||
// Contribution from objective function
|
||||
// term from delta( x ) / delta b
|
||||
// Only for objectives directly including
|
||||
// x, like moments
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
tmp<vectorField> tdxdbFace =
|
||||
Bezier_.dxdbFace(patchI, iCP, idir);
|
||||
const vectorField& dxdbFace = tdxdbFace();
|
||||
dxdbDirectSens_[iDV] +=
|
||||
gSum(dxdbDirectMult_()[patchI] & dxdbFace);
|
||||
}
|
||||
|
||||
// Contribution from delta (V) / delta b
|
||||
// For objectives defined as volume integrals only
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
dVdbSens_[iDV] =
|
||||
gSum
|
||||
(
|
||||
divDxDbMult_
|
||||
* fvc::div(m)().primitiveField()
|
||||
* mesh_.V()
|
||||
);
|
||||
|
||||
// Distance dependent term
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
if (includeDistance_)
|
||||
{
|
||||
distanceSens_[iDV] =
|
||||
gSum
|
||||
(
|
||||
(
|
||||
distanceSensPtr().primitiveField()
|
||||
&& gradDxDb.primitiveField()
|
||||
)
|
||||
*mesh_.V()
|
||||
);
|
||||
}
|
||||
|
||||
// Terms from fvOptions
|
||||
optionsSens_[iDV] +=
|
||||
gSum((optionsDxDbMult_ & m.primitiveField())*mesh_.V());
|
||||
}
|
||||
|
||||
// Sum contributions
|
||||
derivatives_ =
|
||||
flowSens_
|
||||
+ dSdbSens_
|
||||
+ dndbSens_
|
||||
+ dxdbDirectSens_
|
||||
+ dVdbSens_
|
||||
+ distanceSens_
|
||||
+ optionsSens_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivityBezierFI::clearSensitivities()
|
||||
{
|
||||
flowSens_ = Zero;
|
||||
dSdbSens_ = Zero;
|
||||
dndbSens_ = Zero;
|
||||
dxdbDirectSens_ = Zero;
|
||||
dVdbSens_ = Zero;
|
||||
distanceSens_ = Zero;
|
||||
optionsSens_ = Zero;
|
||||
|
||||
FIBase::clearSensitivities();
|
||||
}
|
||||
|
||||
|
||||
void sensitivityBezierFI::write(const word& baseName)
|
||||
{
|
||||
Info<< "Writing control point sensitivities to file" << endl;
|
||||
if (Pstream::master())
|
||||
{
|
||||
OFstream derivFile
|
||||
(
|
||||
derivativesFolder_/
|
||||
baseName + adjointVars_.solverName() + mesh_.time().timeName()
|
||||
);
|
||||
unsigned int widthDV = max(int(name(flowSens_.size()).size()), int(3));
|
||||
unsigned int width = IOstream::defaultPrecision() + 7;
|
||||
derivFile
|
||||
<< setw(widthDV) << "#dv" << " "
|
||||
<< setw(width) << "total" << " "
|
||||
<< setw(width) << "flow" << " "
|
||||
<< setw(width) << "dSdb" << " "
|
||||
<< setw(width) << "dndb" << " "
|
||||
<< setw(width) << "dxdbDirect" << " "
|
||||
<< setw(width) << "dVdb" << " "
|
||||
<< setw(width) << "distance" << endl;
|
||||
const label nDVs = derivatives_.size();
|
||||
const label nBezier = Bezier_.nBezier();
|
||||
const boolListList& confineMovement = Bezier_.confineMovement();
|
||||
label lastActive(-1);
|
||||
|
||||
for (label iDV = 0; iDV < nDVs; iDV++)
|
||||
{
|
||||
label iCP = iDV%nBezier;
|
||||
label idir = iDV/nBezier;
|
||||
if (!confineMovement[idir][iCP])
|
||||
{
|
||||
if (iDV!=lastActive + 1) derivFile << "\n";
|
||||
lastActive = iDV;
|
||||
derivFile
|
||||
<< setw(widthDV) << iDV << " "
|
||||
<< setw(width) << derivatives_[iDV] << " "
|
||||
<< setw(width) << flowSens_[iDV] << " "
|
||||
<< setw(width) << dSdbSens_[iDV] << " "
|
||||
<< setw(width) << dndbSens_[iDV] << " "
|
||||
<< setw(width) << dxdbDirectSens_[iDV] << " "
|
||||
<< setw(width) << dVdbSens_[iDV] << " "
|
||||
<< setw(width) << distanceSens_[iDV] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,169 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::sensitivityBezierFI
|
||||
|
||||
Description
|
||||
Calculation of adjoint based sensitivities for Bezier control points
|
||||
using the FI appoach
|
||||
|
||||
SourceFiles
|
||||
sensitivityBezierFI.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef sensitivityBezierFIIncompressible_H
|
||||
#define sensitivityBezierFIIncompressible_H
|
||||
|
||||
#include "primitiveFieldsFwd.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "pointFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "FIBaseIncompressible.H"
|
||||
#include "PrimitivePatchInterpolation.H"
|
||||
#include "deltaBoundary.H"
|
||||
#include "Bezier.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class sensitivityBezierFI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class sensitivityBezierFI
|
||||
:
|
||||
public FIBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
Bezier Bezier_;
|
||||
|
||||
//- Flow related term
|
||||
scalarField flowSens_;
|
||||
|
||||
//- Term depending on delta(n dS)/delta b
|
||||
scalarField dSdbSens_;
|
||||
|
||||
//- Term depending on delta(n)/delta b
|
||||
scalarField dndbSens_;
|
||||
|
||||
//- Term depending on delta(x)/delta b for objectives that directly
|
||||
//- depend on x
|
||||
scalarField dxdbDirectSens_;
|
||||
|
||||
//- Term depending on delta(V)/delta b
|
||||
scalarField dVdbSens_;
|
||||
|
||||
//- Term depending on distance differentiation
|
||||
scalarField distanceSens_;
|
||||
|
||||
//- Term depending on fvOptions
|
||||
scalarField optionsSens_;
|
||||
|
||||
fileName derivativesFolder_;
|
||||
|
||||
label meshMovementIters_;
|
||||
scalar meshMovementResidualLimit_;
|
||||
volVectorField dxdb_;
|
||||
|
||||
void read();
|
||||
|
||||
tmp<volVectorField> solveMeshMovementEqn
|
||||
(
|
||||
const label iCP,
|
||||
const label idir
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
sensitivityBezierFI(const sensitivityBezierFI&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const sensitivityBezierFI&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("BezierFI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
sensitivityBezierFI
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~sensitivityBezierFI() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivities to file
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -70,8 +70,7 @@ sensitivityMultiple::sensitivityMultiple
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
sensTypes_(dict.subDict("sensTypes").toc()),
|
||||
sens_(sensTypes_.size()),
|
||||
derivatives_(0)
|
||||
sens_(sensTypes_.size())
|
||||
{
|
||||
forAll(sensTypes_, sI)
|
||||
{
|
||||
@ -113,16 +112,43 @@ bool sensitivityMultiple::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
void sensitivityMultiple::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
forAll(sens_, sI)
|
||||
{
|
||||
sens_[sI].accumulateIntegrand(dt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivityMultiple::assembleSensitivities()
|
||||
{
|
||||
forAll(sens_, sI)
|
||||
{
|
||||
sens_[sI].assembleSensitivities();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const scalarField& sensitivityMultiple::calculateSensitivities()
|
||||
{
|
||||
forAll(sens_, sI)
|
||||
{
|
||||
Info<< "Computing sensitivities " << sensTypes_[sI] << endl;
|
||||
sens_[sI].calculateSensitivities();
|
||||
derivatives_ = sens_[sI].calculateSensitivities();
|
||||
}
|
||||
write(type());
|
||||
|
||||
return (derivatives_);
|
||||
return derivatives_;
|
||||
}
|
||||
|
||||
|
||||
void sensitivityMultiple::clearSensitivities()
|
||||
{
|
||||
forAll(sens_, sI)
|
||||
{
|
||||
sens_[sI].clearSensitivities();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -66,8 +66,6 @@ protected:
|
||||
|
||||
PtrList<adjointSensitivity> sens_;
|
||||
|
||||
scalarField derivatives_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -109,9 +107,18 @@ public:
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Accumulate sensitivity integrands
|
||||
virtual void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Calculates sensitivities at wall surface points
|
||||
const scalarField& calculateSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivities to file
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
@ -50,63 +50,7 @@ addToRunTimeSelectionTable
|
||||
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_
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void sensitivitySurface::addGeometricSens()
|
||||
{
|
||||
@ -127,9 +71,8 @@ void sensitivitySurface::addGeometricSens()
|
||||
);
|
||||
// Geometric (or "direct") sensitivities are better computed directly
|
||||
// on the points
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
vectorField nf(patch.nf());
|
||||
|
||||
@ -200,9 +143,8 @@ void sensitivitySurface::addGeometricSens()
|
||||
// boundaries
|
||||
vectorField dSdbGlobal(mesh_.nPoints(), vector::zero);
|
||||
vectorField dndbGlobal(mesh_.nPoints(), vector::zero);
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
const labelList& meshPoints =
|
||||
mesh_.boundaryMesh()[patchI].meshPoints();
|
||||
forAll(meshPoints, ppI)
|
||||
@ -222,9 +164,8 @@ void sensitivitySurface::addGeometricSens()
|
||||
mesh_, dndbGlobal, plusEqOp<vector>(), vector::zero
|
||||
);
|
||||
// Transfer back to local fields and map to faces
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
const labelList& meshPoints = patch.patch().meshPoints();
|
||||
const scalarField& magSf = patch.magSf();
|
||||
@ -252,6 +193,20 @@ void sensitivitySurface::addGeometricSens()
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurface::setSuffixName()
|
||||
{
|
||||
// Determine suffix for fields holding the sens
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
shapeSensitivitiesBase::setSuffix(adjointVars_.solverName() + "ESI");
|
||||
}
|
||||
else
|
||||
{
|
||||
shapeSensitivitiesBase::setSuffix(adjointVars_.solverName() + "SI");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivitySurface::sensitivitySurface
|
||||
@ -273,7 +228,7 @@ sensitivitySurface::sensitivitySurface
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
derivatives_(0),
|
||||
shapeSensitivitiesBase(mesh, dict),
|
||||
includeSurfaceArea_(false),
|
||||
includePressureTerm_(false),
|
||||
includeGradStressTerm_(false),
|
||||
@ -291,6 +246,7 @@ sensitivitySurface::sensitivitySurface
|
||||
CfOnPatchPtr_(nullptr)
|
||||
{
|
||||
read();
|
||||
setSuffixName();
|
||||
|
||||
// Allocate boundary field pointer
|
||||
wallFaceSensVecPtr_.reset(createZeroBoundaryPtr<vector>(mesh_));
|
||||
@ -359,6 +315,62 @@ sensitivitySurface::sensitivitySurface
|
||||
|
||||
// * * * * * * * * * * * * * * * 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_
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool sensitivitySurface::readDict(const dictionary& dict)
|
||||
{
|
||||
if (sensitivity::readDict(dict))
|
||||
@ -383,16 +395,15 @@ bool sensitivitySurface::readDict(const dictionary& dict)
|
||||
void sensitivitySurface::computeDerivativesSize()
|
||||
{
|
||||
label nFaces(0);
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
nFaces += mesh_.boundary()[patchI].size();
|
||||
}
|
||||
derivatives_.setSize(nFaces);
|
||||
}
|
||||
|
||||
|
||||
const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
void sensitivitySurface::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Grab references
|
||||
const volScalarField& p = primalVars_.p();
|
||||
@ -403,27 +414,6 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
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>&
|
||||
@ -479,38 +469,23 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
volTensorField gradStressY(fvc::grad(stressYPtr()));
|
||||
volTensorField gradStressZ(fvc::grad(stressZPtr()));
|
||||
|
||||
// Solve extra equations if necessary
|
||||
autoPtr<boundaryVectorField> distanceSensPtr(nullptr);
|
||||
// Accumulate source for additional post-processing PDEs, if necessary
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->solve();
|
||||
distanceSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
|
||||
const boundaryVectorField& sens =
|
||||
eikonalSolver_->distanceSensitivities();
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
distanceSensPtr()[patchI] = sens[patchI];
|
||||
}
|
||||
eikonalSolver_->accumulateIntegrand(dt);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
meshMovementSolver_->accumulateIntegrand(dt);
|
||||
}
|
||||
|
||||
// Terms from the adjoint turbulence model
|
||||
const boundaryVectorField& adjointTMsensitivities =
|
||||
adjointTurbulence->wallShapeSensitivities();
|
||||
|
||||
Info<< " Calculating adjoint sensitivity. " << endl;
|
||||
DebugInfo
|
||||
<< " Calculating adjoint sensitivity. " << endl;
|
||||
|
||||
// Sensitivities do not include locale surface area by default.
|
||||
// Part of the sensitivities that multiplies dxFace/db
|
||||
@ -598,20 +573,6 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
)* 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());
|
||||
|
||||
@ -630,19 +591,69 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
}
|
||||
|
||||
// Fill in sensitivity fields
|
||||
wallFaceSensVecPtr_()[patchI] =
|
||||
wallFaceSensVecPtr_()[patchI] +=
|
||||
(
|
||||
stressTerm
|
||||
+ gradStressTerm
|
||||
+ pressureTerm
|
||||
+ distanceTerm
|
||||
+ meshMovementTerm
|
||||
+ adjointTMsensitivities[patchI]
|
||||
+ dxdbMultiplierTot;
|
||||
+ dxdbMultiplierTot
|
||||
)*dt;
|
||||
}
|
||||
|
||||
// Add the sensitivity part corresponding to changes of the normal vector
|
||||
// Computed at points and mapped to faces
|
||||
addGeometricSens();
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurface::assembleSensitivities()
|
||||
{
|
||||
// Update geometric fields for use by external users
|
||||
if (writeGeometricInfo_)
|
||||
{
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Solve extra equations if necessary
|
||||
// Solved using accumulated sources over time
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Project to normal face vector
|
||||
label nPassedFaces(0);
|
||||
@ -651,11 +662,22 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
tmp<vectorField> tnf(patch.nf());
|
||||
const vectorField& nf = tnf();
|
||||
const scalarField& magSf = patch.magSf();
|
||||
|
||||
// Distance related terms
|
||||
if (includeDistance_)
|
||||
{
|
||||
wallFaceSensVecPtr_()[patchI] += distanceSensPtr()[patchI];
|
||||
}
|
||||
|
||||
// Mesh movement related terms
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
wallFaceSensVecPtr_()[patchI] += meshMovementSensPtr()[patchI];
|
||||
}
|
||||
|
||||
if (includeSurfaceArea_)
|
||||
{
|
||||
wallFaceSensVecPtr_()[patchI] *= magSf;
|
||||
wallFaceSensVecPtr_()[patchI] *= patch.magSf();
|
||||
}
|
||||
|
||||
wallFaceSensNormalPtr_()[patchI] = wallFaceSensVecPtr_()[patchI] & nf;
|
||||
@ -669,11 +691,23 @@ const scalarField& sensitivitySurface::calculateSensitivities()
|
||||
}
|
||||
nPassedFaces += patch.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Write sens fields
|
||||
write(type());
|
||||
|
||||
return (derivatives_);
|
||||
void sensitivitySurface::clearSensitivities()
|
||||
{
|
||||
// Reset terms in post-processing PDEs
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->reset();
|
||||
}
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
meshMovementSolver_->reset();
|
||||
}
|
||||
// Reset sensitivity fields
|
||||
adjointSensitivity::clearSensitivities();
|
||||
shapeSensitivitiesBase::clear();
|
||||
}
|
||||
|
||||
|
||||
@ -685,16 +719,9 @@ autoPtr<adjointEikonalSolver>& sensitivitySurface::getAdjointEikonalSolver()
|
||||
|
||||
void sensitivitySurface::write(const word& baseName)
|
||||
{
|
||||
// Determine suffix for fields holding the sens
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
surfaceFieldSuffix_ = word("ESI");
|
||||
}
|
||||
else
|
||||
{
|
||||
surfaceFieldSuffix_ = word("SI");
|
||||
}
|
||||
setSuffixName();
|
||||
adjointSensitivity::write();
|
||||
shapeSensitivitiesBase::write();
|
||||
|
||||
if (writeGeometricInfo_)
|
||||
{
|
||||
|
||||
@ -41,6 +41,7 @@ SourceFiles
|
||||
#define sensitivitySurfaceIncompressible_H
|
||||
|
||||
#include "adjointSensitivityIncompressible.H"
|
||||
#include "shapeSensitivitiesBase.H"
|
||||
#include "adjointEikonalSolverIncompressible.H"
|
||||
#include "adjointMeshMovementSolverIncompressible.H"
|
||||
#include "deltaBoundary.H"
|
||||
@ -54,19 +55,18 @@ namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class sensitivitySurface Declaration
|
||||
Class sensitivitySurface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class sensitivitySurface
|
||||
:
|
||||
public adjointSensitivity
|
||||
public adjointSensitivity,
|
||||
public shapeSensitivitiesBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Scalar normal sens
|
||||
scalarField derivatives_;
|
||||
|
||||
//- Include surface area in sens computation
|
||||
bool includeSurfaceArea_;
|
||||
@ -107,13 +107,13 @@ protected:
|
||||
|
||||
// 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();
|
||||
|
||||
//- Set suffix name for sensitivity fields
|
||||
void setSuffixName();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -152,19 +152,44 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Read controls and update solver pointers if necessary
|
||||
void read();
|
||||
|
||||
//- 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();
|
||||
//- Accumulate sensitivity integrands
|
||||
virtual void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Get adjoint eikonal solver
|
||||
autoPtr<adjointEikonalSolver>& getAdjointEikonalSolver();
|
||||
|
||||
//- Write sensitivity maps
|
||||
virtual void write(const word& baseName = word::null);
|
||||
|
||||
// Inline geters and setters
|
||||
|
||||
//- Get access to the includeObjective bool
|
||||
inline bool getIncludeObjective() const;
|
||||
|
||||
//- Get access to the includeSurfaceArea bool
|
||||
inline bool getIncludeSurfaceArea() const;
|
||||
|
||||
//- Set includeObjective bool
|
||||
inline void setIncludeObjective(const bool includeObjective);
|
||||
|
||||
//- Set includeSurfaceArea bool
|
||||
inline void setIncludeSurfaceArea(const bool includeSurfaceArea);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -175,6 +200,10 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "sensitivitySurfaceIncompressibleI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
| Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
| Copyright (C) 2013-2019 FOSS GP
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool sensitivitySurface::getIncludeObjective() const
|
||||
{
|
||||
return includeObjective_;
|
||||
}
|
||||
|
||||
|
||||
inline bool sensitivitySurface::getIncludeSurfaceArea() const
|
||||
{
|
||||
return includeSurfaceArea_;
|
||||
}
|
||||
|
||||
|
||||
inline void sensitivitySurface::setIncludeObjective
|
||||
(
|
||||
const bool includeObjective
|
||||
)
|
||||
{
|
||||
includeObjective_ = includeObjective;
|
||||
}
|
||||
|
||||
|
||||
inline void sensitivitySurface::setIncludeSurfaceArea
|
||||
(
|
||||
const bool includeSurfaceArea
|
||||
)
|
||||
{
|
||||
includeSurfaceArea_ = includeSurfaceArea;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
@ -49,7 +49,7 @@ addToRunTimeSelectionTable
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void sensitivitySurfacePoints::read()
|
||||
{
|
||||
@ -107,6 +107,217 @@ void sensitivitySurfacePoints::read()
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::finaliseFaceMultiplier()
|
||||
{
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
// Add to other terms multiplying dxFace/dxPoints
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
tmp<vectorField> tnf = patch.nf();
|
||||
const scalarField& magSf = patch.magSf();
|
||||
// Distance related terms
|
||||
if (includeDistance_)
|
||||
{
|
||||
wallFaceSens_()[patchI] += distanceSensPtr()[patchI];
|
||||
}
|
||||
|
||||
// Mesh movement related terms
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
wallFaceSens_()[patchI] += meshMovementSensPtr()[patchI];
|
||||
}
|
||||
|
||||
// Add local face area
|
||||
//~~~~~~~~~~~~~~~~~~~~
|
||||
// Sensitivities DO include locale surface area, to get
|
||||
// the correct weighting from the contributions of various faces.
|
||||
// Normalized at the end.
|
||||
// dSfdbMult already includes the local area. No need to re-multiply
|
||||
wallFaceSens_()[patchI] *= magSf;
|
||||
dnfdbMult_()[patchI] *= magSf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::finalisePointSensitivities()
|
||||
{
|
||||
// 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];
|
||||
vectorField nf(patch.nf());
|
||||
|
||||
// Point sens result for patch
|
||||
vectorField& pointPatchSens = wallPointSensVecPtr_()[patchI];
|
||||
|
||||
// Face sens for patch
|
||||
const vectorField& facePatchSens = wallFaceSens_()[patchI];
|
||||
|
||||
// Geometry variances
|
||||
const vectorField& dSfdbMultPatch = dSfdbMult_()[patchI];
|
||||
const vectorField& dnfdbMultPatch = dnfdbMult_()[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 [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] +=
|
||||
dSfdbMultPatch[localFaceIndex] & deltaSf;
|
||||
|
||||
// Element [2] is the variation in the unit normal
|
||||
const tensor& deltaNf = deltaNormals[2];
|
||||
pointPatchSens[ppI] +=
|
||||
dnfdbMultPatch[localFaceIndex] & deltaNf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::constructGlobalPointNormalsAndAreas
|
||||
(
|
||||
vectorField& pointNormals,
|
||||
scalarField& pointMagSf
|
||||
)
|
||||
{
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const fvPatch& patch = mesh_.boundary()[patchI];
|
||||
const scalarField& magSf = patch.magSf();
|
||||
vectorField nf(patch.nf());
|
||||
|
||||
// Correspondance of local point addressing to global point addressing
|
||||
const labelList& meshPoints = patch.patch().meshPoints();
|
||||
|
||||
// Each local patch point belongs to these local patch faces
|
||||
// (local numbering)
|
||||
const labelListList& patchPointFaces = patch.patch().pointFaces();
|
||||
|
||||
// Loop over patch points
|
||||
forAll(meshPoints, ppI)
|
||||
{
|
||||
const labelList& pointFaces = patchPointFaces[ppI];
|
||||
forAll(pointFaces, pfI)
|
||||
{
|
||||
const label localFaceIndex = pointFaces[pfI];
|
||||
|
||||
// Accumulate information for point normals
|
||||
pointNormals[meshPoints[ppI]] += nf[localFaceIndex];
|
||||
pointMagSf[meshPoints[ppI]] += magSf[localFaceIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh_,
|
||||
pointNormals,
|
||||
plusEqOp<vector>(),
|
||||
vector::zero
|
||||
);
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh_,
|
||||
pointMagSf,
|
||||
plusEqOp<scalar>(),
|
||||
scalar(0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::setSuffixName()
|
||||
{
|
||||
// Determine suffix for fields holding the sens
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
shapeSensitivitiesBase::setSuffix(adjointVars_.solverName() + "ESI");
|
||||
}
|
||||
else
|
||||
{
|
||||
shapeSensitivitiesBase::setSuffix(adjointVars_.solverName() + "SI");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivitySurfacePoints::sensitivitySurfacePoints
|
||||
@ -128,7 +339,7 @@ sensitivitySurfacePoints::sensitivitySurfacePoints
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
derivatives_(0),
|
||||
shapeSensitivitiesBase(mesh, dict),
|
||||
includeSurfaceArea_(false),
|
||||
includePressureTerm_(false),
|
||||
includeGradStressTerm_(false),
|
||||
@ -138,7 +349,11 @@ sensitivitySurfacePoints::sensitivitySurfacePoints
|
||||
includeMeshMovement_(false),
|
||||
includeObjective_(false),
|
||||
eikonalSolver_(nullptr),
|
||||
meshMovementSolver_(nullptr)
|
||||
meshMovementSolver_(nullptr),
|
||||
wallFaceSens_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dSfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
|
||||
dnfdbMult_(createZeroBoundaryPtr<vector>(mesh_))
|
||||
|
||||
{
|
||||
read();
|
||||
|
||||
@ -189,7 +404,7 @@ bool sensitivitySurfacePoints::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
void sensitivitySurfacePoints::accumulateIntegrand(const scalar dt)
|
||||
{
|
||||
// Grab references
|
||||
const volScalarField& p = primalVars_.p();
|
||||
@ -200,16 +415,8 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
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;
|
||||
DebugInfo
|
||||
<< " Calculating auxilary quantities " << endl;
|
||||
|
||||
// Fields needed to calculate adjoint sensitivities
|
||||
volScalarField nuEff(adjointTurbulence->nuEff());
|
||||
@ -262,31 +469,16 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
volTensorField gradStressY(fvc::grad(stressYPtr()));
|
||||
volTensorField gradStressZ(fvc::grad(stressZPtr()));
|
||||
|
||||
// solve extra equations if necessary
|
||||
autoPtr<boundaryVectorField> distanceSensPtr(nullptr);
|
||||
// Solve extra equations if necessary
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->solve();
|
||||
distanceSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
|
||||
const boundaryVectorField& sens =
|
||||
eikonalSolver_->distanceSensitivities();
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
distanceSensPtr()[patchI] = sens[patchI];
|
||||
}
|
||||
eikonalSolver_->accumulateIntegrand(dt);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
meshMovementSolver_->accumulateIntegrand(dt);
|
||||
}
|
||||
|
||||
// Terms from the adjoint turbulence model
|
||||
@ -296,23 +488,16 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
// Objective references
|
||||
PtrList<objective>& functions(objectiveManager_.getObjectiveFunctions());
|
||||
|
||||
Info<< " Calculating adjoint sensitivity. " << endl;
|
||||
DebugInfo
|
||||
<< " 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_)
|
||||
);
|
||||
|
||||
// dxFace/dxPoint.
|
||||
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
|
||||
@ -387,49 +572,49 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
*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
|
||||
);
|
||||
vectorField dxdbMultiplierTot(patch.size(), vector::zero);
|
||||
if (includeObjective_)
|
||||
{
|
||||
// Term from objectives multiplying dxdb
|
||||
forAll(functions, funcI)
|
||||
{
|
||||
const scalar wei = functions[funcI].weight();
|
||||
// dt added in wallFaceSens_
|
||||
dxdbMultiplierTot +=
|
||||
functions[funcI].weight()
|
||||
* functions[funcI].dxdbDirectMultiplier(patchI);
|
||||
wei*functions[funcI].dxdbDirectMultiplier(patchI);
|
||||
|
||||
// Fill in multipliers of d(Sf)/db and d(nf)/db
|
||||
dSfdbMult_()[patchI] +=
|
||||
wei*dt*functions[funcI].dSdbMultiplier(patchI);
|
||||
dnfdbMult_()[patchI] +=
|
||||
wei*dt*functions[funcI].dndbMultiplier(patchI);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in dxFace/dxPoint multiplier.
|
||||
// Missing geometric contributions which are directly computed on the
|
||||
// points
|
||||
wallFaceSens()[patchI] =
|
||||
wallFaceSens_()[patchI] +=
|
||||
(
|
||||
stressTerm
|
||||
+ gradStressTerm
|
||||
+ pressureTerm
|
||||
+ distanceTerm
|
||||
+ meshMovementTerm
|
||||
+ adjointTMsensitivities[patchI]
|
||||
+ dxdbMultiplierTot;
|
||||
wallFaceSens()[patchI] *= magSf;
|
||||
+ dxdbMultiplierTot
|
||||
)*dt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::assembleSensitivities()
|
||||
{
|
||||
// Add remaining parts to term multiplying dxFace/dxPoints
|
||||
// Solves for post-processing PDEs
|
||||
finaliseFaceMultiplier();
|
||||
|
||||
// Geometric (or "direct") sensitivities are better computed directly on
|
||||
// the points. Compute them and add the ones that depend on dxFace/dxPoint
|
||||
finalisePointSensitivities();
|
||||
|
||||
// polyPatch::pointNormals will give the wrong result for points
|
||||
// belonging to multiple patches or patch-processorPatch intersections.
|
||||
@ -437,104 +622,10 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
constructGlobalPointNormalsAndAreas(pointNormals, pointMagSf);
|
||||
|
||||
// Do parallel communications to avoid wrong values at processor boundaries
|
||||
// - global field for accumulation
|
||||
// Global field for accumulation
|
||||
vectorField pointSensGlobal(mesh_.nPoints(), vector::zero);
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
@ -547,7 +638,7 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate dJ/dx_i, pointNormals and pointFaces number
|
||||
// Accumulate dJ/dx_i
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh_,
|
||||
@ -555,20 +646,6 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
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_)
|
||||
@ -588,7 +665,7 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
{
|
||||
const labelList& meshPoints = patch.meshPoints();
|
||||
|
||||
// avoid storing unit point normals in the global list since we
|
||||
// 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);
|
||||
@ -644,26 +721,37 @@ const scalarField& sensitivitySurfacePoints::calculateSensitivities()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write sens fields
|
||||
write(type());
|
||||
|
||||
return (derivatives_);
|
||||
void sensitivitySurfacePoints::clearSensitivities()
|
||||
{
|
||||
// Reset terms in post-processing PDEs
|
||||
if (includeDistance_)
|
||||
{
|
||||
eikonalSolver_->reset();
|
||||
}
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
meshMovementSolver_->reset();
|
||||
}
|
||||
|
||||
// Reset local fields to zero
|
||||
wallFaceSens_() = vector::zero;
|
||||
dSfdbMult_() = vector::zero;
|
||||
dnfdbMult_() = vector::zero;
|
||||
|
||||
// Reset sensitivity fields
|
||||
adjointSensitivity::clearSensitivities();
|
||||
shapeSensitivitiesBase::clear();
|
||||
}
|
||||
|
||||
|
||||
void sensitivitySurfacePoints::write(const word& baseName)
|
||||
{
|
||||
//determine suffix for fields holding the sens
|
||||
if (includeMeshMovement_)
|
||||
{
|
||||
surfaceFieldSuffix_ = "ESI";
|
||||
}
|
||||
else
|
||||
{
|
||||
surfaceFieldSuffix_ = "SI";
|
||||
}
|
||||
setSuffixName();
|
||||
adjointSensitivity::write();
|
||||
shapeSensitivitiesBase::write();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ SourceFiles
|
||||
#define sensitivitySurfacePointsIncompressible_H
|
||||
|
||||
#include "adjointSensitivityIncompressible.H"
|
||||
#include "shapeSensitivitiesBase.H"
|
||||
#include "adjointEikonalSolverIncompressible.H"
|
||||
#include "adjointMeshMovementSolverIncompressible.H"
|
||||
#include "deltaBoundary.H"
|
||||
@ -59,14 +60,13 @@ namespace incompressible
|
||||
|
||||
class sensitivitySurfacePoints
|
||||
:
|
||||
public adjointSensitivity
|
||||
public adjointSensitivity,
|
||||
public shapeSensitivitiesBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Scalar normal sens
|
||||
scalarField derivatives_;
|
||||
|
||||
//- Include surface area in sens computation
|
||||
bool includeSurfaceArea_;
|
||||
@ -96,12 +96,42 @@ protected:
|
||||
|
||||
autoPtr<adjointMeshMovementSolver> meshMovementSolver_;
|
||||
|
||||
//- 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_;
|
||||
|
||||
//- Multipliers of d(Sf)/db and d(nf)/db
|
||||
autoPtr<boundaryVectorField> dSfdbMult_;
|
||||
autoPtr<boundaryVectorField> dnfdbMult_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Read controls and update solver pointers if necessary
|
||||
void read();
|
||||
|
||||
//- Add terms related to post-processing PDEs
|
||||
//- (i.e. adjoint Eikonal, adjoint mesh movement)
|
||||
//- and add local face area
|
||||
void finaliseFaceMultiplier();
|
||||
|
||||
//- Converts face sensitivities to point sensitivities and adds the
|
||||
//- ones directly computed in points (i.e. dSf/db and dnf/db).
|
||||
void finalisePointSensitivities();
|
||||
|
||||
//- Construct globally correct point normals and point areas
|
||||
void constructGlobalPointNormalsAndAreas
|
||||
(
|
||||
vectorField& pointNormals,
|
||||
scalarField& pointMagSf
|
||||
);
|
||||
|
||||
//- Set suffix name for sensitivity fields
|
||||
void setSuffixName();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@ -143,8 +173,14 @@ public:
|
||||
//- Read dict if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Calculates sensitivities at wall surface points
|
||||
const scalarField& calculateSensitivities();
|
||||
//- Accumulate sensitivity integrands
|
||||
virtual void accumulateIntegrand(const scalar dt);
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
@ -0,0 +1,317 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "sensitivityVolBSplinesIncompressible.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IOmanip.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(sensitivityVolBSplines, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
adjointSensitivity,
|
||||
sensitivityVolBSplines,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityVolBSplines::computeObjectiveContributions()
|
||||
{
|
||||
if (includeObjective_)
|
||||
{
|
||||
label passedCPs = 0;
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
label nb = boxes[iNURB].getControlPoints().size();
|
||||
for (label cpI = 0; cpI < nb; cpI++)
|
||||
{
|
||||
vector dSdbSensCP(vector::zero);
|
||||
vector dndbSensCP(vector::zero);
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
tensorField dSdb
|
||||
(
|
||||
boxes[iNURB].dndbBasedSensitivities(patchI, cpI)
|
||||
);
|
||||
dSdbSensCP += gSum(dSfdbMult_()[patchI] & dSdb);
|
||||
|
||||
tensorField dndb
|
||||
(
|
||||
boxes[iNURB].dndbBasedSensitivities
|
||||
(
|
||||
patchI,
|
||||
cpI,
|
||||
false
|
||||
)
|
||||
);
|
||||
dndbSensCP += gSum((dnfdbMult_()[patchI] & dndb));
|
||||
}
|
||||
dSdbSens_[passedCPs + cpI] = dSdbSensCP;
|
||||
dndbSens_[passedCPs + cpI] = dndbSensCP;
|
||||
}
|
||||
boxes[iNURB].boundControlPointMovement(dSdbSens_);
|
||||
boxes[iNURB].boundControlPointMovement(dndbSens_);
|
||||
passedCPs += nb;
|
||||
}
|
||||
|
||||
passedCPs = 0;
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
vectorField sensDxDbDirect =
|
||||
boxes[iNURB].computeControlPointSensitivities
|
||||
(
|
||||
dxdbDirectMult_(),
|
||||
sensitivityPatchIDs_.toc()
|
||||
);
|
||||
|
||||
// Transfer to global list
|
||||
forAll(sensDxDbDirect, cpI)
|
||||
{
|
||||
dxdbDirectSens_[passedCPs + cpI] = sensDxDbDirect[cpI];
|
||||
}
|
||||
boxes[iNURB].boundControlPointMovement(dxdbDirectSens_);
|
||||
passedCPs += sensDxDbDirect.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivityVolBSplines::sensitivityVolBSplines
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
SIBase
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
volBSplinesBase_
|
||||
(
|
||||
const_cast<volBSplinesBase&>(volBSplinesBase::New(mesh))
|
||||
),
|
||||
|
||||
flowSens_(0),
|
||||
dSdbSens_(0),
|
||||
dndbSens_(0),
|
||||
dxdbDirectSens_(0),
|
||||
|
||||
derivativesFolder_("optimisation"/type() + "Derivatives")
|
||||
{
|
||||
// No boundary field pointers need to be allocated
|
||||
label nCPs = volBSplinesBase_.getTotalControlPointsNumber();
|
||||
derivatives_ = scalarField(3*nCPs, Zero);
|
||||
flowSens_ = vectorField(nCPs, vector::zero);
|
||||
dSdbSens_ = vectorField(nCPs, vector::zero);
|
||||
dndbSens_ = vectorField(nCPs, vector::zero);
|
||||
dxdbDirectSens_ = vectorField(nCPs, vector::zero);
|
||||
|
||||
// Create folder to store sensitivities
|
||||
mkDir(derivativesFolder_);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityVolBSplines::assembleSensitivities()
|
||||
{
|
||||
// Assemble the sensitivity map
|
||||
// Solves for the post-processing equations and adds their contribution to
|
||||
// the sensitivity map
|
||||
surfaceSensitivity_.assembleSensitivities();
|
||||
|
||||
// Finalise sensitivities including dxFace/db
|
||||
const boundaryVectorField& faceSens =
|
||||
surfaceSensitivity_.getWallFaceSensVecBoundary();
|
||||
|
||||
label passedCPs(0);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
vectorField sens =
|
||||
boxes[iNURB].computeControlPointSensitivities
|
||||
(
|
||||
faceSens,
|
||||
sensitivityPatchIDs_.toc()
|
||||
);
|
||||
// Transfer to global list
|
||||
forAll(sens, cpI)
|
||||
{
|
||||
flowSens_[passedCPs + cpI] = sens[cpI];
|
||||
}
|
||||
passedCPs += sens.size();
|
||||
|
||||
boxes[iNURB].boundControlPointMovement(flowSens_);
|
||||
}
|
||||
|
||||
// Contribution from objective function
|
||||
// Note:
|
||||
// includeObjectiveContribution has to be set to false (false by default)
|
||||
// in surfaceSensitivity, in order to avoid computing this term twice.
|
||||
// Optionally avoided altogether if includeObjectiveContribution is set to
|
||||
// false for sensitivityVolBSplines
|
||||
computeObjectiveContributions();
|
||||
|
||||
// Transform sensitivites to scalarField in order to cooperate with
|
||||
// updateMethod
|
||||
forAll(flowSens_, cpI)
|
||||
{
|
||||
derivatives_[3*cpI] =
|
||||
flowSens_[cpI].x()
|
||||
+ dSdbSens_[cpI].x()
|
||||
+ dndbSens_[cpI].x()
|
||||
+ dxdbDirectSens_[cpI].x();
|
||||
derivatives_[3*cpI + 1] =
|
||||
flowSens_[cpI].y()
|
||||
+ dSdbSens_[cpI].y()
|
||||
+ dndbSens_[cpI].y()
|
||||
+ dxdbDirectSens_[cpI].y();
|
||||
derivatives_[3*cpI + 2] =
|
||||
flowSens_[cpI].z()
|
||||
+ dSdbSens_[cpI].z()
|
||||
+ dndbSens_[cpI].z()
|
||||
+ dxdbDirectSens_[cpI].z();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivityVolBSplines::clearSensitivities()
|
||||
{
|
||||
flowSens_ = vector::zero;
|
||||
dSdbSens_ = vector::zero;
|
||||
dndbSens_ = vector::zero;
|
||||
dxdbDirectSens_ = vector::zero;
|
||||
|
||||
SIBase::clearSensitivities();
|
||||
}
|
||||
|
||||
|
||||
void sensitivityVolBSplines::write(const word& baseName)
|
||||
{
|
||||
Info<< "Writing control point sensitivities to file" << endl;
|
||||
if (Pstream::master())
|
||||
{
|
||||
OFstream derivFile
|
||||
(
|
||||
derivativesFolder_/
|
||||
baseName + adjointVars_.solverName() + mesh_.time().timeName()
|
||||
);
|
||||
unsigned int widthDV =
|
||||
max(int(Foam::name(derivatives_.size()).size()), int(3));
|
||||
unsigned int width = IOstream::defaultPrecision() + 7;
|
||||
derivFile
|
||||
<< setw(widthDV) << "#cp" << " "
|
||||
<< setw(width) << "total::x"<< " "
|
||||
<< setw(width) << "total::y"<< " "
|
||||
<< setw(width) << "total::z"<< " "
|
||||
<< setw(width) << "flow::x" << " "
|
||||
<< setw(width) << "flow::y" << " "
|
||||
<< setw(width) << "flow::z" << " "
|
||||
<< setw(width) << "dSdb::x" << " "
|
||||
<< setw(width) << "dSdb::y" << " "
|
||||
<< setw(width) << "dSdb::z" << " "
|
||||
<< setw(width) << "dndb::x" << " "
|
||||
<< setw(width) << "dndb::y" << " "
|
||||
<< setw(width) << "dndb::z" << " "
|
||||
<< setw(width) << "dxdbDirect::x" << " "
|
||||
<< setw(width) << "dxdbDirect::y" << " "
|
||||
<< setw(width) << "dxdbDirect::z" << endl;
|
||||
|
||||
label passedCPs(0);
|
||||
label lastActive(-1);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
label nb = boxes[iNURB].getControlPoints().size();
|
||||
const boolList& activeCPs = boxes[iNURB].getActiveCPs();
|
||||
for (label iCP = 0; iCP < nb; iCP++)
|
||||
{
|
||||
if (activeCPs[iCP])
|
||||
{
|
||||
label globalCP = passedCPs + iCP;
|
||||
if (globalCP!=lastActive + 1)
|
||||
{
|
||||
derivFile << "\n";
|
||||
}
|
||||
lastActive = globalCP;
|
||||
|
||||
derivFile
|
||||
<< setw(widthDV) << globalCP << " "
|
||||
<< setw(width) << derivatives_[3*globalCP] << " "
|
||||
<< setw(width) << derivatives_[3*globalCP + 1] << " "
|
||||
<< setw(width) << derivatives_[3*globalCP + 2] << " "
|
||||
<< setw(width) << flowSens_[globalCP].x() << " "
|
||||
<< setw(width) << flowSens_[globalCP].y() << " "
|
||||
<< setw(width) << flowSens_[globalCP].z() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].x() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].y() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].z() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].x() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].y() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].z() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].x() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].y() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].z()
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
passedCPs += nb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,148 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::sensitivityVolBSplines
|
||||
|
||||
Description
|
||||
Calculation of adjoint based sensitivities at vol B-Splines control points
|
||||
using the SI or e-SI approach (determined by surface sensitivities)
|
||||
|
||||
SourceFiles
|
||||
sensitivityVolBSplines.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef sensitivityVolBSplinesIncompressible_H
|
||||
#define sensitivityVolBSplinesIncompressible_H
|
||||
|
||||
#include "SIBaseIncompressible.H"
|
||||
#include "volBSplinesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class sensitivityVolBSplines Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class sensitivityVolBSplines
|
||||
:
|
||||
public SIBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to underlaying volumetric B-Splines morpher
|
||||
volBSplinesBase& volBSplinesBase_;
|
||||
|
||||
//- Flow related term
|
||||
vectorField flowSens_;
|
||||
|
||||
//- Term depending on delta(n dS)/delta b
|
||||
vectorField dSdbSens_;
|
||||
|
||||
//- Term depending on delta (n)/delta b
|
||||
vectorField dndbSens_;
|
||||
|
||||
//- Term dependng on dxdb for objective funtions directly depending
|
||||
//- on x
|
||||
vectorField dxdbDirectSens_;
|
||||
|
||||
fileName derivativesFolder_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
void computeObjectiveContributions();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
sensitivityVolBSplines(const sensitivityVolBSplines&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const sensitivityVolBSplines&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplines");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
sensitivityVolBSplines
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~sensitivityVolBSplines() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivities to file
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,415 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "sensitivityVolBSplinesFIIncompressible.H"
|
||||
#include "pointVolInterpolation.H"
|
||||
#include "fvOptionAdjoint.H"
|
||||
#include "IOmanip.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(sensitivityVolBSplinesFI, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
adjointSensitivity,
|
||||
sensitivityVolBSplinesFI,
|
||||
dictionary
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
sensitivityVolBSplinesFI::sensitivityVolBSplinesFI
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
)
|
||||
:
|
||||
FIBase
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
primalVars,
|
||||
adjointVars,
|
||||
objectiveManager,
|
||||
fvOptionsAdjoint
|
||||
),
|
||||
volBSplinesBase_
|
||||
(
|
||||
const_cast<volBSplinesBase&>(volBSplinesBase::New(mesh))
|
||||
),
|
||||
flowSens_(0),
|
||||
dSdbSens_(0),
|
||||
dndbSens_(0),
|
||||
dxdbDirectSens_(0),
|
||||
dVdbSens_(0),
|
||||
distanceSens_(0),
|
||||
optionsSens_(0),
|
||||
|
||||
derivativesFolder_("optimisation"/type() + "Derivatives")
|
||||
{
|
||||
// No boundary field pointers need to be allocated
|
||||
|
||||
label nCPs = volBSplinesBase_.getTotalControlPointsNumber();
|
||||
derivatives_ = scalarField(3*nCPs, Zero);
|
||||
flowSens_ = vectorField(nCPs, vector::zero);
|
||||
dSdbSens_ = vectorField(nCPs, vector::zero);
|
||||
dndbSens_ = vectorField(nCPs, vector::zero);
|
||||
dxdbDirectSens_ = vectorField(nCPs, vector::zero);
|
||||
dVdbSens_ = vectorField(nCPs, vector::zero);
|
||||
distanceSens_ = vectorField(nCPs, vector::zero);
|
||||
optionsSens_ = vectorField(nCPs, vector::zero);
|
||||
|
||||
// Create folder to store sensitivities
|
||||
mkDir(derivativesFolder_);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void sensitivityVolBSplinesFI::assembleSensitivities()
|
||||
{
|
||||
read();
|
||||
|
||||
// Interpolation engine
|
||||
pointVolInterpolation volPointInter(pointMesh::New(mesh_), mesh_);
|
||||
|
||||
// Adjoint to the eikonal equation
|
||||
autoPtr<volTensorField> distanceSensPtr(nullptr);
|
||||
if (includeDistance_)
|
||||
{
|
||||
// Solver equation
|
||||
eikonalSolver_->solve();
|
||||
|
||||
// Allocate memory and compute grad(dxdb) multiplier
|
||||
distanceSensPtr.reset
|
||||
(
|
||||
createZeroFieldPtr<tensor>
|
||||
(
|
||||
mesh_,
|
||||
"distanceSensPtr",
|
||||
dimensionSet(0, 2, -3, 0, 0, 0, 0)
|
||||
)
|
||||
);
|
||||
distanceSensPtr() = eikonalSolver_->getFISensitivityTerm()().T();
|
||||
}
|
||||
|
||||
// Integration
|
||||
label passedCPs(0);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
label nb = boxes[iNURB].getControlPoints().size();
|
||||
vectorField boxSensitivities(nb, vector::zero);
|
||||
|
||||
vectorField dxdbSens = boxes[iNURB].computeControlPointSensitivities
|
||||
(
|
||||
dxdbDirectMult_(),
|
||||
sensitivityPatchIDs_.toc()
|
||||
);
|
||||
|
||||
for (label cpI = 0; cpI < nb; cpI++)
|
||||
{
|
||||
label globalCP = passedCPs + cpI;
|
||||
|
||||
// Parameterization info
|
||||
tmp<pointTensorField> dxdbI(boxes[iNURB].getDxDb(cpI));
|
||||
tmp<volTensorField> tvolDxDbI(volPointInter.interpolate(dxdbI));
|
||||
const volTensorField& volDxDbI = tvolDxDbI();
|
||||
|
||||
// Chain rule used to get dx/db at cells
|
||||
// Gives practically the same results at a much higher CPU cost
|
||||
/*
|
||||
tmp<volTensorField> tvolDxDbI(boxes[iNURB].getDxCellsDb(cpI));
|
||||
volTensorField& volDxDbI = tvolDxDbI.ref();
|
||||
*/
|
||||
|
||||
// Gradient of parameterization info
|
||||
volVectorField temp
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dxdb",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
vector::zero
|
||||
);
|
||||
|
||||
temp.replace(0, volDxDbI.component(0));
|
||||
temp.replace(1, volDxDbI.component(3));
|
||||
temp.replace(2, volDxDbI.component(6));
|
||||
volTensorField gradDxDb1(fvc::grad(temp));
|
||||
|
||||
temp.replace(0, volDxDbI.component(1));
|
||||
temp.replace(1, volDxDbI.component(4));
|
||||
temp.replace(2, volDxDbI.component(7));
|
||||
volTensorField gradDxDb2(fvc::grad(temp));
|
||||
|
||||
temp.replace(0, volDxDbI.component(2));
|
||||
temp.replace(1, volDxDbI.component(5));
|
||||
temp.replace(2, volDxDbI.component(8));
|
||||
volTensorField gradDxDb3(fvc::grad(temp));
|
||||
|
||||
|
||||
// Volume integral terms
|
||||
flowSens_[globalCP].x() = gSum
|
||||
(
|
||||
(gradDxDbMult_.primitiveField() && gradDxDb1.primitiveField())
|
||||
*mesh_.V()
|
||||
);
|
||||
flowSens_[globalCP].y() = gSum
|
||||
(
|
||||
(gradDxDbMult_.primitiveField() && gradDxDb2.primitiveField())
|
||||
*mesh_.V()
|
||||
);
|
||||
flowSens_[globalCP].z() = gSum
|
||||
(
|
||||
(gradDxDbMult_.primitiveField() && gradDxDb3.primitiveField())
|
||||
*mesh_.V()
|
||||
);
|
||||
|
||||
// Contribution from objective function term from
|
||||
// delta( n dS ) / delta b and
|
||||
// delta ( x ) / delta b
|
||||
// for objectives directly depending on x
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
tensorField dSdb
|
||||
(
|
||||
boxes[iNURB].dndbBasedSensitivities(patchI, cpI)
|
||||
);
|
||||
dSdbSens_[globalCP] += gSum(dSfdbMult_()[patchI] & dSdb);
|
||||
tensorField dndb
|
||||
(
|
||||
boxes[iNURB].dndbBasedSensitivities(patchI, cpI, false)
|
||||
);
|
||||
dndbSens_[globalCP] += gSum((dnfdbMult_()[patchI] & dndb));
|
||||
}
|
||||
|
||||
// Contribution from delta (V) / delta b
|
||||
// For objectives defined as volume integrals only
|
||||
dVdbSens_[globalCP] +=
|
||||
gSum
|
||||
(
|
||||
divDxDbMult_
|
||||
*fvc::div(T(volDxDbI))().primitiveField()
|
||||
*mesh_.V()
|
||||
);
|
||||
|
||||
// Distance dependent term
|
||||
if (includeDistance_)
|
||||
{
|
||||
const tensorField& distSensInt =
|
||||
distanceSensPtr().primitiveField();
|
||||
distanceSens_[globalCP].x() =
|
||||
gSum
|
||||
(
|
||||
(distSensInt && gradDxDb1.primitiveField())*mesh_.V()
|
||||
);
|
||||
distanceSens_[globalCP].y() =
|
||||
gSum
|
||||
(
|
||||
(distSensInt && gradDxDb2.primitiveField())*mesh_.V()
|
||||
);
|
||||
distanceSens_[globalCP].z() =
|
||||
gSum
|
||||
(
|
||||
(distSensInt && gradDxDb3.primitiveField()) *mesh_.V()
|
||||
);
|
||||
}
|
||||
|
||||
// Terms from fvOptions
|
||||
optionsSens_[globalCP] +=
|
||||
gSum((optionsDxDbMult_ & volDxDbI.primitiveField())*mesh_.V());
|
||||
|
||||
// dxdbSens storage
|
||||
dxdbDirectSens_[globalCP] = dxdbSens[cpI];
|
||||
|
||||
boxSensitivities[cpI] =
|
||||
flowSens_[globalCP]
|
||||
+ dSdbSens_[globalCP]
|
||||
+ dndbSens_[globalCP]
|
||||
+ dVdbSens_[globalCP]
|
||||
+ distanceSens_[globalCP]
|
||||
+ dxdbDirectSens_[globalCP]
|
||||
+ optionsSens_[globalCP];
|
||||
}
|
||||
|
||||
// Zero sensitivities in non-active design variables
|
||||
boxes[iNURB].boundControlPointMovement(flowSens_);
|
||||
boxes[iNURB].boundControlPointMovement(dSdbSens_);
|
||||
boxes[iNURB].boundControlPointMovement(dndbSens_);
|
||||
boxes[iNURB].boundControlPointMovement(dVdbSens_);
|
||||
boxes[iNURB].boundControlPointMovement(distanceSens_);
|
||||
boxes[iNURB].boundControlPointMovement(dxdbDirectSens_);
|
||||
boxes[iNURB].boundControlPointMovement(optionsSens_);
|
||||
boxes[iNURB].boundControlPointMovement(boxSensitivities);
|
||||
|
||||
// Transfer sensitivities to global list
|
||||
for (label cpI = 0; cpI < nb; cpI++)
|
||||
{
|
||||
label globalCP = passedCPs + cpI;
|
||||
derivatives_[3*globalCP] = boxSensitivities[cpI].x();
|
||||
derivatives_[3*globalCP + 1] = boxSensitivities[cpI].y();
|
||||
derivatives_[3*globalCP + 2] = boxSensitivities[cpI].z();
|
||||
}
|
||||
|
||||
// Increment number of passed sensitivities
|
||||
passedCPs += nb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sensitivityVolBSplinesFI::clearSensitivities()
|
||||
{
|
||||
flowSens_ = vector::zero;
|
||||
dSdbSens_ = vector::zero;
|
||||
dndbSens_ = vector::zero;
|
||||
dxdbDirectSens_ = vector::zero;
|
||||
dVdbSens_ = vector::zero;
|
||||
distanceSens_ = vector::zero;
|
||||
optionsSens_ = vector::zero;
|
||||
|
||||
FIBase::clearSensitivities();
|
||||
}
|
||||
|
||||
|
||||
void sensitivityVolBSplinesFI::write(const word& baseName)
|
||||
{
|
||||
Info<< "Writing control point sensitivities to file" << endl;
|
||||
if (Pstream::master())
|
||||
{
|
||||
OFstream derivFile
|
||||
(
|
||||
derivativesFolder_/
|
||||
baseName + adjointVars_.solverName() + mesh_.time().timeName()
|
||||
);
|
||||
unsigned int widthDV
|
||||
(
|
||||
max(int(Foam::name(flowSens_.size()).size()), int(3))
|
||||
);
|
||||
unsigned int width = IOstream::defaultPrecision() + 7;
|
||||
derivFile
|
||||
<< setw(widthDV) << "#cp" << " "
|
||||
<< setw(width) << "total::x" << " "
|
||||
<< setw(width) << "total::y" << " "
|
||||
<< setw(width) << "total::z" << " "
|
||||
<< setw(width) << "flow::x" << " "
|
||||
<< setw(width) << "flow::y" << " "
|
||||
<< setw(width) << "flow::z" << " "
|
||||
<< setw(width) << "dSdb::x" << " "
|
||||
<< setw(width) << "dSdb::y" << " "
|
||||
<< setw(width) << "dSdb::z" << " "
|
||||
<< setw(width) << "dndb::x" << " "
|
||||
<< setw(width) << "dndb::y" << " "
|
||||
<< setw(width) << "dndb::z" << " "
|
||||
<< setw(width) << "dxdbDirect::x" << " "
|
||||
<< setw(width) << "dxdbDirect::y" << " "
|
||||
<< setw(width) << "dxdbDirect::z" << " "
|
||||
<< setw(width) << "dVdb::x" << " "
|
||||
<< setw(width) << "dVdb::y" << " "
|
||||
<< setw(width) << "dVdb::z" << " "
|
||||
<< setw(width) << "distance::x" << " "
|
||||
<< setw(width) << "distance::y" << " "
|
||||
<< setw(width) << "distance::z" << " "
|
||||
<< setw(width) << "options::x" << " "
|
||||
<< setw(width) << "options::y" << " "
|
||||
<< setw(width) << "options::z" << endl;
|
||||
|
||||
label passedCPs(0);
|
||||
label lastActive(-1);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
label nb = boxes[iNURB].getControlPoints().size();
|
||||
const boolList& activeCPs = boxes[iNURB].getActiveCPs();
|
||||
for (label iCP = 0; iCP < nb; iCP++)
|
||||
{
|
||||
if (activeCPs[iCP])
|
||||
{
|
||||
label globalCP = passedCPs + iCP;
|
||||
if (globalCP!=lastActive + 1) derivFile << "\n";
|
||||
lastActive = globalCP;
|
||||
|
||||
derivFile
|
||||
<< setw(widthDV) << globalCP << " "
|
||||
<< setw(width) << derivatives_[3*globalCP] << " "
|
||||
<< setw(width) << derivatives_[3*globalCP + 1] << " "
|
||||
<< setw(width) << derivatives_[3*globalCP + 2] << " "
|
||||
<< setw(width) << flowSens_[globalCP].x() << " "
|
||||
<< setw(width) << flowSens_[globalCP].y() << " "
|
||||
<< setw(width) << flowSens_[globalCP].z() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].x() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].y() << " "
|
||||
<< setw(width) << dSdbSens_[globalCP].z() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].x() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].y() << " "
|
||||
<< setw(width) << dndbSens_[globalCP].z() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].x() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].y() << " "
|
||||
<< setw(width) << dxdbDirectSens_[globalCP].z() << " "
|
||||
<< setw(width) << dVdbSens_[globalCP].x() << " "
|
||||
<< setw(width) << dVdbSens_[globalCP].y() << " "
|
||||
<< setw(width) << dVdbSens_[globalCP].z() << " "
|
||||
<< setw(width) << distanceSens_[globalCP].x() << " "
|
||||
<< setw(width) << distanceSens_[globalCP].y() << " "
|
||||
<< setw(width) << distanceSens_[globalCP].z() << " "
|
||||
<< setw(width) << optionsSens_[globalCP].x() << " "
|
||||
<< setw(width) << optionsSens_[globalCP].y() << " "
|
||||
<< setw(width) << optionsSens_[globalCP].z() << endl;
|
||||
}
|
||||
}
|
||||
passedCPs += nb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::sensitivityVolBSplinesFI
|
||||
|
||||
Description
|
||||
Calculation of adjoint based sensitivities at vol B-Splines control points
|
||||
using the FI approach.
|
||||
|
||||
SourceFiles
|
||||
sensitivityVolBSplinesFI.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef sensitivityVolBSplinesFIIncompressible_H
|
||||
#define sensitivityVolBSplinesFIIncompressible_H
|
||||
|
||||
#include "FIBaseIncompressible.H"
|
||||
#include "volBSplinesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace incompressible
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class sensitivityVolBSplinesFI Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class sensitivityVolBSplinesFI
|
||||
:
|
||||
public FIBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to underlaying volumetric B-Splines morpher
|
||||
volBSplinesBase& volBSplinesBase_;
|
||||
|
||||
//- Flow related term
|
||||
vectorField flowSens_;
|
||||
|
||||
//- Term depending on delta(n dS)/delta b
|
||||
vectorField dSdbSens_;
|
||||
|
||||
//- Term depending on delta(n)/delta b
|
||||
vectorField dndbSens_;
|
||||
|
||||
//- Term depending on delta(x)/delta b for objectives that directly
|
||||
//- depend on x
|
||||
vectorField dxdbDirectSens_;
|
||||
|
||||
//- Term depending on delta(V)/delta b
|
||||
vectorField dVdbSens_;
|
||||
|
||||
//- Term depending on distance differentiation
|
||||
vectorField distanceSens_;
|
||||
|
||||
//- Term depending on fvOptions
|
||||
vectorField optionsSens_;
|
||||
|
||||
fileName derivativesFolder_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
sensitivityVolBSplinesFI(const sensitivityVolBSplinesFI&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const sensitivityVolBSplinesFI&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplinesFI");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
sensitivityVolBSplinesFI
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
incompressibleVars& primalVars,
|
||||
incompressibleAdjointVars& adjointVars,
|
||||
objectiveManager& objectiveManager,
|
||||
fv::optionAdjointList& fvOptionsAdjoint
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~sensitivityVolBSplinesFI() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Assemble sensitivities
|
||||
virtual void assembleSensitivities();
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
virtual void clearSensitivities();
|
||||
|
||||
//- Write sensitivities to file
|
||||
virtual void write(const word& baseName = word::null);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -38,136 +38,18 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::sensitivity::writeFaceBasedSens() const
|
||||
{
|
||||
const word suffix(adjointSolverName_ + surfaceFieldSuffix_);
|
||||
|
||||
// Wall face sensitivity projected to normal
|
||||
if (wallFaceSensNormalPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<scalar>
|
||||
(
|
||||
wallFaceSensNormalPtr_,
|
||||
"faceSensNormal" + suffix
|
||||
);
|
||||
}
|
||||
|
||||
if (writeAllSurfaceFiles_)
|
||||
{
|
||||
// Wall face sensitivity vectors
|
||||
if (wallFaceSensVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<vector>
|
||||
(
|
||||
wallFaceSensVecPtr_,
|
||||
"faceSensVec" + suffix
|
||||
);
|
||||
}
|
||||
|
||||
// Normal sens as vectors
|
||||
if (wallFaceSensNormalVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<vector>
|
||||
(
|
||||
wallFaceSensNormalVecPtr_,
|
||||
"faceSensNormalVec" + suffix
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::sensitivity::writePointBasedSens() const
|
||||
{
|
||||
const word suffix(adjointSolverName_ + surfaceFieldSuffix_);
|
||||
|
||||
// Wall point sensitivity projected to normal
|
||||
if (wallPointSensNormalPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<scalar>
|
||||
(
|
||||
wallPointSensNormalPtr_,
|
||||
"pointSensNormal" + suffix
|
||||
);
|
||||
}
|
||||
|
||||
// Write point-based sensitivities, if present
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if (writeAllSurfaceFiles_)
|
||||
{
|
||||
// Wall point sensitivity vectors
|
||||
if (wallPointSensVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<vector>
|
||||
(
|
||||
wallPointSensVecPtr_,
|
||||
"pointSensVec" + suffix
|
||||
);
|
||||
}
|
||||
|
||||
// Normal point as vectors
|
||||
if (wallPointSensNormalVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<vector>
|
||||
(
|
||||
wallPointSensNormalVecPtr_,
|
||||
"pointSensNormalVec" + suffix
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::sensitivity::sensitivity
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
dict_(dict),
|
||||
sensitivityPatchIDs_(0),
|
||||
adjointSolverName_(adjointSolverName),
|
||||
surfaceFieldSuffix_(word::null),
|
||||
writeAllSurfaceFiles_
|
||||
(
|
||||
dict.lookupOrDefault<bool>
|
||||
(
|
||||
"writeAllSurfaceFiles",
|
||||
false
|
||||
)
|
||||
),
|
||||
|
||||
wallFaceSensVecPtr_(nullptr),
|
||||
wallFaceSensNormalPtr_(nullptr),
|
||||
wallFaceSensNormalVecPtr_(nullptr),
|
||||
|
||||
wallPointSensVecPtr_(nullptr),
|
||||
wallPointSensNormalPtr_(nullptr),
|
||||
wallPointSensNormalVecPtr_(nullptr),
|
||||
|
||||
fieldSensPtr_(nullptr)
|
||||
{
|
||||
labelHashSet patches
|
||||
(
|
||||
mesh_.boundaryMesh().patchSet(dict.get<wordRes>("patches"))
|
||||
);
|
||||
|
||||
if (patches.empty())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "There is no patch on which to compute sensitivities. "
|
||||
<< "Check optimisationDict" << nl
|
||||
<< endl;
|
||||
}
|
||||
sensitivityPatchIDs_ = patches.toc();
|
||||
};
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
@ -186,18 +68,6 @@ bool Foam::sensitivity::readDict(const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::sensitivity::sensitivityPatchIDs() const
|
||||
{
|
||||
return sensitivityPatchIDs_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::sensitivity::setSensitivityPatchIDs(const labelList& sensPatchIDs)
|
||||
{
|
||||
sensitivityPatchIDs_ = sensPatchIDs;
|
||||
}
|
||||
|
||||
|
||||
void Foam::sensitivity::computeDerivativesSize()
|
||||
{
|
||||
// Does nothing
|
||||
@ -206,10 +76,6 @@ void Foam::sensitivity::computeDerivativesSize()
|
||||
|
||||
void Foam::sensitivity::write(const word& baseName)
|
||||
{
|
||||
writeFaceBasedSens();
|
||||
|
||||
writePointBasedSens();
|
||||
|
||||
if (fieldSensPtr_.valid())
|
||||
{
|
||||
fieldSensPtr_().write();
|
||||
@ -217,143 +83,4 @@ void Foam::sensitivity::write(const word& baseName)
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volVectorField> Foam::sensitivity::getWallFaceSensVec()
|
||||
{
|
||||
if (wallFaceSensVecPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<vector>
|
||||
(
|
||||
wallFaceSensVecPtr_,
|
||||
"faceSensVec" + adjointSolverName_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no faceSensVec boundary field. Returning zero" << endl;
|
||||
|
||||
return
|
||||
tmp<volVectorField>
|
||||
(
|
||||
createZeroFieldPtr<vector>
|
||||
(
|
||||
mesh_,
|
||||
"faceSensVec" + adjointSolverName_,
|
||||
dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volScalarField> Foam::sensitivity::getWallFaceSensNormal()
|
||||
{
|
||||
if (wallFaceSensNormalPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<scalar>
|
||||
(
|
||||
wallFaceSensNormalPtr_,
|
||||
"faceSensNormal" + adjointSolverName_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no wallFaceSensNormal boundary field. Returning zero" << endl;
|
||||
|
||||
return
|
||||
tmp<volScalarField>
|
||||
(
|
||||
createZeroFieldPtr<scalar>
|
||||
(
|
||||
mesh_,
|
||||
"faceSensNormal" + adjointSolverName_, dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volVectorField> Foam::sensitivity::getWallFaceSensNormalVec()
|
||||
{
|
||||
if (wallFaceSensNormalVecPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<vector>
|
||||
(
|
||||
wallFaceSensNormalVecPtr_,
|
||||
"faceSensNormalVec" + adjointSolverName_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no wallFaceSensNormalVec boundary field. Returning zero"
|
||||
<< endl;
|
||||
|
||||
return
|
||||
tmp<volVectorField>
|
||||
(
|
||||
createZeroFieldPtr<vector>
|
||||
(
|
||||
mesh_,
|
||||
"faceSensNormalVec" + adjointSolverName_,
|
||||
dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointVectorField> Foam::sensitivity::getWallPointSensVec()
|
||||
{
|
||||
tmp<volVectorField> tWallFaceSensVec = getWallFaceSensVec();
|
||||
volPointInterpolation volPointInter(mesh_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensVec));
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointScalarField> Foam::sensitivity::getWallPointSensNormal()
|
||||
{
|
||||
tmp<volScalarField> tWallFaceSensNormal = getWallFaceSensNormal();
|
||||
volPointInterpolation volPointInter(mesh_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensNormal));
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointVectorField>
|
||||
Foam::sensitivity::getWallPointSensNormalVec()
|
||||
{
|
||||
tmp<volVectorField> tWallFaceSensNormalVec = getWallFaceSensNormalVec();
|
||||
volPointInterpolation volPointInter(mesh_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensNormalVec));
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryVectorField&
|
||||
Foam::sensitivity::getWallFaceSensVecBoundary() const
|
||||
{
|
||||
return wallFaceSensVecPtr_();
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryScalarField&
|
||||
Foam::sensitivity::getWallFaceSensNormalBoundary() const
|
||||
{
|
||||
return wallFaceSensNormalPtr_();
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryVectorField&
|
||||
Foam::sensitivity::getWallFaceSensNormalVecBoundary() const
|
||||
{
|
||||
return wallFaceSensNormalVecPtr_();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -70,85 +70,13 @@ protected:
|
||||
const fvMesh& mesh_;
|
||||
dictionary dict_;
|
||||
|
||||
// Cleaner option to go for a labelHashSet. Kept this way for
|
||||
// compatibility
|
||||
labelList sensitivityPatchIDs_;
|
||||
word adjointSolverName_;
|
||||
word surfaceFieldSuffix_;
|
||||
bool writeAllSurfaceFiles_;
|
||||
|
||||
// autoPtrs for fields holding sensitivities.
|
||||
// Not all of them are required for each case
|
||||
|
||||
// Boundary sensitivities at faces. Shape opt & flow control
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//- Wall face sens w.r.t. (x,y.z)
|
||||
autoPtr<boundaryVectorField> wallFaceSensVecPtr_;
|
||||
|
||||
//- Wall face sens projected to normal
|
||||
autoPtr<boundaryScalarField> wallFaceSensNormalPtr_;
|
||||
|
||||
//- Normal sens as vectors
|
||||
autoPtr<boundaryVectorField> wallFaceSensNormalVecPtr_;
|
||||
|
||||
// Boundary sensitivities at points. Shape opt
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//- Wall point sens w.r.t. (x,y.z)
|
||||
autoPtr<pointBoundaryVectorField> wallPointSensVecPtr_;
|
||||
|
||||
//- Wall point sens projected to normal
|
||||
autoPtr<pointBoundaryScalarField> wallPointSensNormalPtr_;
|
||||
|
||||
//- Normal sens as vectors
|
||||
autoPtr<pointBoundaryVectorField> wallPointSensNormalVecPtr_;
|
||||
|
||||
//field sensitivities. Topology optimisation
|
||||
// Field sensitivities. Topology optimisation
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
autoPtr<volScalarField> fieldSensPtr_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Constructs volField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
void constructAndWriteSensitivityField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
typename GeometricField<Type, fvPatchField, volMesh>::Boundary
|
||||
>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Constructs pointField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
void constructAndWriteSensitivtyPointField
|
||||
(
|
||||
const autoPtr<List<Field<Type>>>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Constructs volField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
constructVolSensitivtyField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
typename GeometricField<Type, fvPatchField, volMesh>::Boundary
|
||||
>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Write face-based sensitivities, if present
|
||||
void writeFaceBasedSens() const;
|
||||
|
||||
//- Write point-based sensitivities, if present
|
||||
void writePointBasedSens() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
@ -171,8 +99,7 @@ public:
|
||||
sensitivity
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const word& adjointSolverName
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
//- Destructor
|
||||
@ -187,12 +114,6 @@ public:
|
||||
//- Read dictionary if changed
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
//- Get patch IDs on which sensitivities are computed
|
||||
const labelList& sensitivityPatchIDs() const;
|
||||
|
||||
//- Overwrite sensitivityPatchIDs
|
||||
void setSensitivityPatchIDs(const labelList& sensPatchIDs);
|
||||
|
||||
//- Compute design variables number. Does nothing in the base
|
||||
// Used to get the correct design variables number when
|
||||
// setSensitivityPatchIDs are not set in the constructor
|
||||
@ -208,37 +129,6 @@ public:
|
||||
// (Bezier, RBF) which do not need to write fields
|
||||
virtual void write(const word& baseName = word::null);
|
||||
|
||||
//- Get wall face sensitivity vectors field
|
||||
tmp<volVectorField> getWallFaceSensVec();
|
||||
|
||||
//- Get wall face sensitivity projected to normal field
|
||||
tmp<volScalarField> getWallFaceSensNormal();
|
||||
|
||||
//- Get wall face normal sens as vectors field
|
||||
tmp<volVectorField> getWallFaceSensNormalVec();
|
||||
|
||||
//- Get wall point sensitivity vectors field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointVectorField> getWallPointSensVec();
|
||||
|
||||
//- Get wall point sensitivity projected to normal field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointScalarField> getWallPointSensNormal();
|
||||
|
||||
//- Get wall point sens as vectors field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointVectorField> getWallPointSensNormalVec();
|
||||
|
||||
//- Get wall face sensitivity vectors field
|
||||
virtual const boundaryVectorField& getWallFaceSensVecBoundary() const;
|
||||
|
||||
//- Get wall face sensitivity projected to normal field
|
||||
virtual const boundaryScalarField&
|
||||
getWallFaceSensNormalBoundary() const;
|
||||
|
||||
//- Get wall face normal sens as vectors field
|
||||
virtual const boundaryVectorField&
|
||||
getWallFaceSensNormalVecBoundary() const;
|
||||
};
|
||||
|
||||
|
||||
@ -248,9 +138,9 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "sensitivityTemplates.C"
|
||||
#endif
|
||||
//#ifdef NoRepository
|
||||
// #include "sensitivityTemplates.C"
|
||||
//#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -0,0 +1,373 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "shapeSensitivitiesBase.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(shapeSensitivitiesBase, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::shapeSensitivitiesBase::writeFaceBasedSens() const
|
||||
{
|
||||
// Wall face sensitivity projected to normal
|
||||
if (wallFaceSensNormalPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<scalar>
|
||||
(
|
||||
wallFaceSensNormalPtr_,
|
||||
"faceSensNormal" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
|
||||
if (writeAllSurfaceFiles_)
|
||||
{
|
||||
// Wall face sensitivity vectors
|
||||
if (wallFaceSensVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<vector>
|
||||
(
|
||||
wallFaceSensVecPtr_,
|
||||
"faceSensVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
|
||||
// Normal sens as vectors
|
||||
if (wallFaceSensNormalVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivityField<vector>
|
||||
(
|
||||
wallFaceSensNormalVecPtr_,
|
||||
"faceSensNormalVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::shapeSensitivitiesBase::writePointBasedSens() const
|
||||
{
|
||||
// Wall point sensitivity projected to normal
|
||||
if (wallPointSensNormalPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<scalar>
|
||||
(
|
||||
wallPointSensNormalPtr_,
|
||||
"pointSensNormal" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
|
||||
// Write point-based sensitivities, if present
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if (writeAllSurfaceFiles_)
|
||||
{
|
||||
// Wall point sensitivity vectors
|
||||
if (wallPointSensVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<vector>
|
||||
(
|
||||
wallPointSensVecPtr_,
|
||||
"pointSensVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
|
||||
// Normal point as vectors
|
||||
if (wallPointSensNormalVecPtr_.valid())
|
||||
{
|
||||
constructAndWriteSensitivtyPointField<vector>
|
||||
(
|
||||
wallPointSensNormalVecPtr_,
|
||||
"pointSensNormalVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::shapeSensitivitiesBase::shapeSensitivitiesBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
meshShape_(mesh),
|
||||
surfaceFieldSuffix_(word::null),
|
||||
writeAllSurfaceFiles_
|
||||
(
|
||||
dict.lookupOrDefault<bool>
|
||||
(
|
||||
"writeAllSurfaceFiles",
|
||||
false
|
||||
)
|
||||
),
|
||||
sensitivityPatchIDs_
|
||||
(
|
||||
mesh.boundaryMesh().patchSet
|
||||
(
|
||||
dict.get<wordRes>("patches", keyType::REGEX_RECURSIVE)
|
||||
)
|
||||
),
|
||||
wallFaceSensVecPtr_(nullptr),
|
||||
wallFaceSensNormalPtr_(nullptr),
|
||||
wallFaceSensNormalVecPtr_(nullptr),
|
||||
|
||||
wallPointSensVecPtr_(nullptr),
|
||||
wallPointSensNormalPtr_(nullptr),
|
||||
wallPointSensNormalVecPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::labelHashSet&
|
||||
Foam::shapeSensitivitiesBase::sensitivityPatchIDs() const
|
||||
{
|
||||
return sensitivityPatchIDs_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::shapeSensitivitiesBase::setSensitivityPatchIDs
|
||||
(
|
||||
const labelHashSet& sensPatchIDs
|
||||
)
|
||||
{
|
||||
sensitivityPatchIDs_ = sensPatchIDs;
|
||||
}
|
||||
|
||||
|
||||
void Foam::shapeSensitivitiesBase::clear()
|
||||
{
|
||||
// Face-based boundary sens
|
||||
if (wallFaceSensVecPtr_.valid())
|
||||
{
|
||||
wallFaceSensVecPtr_() = vector::zero;
|
||||
}
|
||||
if (wallFaceSensNormalVecPtr_.valid())
|
||||
{
|
||||
wallFaceSensNormalVecPtr_() = vector::zero;
|
||||
}
|
||||
if (wallFaceSensNormalPtr_.valid())
|
||||
{
|
||||
wallFaceSensNormalPtr_() = scalar(0);
|
||||
}
|
||||
|
||||
// Point-based boundary sens
|
||||
if (wallPointSensVecPtr_.valid())
|
||||
{
|
||||
for (vectorField& patchSens : wallPointSensVecPtr_())
|
||||
{
|
||||
patchSens = vector::zero;
|
||||
}
|
||||
}
|
||||
if (wallPointSensNormalVecPtr_.valid())
|
||||
{
|
||||
for (vectorField& patchSens : wallPointSensNormalVecPtr_())
|
||||
{
|
||||
patchSens = vector::zero;
|
||||
}
|
||||
}
|
||||
if (wallPointSensNormalPtr_.valid())
|
||||
{
|
||||
for (scalarField& patchSens : wallPointSensNormalPtr_())
|
||||
{
|
||||
patchSens = scalar(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::shapeSensitivitiesBase::write()
|
||||
{
|
||||
writeFaceBasedSens();
|
||||
writePointBasedSens();
|
||||
}
|
||||
|
||||
|
||||
void Foam::shapeSensitivitiesBase::setSuffix(const word& suffix)
|
||||
{
|
||||
surfaceFieldSuffix_ = suffix;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volVectorField>
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensVec()
|
||||
{
|
||||
if (wallFaceSensVecPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<vector>
|
||||
(
|
||||
wallFaceSensVecPtr_,
|
||||
"faceSensVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no faceSensVec boundary field. Returning zero" << endl;
|
||||
|
||||
return
|
||||
tmp<volVectorField>
|
||||
(
|
||||
createZeroFieldPtr<vector>
|
||||
(
|
||||
meshShape_,
|
||||
"faceSensVec" + surfaceFieldSuffix_,
|
||||
dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volScalarField>
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensNormal()
|
||||
{
|
||||
if (wallFaceSensNormalPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<scalar>
|
||||
(
|
||||
wallFaceSensNormalPtr_,
|
||||
"faceSensNormal" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no wallFaceSensNormal boundary field. Returning zero" << endl;
|
||||
|
||||
return
|
||||
tmp<volScalarField>
|
||||
(
|
||||
createZeroFieldPtr<scalar>
|
||||
(
|
||||
meshShape_,
|
||||
"faceSensNormal" + surfaceFieldSuffix_, dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volVectorField>
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensNormalVec()
|
||||
{
|
||||
if (wallFaceSensNormalVecPtr_.valid())
|
||||
{
|
||||
return
|
||||
constructVolSensitivtyField<vector>
|
||||
(
|
||||
wallFaceSensNormalVecPtr_,
|
||||
"faceSensNormalVec" + surfaceFieldSuffix_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< " no wallFaceSensNormalVec boundary field. Returning zero"
|
||||
<< endl;
|
||||
|
||||
return
|
||||
tmp<volVectorField>
|
||||
(
|
||||
createZeroFieldPtr<vector>
|
||||
(
|
||||
meshShape_,
|
||||
"faceSensNormalVec" + surfaceFieldSuffix_,
|
||||
dimless
|
||||
).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointVectorField>
|
||||
Foam::shapeSensitivitiesBase::getWallPointSensVec()
|
||||
{
|
||||
tmp<volVectorField> tWallFaceSensVec = getWallFaceSensVec();
|
||||
volPointInterpolation volPointInter(meshShape_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensVec));
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointScalarField>
|
||||
Foam::shapeSensitivitiesBase::getWallPointSensNormal()
|
||||
{
|
||||
tmp<volScalarField> tWallFaceSensNormal = getWallFaceSensNormal();
|
||||
volPointInterpolation volPointInter(meshShape_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensNormal));
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointVectorField>
|
||||
Foam::shapeSensitivitiesBase::getWallPointSensNormalVec()
|
||||
{
|
||||
tmp<volVectorField> tWallFaceSensNormalVec = getWallFaceSensNormalVec();
|
||||
volPointInterpolation volPointInter(meshShape_);
|
||||
|
||||
return (volPointInter.interpolate(tWallFaceSensNormalVec));
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryVectorField&
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensVecBoundary() const
|
||||
{
|
||||
return wallFaceSensVecPtr_();
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryScalarField&
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensNormalBoundary() const
|
||||
{
|
||||
return wallFaceSensNormalPtr_();
|
||||
}
|
||||
|
||||
|
||||
const Foam::boundaryVectorField&
|
||||
Foam::shapeSensitivitiesBase::getWallFaceSensNormalVecBoundary() const
|
||||
{
|
||||
return wallFaceSensNormalVecPtr_();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,240 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::shapeSensitivitiesBase
|
||||
|
||||
Description
|
||||
Base class supporting shape sensitivity derivatives
|
||||
|
||||
SourceFiles
|
||||
shapeSensitivitiesBase.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef shapeSensitivitiesBase_H
|
||||
#define shapeSensitivitiesBase_H
|
||||
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "dictionary.H"
|
||||
#include "volPointInterpolation.H"
|
||||
|
||||
#include "pointMesh.H"
|
||||
#include "pointPatchField.H"
|
||||
#include "pointPatchFieldsFwd.H"
|
||||
#include "fixedValuePointPatchField.H"
|
||||
#include "boundaryFieldsFwd.H"
|
||||
#include "createZeroField.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class shapeSensitivitiesBase Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class shapeSensitivitiesBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
const fvMesh& meshShape_;
|
||||
word surfaceFieldSuffix_;
|
||||
bool writeAllSurfaceFiles_;
|
||||
|
||||
// Patches on which to compute shape sensitivities
|
||||
labelHashSet sensitivityPatchIDs_;
|
||||
|
||||
// autoPtrs for fields holding sensitivities.
|
||||
// Not all of them are required for each case
|
||||
|
||||
// Boundary sensitivities at faces. Shape opt & flow control
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//- Wall face sens w.r.t. (x,y.z)
|
||||
autoPtr<boundaryVectorField> wallFaceSensVecPtr_;
|
||||
|
||||
//- Wall face sens projected to normal
|
||||
autoPtr<boundaryScalarField> wallFaceSensNormalPtr_;
|
||||
|
||||
//- Normal sens as vectors
|
||||
autoPtr<boundaryVectorField> wallFaceSensNormalVecPtr_;
|
||||
|
||||
// Boundary sensitivities at points. Shape opt
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//- Wall point sens w.r.t. (x,y.z)
|
||||
autoPtr<pointBoundaryVectorField> wallPointSensVecPtr_;
|
||||
|
||||
//- Wall point sens projected to normal
|
||||
autoPtr<pointBoundaryScalarField> wallPointSensNormalPtr_;
|
||||
|
||||
//- Normal sens as vectors
|
||||
autoPtr<pointBoundaryVectorField> wallPointSensNormalVecPtr_;
|
||||
|
||||
//- Constructs volField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
void constructAndWriteSensitivityField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
typename GeometricField<Type, fvPatchField, volMesh>::Boundary
|
||||
>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Constructs pointField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
void constructAndWriteSensitivtyPointField
|
||||
(
|
||||
const autoPtr<List<Field<Type>>>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Constructs volField based on boundaryField and writes it
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
constructVolSensitivtyField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
typename GeometricField<Type, fvPatchField, volMesh>::Boundary
|
||||
>& sensFieldPtr,
|
||||
const word& name
|
||||
) const;
|
||||
|
||||
//- Write face-based sensitivities, if present
|
||||
void writeFaceBasedSens() const;
|
||||
|
||||
//- Write point-based sensitivities, if present
|
||||
void writePointBasedSens() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
shapeSensitivitiesBase(const shapeSensitivitiesBase&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const shapeSensitivitiesBase&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("shapeSensitivitiesBase");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
shapeSensitivitiesBase
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~shapeSensitivitiesBase() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Get patch IDs on which sensitivities are computed
|
||||
const labelHashSet& sensitivityPatchIDs() const;
|
||||
|
||||
//- Overwrite sensitivityPatchIDs
|
||||
void setSensitivityPatchIDs(const labelHashSet& sensPatchIDs);
|
||||
|
||||
//- Zero sensitivity fields and their constituents
|
||||
void clear();
|
||||
|
||||
//- Write sensitivity fields.
|
||||
// If valid, copies boundaryFields to volFields and writes them.
|
||||
void write();
|
||||
|
||||
//- Set suffix
|
||||
void setSuffix(const word& suffix);
|
||||
|
||||
//- Get wall face sensitivity vectors field
|
||||
tmp<volVectorField> getWallFaceSensVec();
|
||||
|
||||
//- Get wall face sensitivity projected to normal field
|
||||
tmp<volScalarField> getWallFaceSensNormal();
|
||||
|
||||
//- Get wall face normal sens as vectors field
|
||||
tmp<volVectorField> getWallFaceSensNormalVec();
|
||||
|
||||
//- Get wall point sensitivity vectors field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointVectorField> getWallPointSensVec();
|
||||
|
||||
//- Get wall point sensitivity projected to normal field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointScalarField> getWallPointSensNormal();
|
||||
|
||||
//- Get wall point sens as vectors field
|
||||
// Uses volPointInterpolation
|
||||
tmp<pointVectorField> getWallPointSensNormalVec();
|
||||
|
||||
//- Get wall face sensitivity vectors field
|
||||
virtual const boundaryVectorField& getWallFaceSensVecBoundary() const;
|
||||
|
||||
//- Get wall face sensitivity projected to normal field
|
||||
virtual const boundaryScalarField&
|
||||
getWallFaceSensNormalBoundary() const;
|
||||
|
||||
//- Get wall face normal sens as vectors field
|
||||
virtual const boundaryVectorField&
|
||||
getWallFaceSensNormalVecBoundary() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "shapeSensitivitiesBaseTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -27,7 +27,7 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "sensitivity.H"
|
||||
#include "shapeSensitivitiesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -37,7 +37,7 @@ namespace Foam
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void sensitivity::constructAndWriteSensitivityField
|
||||
void shapeSensitivitiesBase::constructAndWriteSensitivityField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
@ -51,18 +51,17 @@ void sensitivity::constructAndWriteSensitivityField
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
meshShape_.time().timeName(),
|
||||
meshShape_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
meshShape_,
|
||||
dimensioned<Type>(dimless, Zero)
|
||||
);
|
||||
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
volSensField.boundaryFieldRef()[patchI] = sensFieldPtr()[patchI];
|
||||
}
|
||||
|
||||
@ -71,7 +70,7 @@ void sensitivity::constructAndWriteSensitivityField
|
||||
|
||||
|
||||
template<class Type>
|
||||
void sensitivity::constructAndWriteSensitivtyPointField
|
||||
void shapeSensitivitiesBase::constructAndWriteSensitivtyPointField
|
||||
(
|
||||
const autoPtr<List<Field<Type>>>& sensFieldPtr,
|
||||
const word& name
|
||||
@ -82,20 +81,20 @@ void sensitivity::constructAndWriteSensitivtyPointField
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
meshShape_.time().timeName(),
|
||||
meshShape_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
pointMesh::New(mesh_),
|
||||
pointMesh::New(meshShape_),
|
||||
dimensioned<Type>(dimless, Zero)
|
||||
// fixedValuePointPatchField<Type>::typeName
|
||||
//fixedValuePointPatchField<Type>::typeName
|
||||
);
|
||||
|
||||
forAll(sensitivityPatchIDs_, pI)
|
||||
for (const label patchI : sensitivityPatchIDs_)
|
||||
{
|
||||
const label patchI = sensitivityPatchIDs_[pI];
|
||||
|
||||
// Paraview does not visualise values on fixedValuePointPatchFields
|
||||
// Only option is to store in internalField
|
||||
//pointSensField.boundaryFieldRef()[patchI] == sensFieldPtr()[patchI];
|
||||
pointSensField.boundaryField()[patchI].setInInternalField
|
||||
(
|
||||
@ -110,7 +109,7 @@ void sensitivity::constructAndWriteSensitivtyPointField
|
||||
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
sensitivity::constructVolSensitivtyField
|
||||
shapeSensitivitiesBase::constructVolSensitivtyField
|
||||
(
|
||||
const autoPtr
|
||||
<
|
||||
@ -126,12 +125,12 @@ sensitivity::constructVolSensitivtyField
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
meshShape_.time().timeName(),
|
||||
meshShape_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh_,
|
||||
meshShape_,
|
||||
pTraits<Type>::zero
|
||||
)
|
||||
);
|
||||
@ -0,0 +1,79 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "ArmijoConditions.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(ArmijoConditions, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
lineSearch,
|
||||
ArmijoConditions,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::ArmijoConditions::ArmijoConditions
|
||||
(
|
||||
const dictionary& dict,
|
||||
const Time& time
|
||||
)
|
||||
:
|
||||
lineSearch(dict, time),
|
||||
c1_(coeffsDict().lookupOrDefault<scalar>("c1", 1.e-4))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::ArmijoConditions::converged()
|
||||
{
|
||||
Info<< "New merit function value " << newMeritValue_ << endl;
|
||||
Info<< "Old merit function value " << oldMeritValue_ << endl;
|
||||
Info<< "Extrapolated merit function value "
|
||||
<< oldMeritValue_ + c1_*step_*directionalDeriv_ << endl;
|
||||
return newMeritValue_ < oldMeritValue_ + c1_*step_*directionalDeriv_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::ArmijoConditions::updateStep()
|
||||
{
|
||||
stepUpdate_->updateStep(step_);
|
||||
Info<< "Using step " << step_ << endl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::ArmijoConditions
|
||||
|
||||
Description
|
||||
Class satisfying the Armijo line search conditions
|
||||
|
||||
SourceFiles
|
||||
ArmijoConditions.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ArmijoConditions_H
|
||||
#define ArmijoConditions_H
|
||||
|
||||
#include "lineSearch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ArmijoConditions Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class ArmijoConditions
|
||||
:
|
||||
public lineSearch
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Multiplier of the merit function reduction computed using
|
||||
//- a first-order Taylor expansion
|
||||
scalar c1_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
ArmijoConditions(const ArmijoConditions&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const ArmijoConditions&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("ArmijoConditions");
|
||||
|
||||
|
||||
// Declare run-time constructor selection table
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
ArmijoConditions,
|
||||
dictionary,
|
||||
(
|
||||
const dictionary& dict,
|
||||
const Time& time
|
||||
),
|
||||
(dict)
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
ArmijoConditions(const dictionary& dict, const Time& time);
|
||||
|
||||
|
||||
// Destructor
|
||||
virtual ~ArmijoConditions() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//Return the correction of the design variables
|
||||
virtual bool converged();
|
||||
|
||||
//Update step in given direction
|
||||
virtual void updateStep();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,19 +30,26 @@ License
|
||||
#include "lineSearch.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(lineSearch, 0);
|
||||
defineRunTimeSelectionTable(lineSearch, dictionary);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(lineSearch, 0);
|
||||
defineRunTimeSelectionTable(lineSearch, dictionary);
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
const Foam::dictionary& Foam::lineSearch::coeffsDict()
|
||||
{
|
||||
return dict_.optionalSubDict(type() + "Coeffs");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
lineSearch::lineSearch(const dictionary& dict, const Time& time)
|
||||
Foam::lineSearch::lineSearch(const dictionary& dict, const Time& time)
|
||||
:
|
||||
dict_(dict),
|
||||
lineSearchDict_
|
||||
@ -66,11 +73,11 @@ lineSearch::lineSearch(const dictionary& dict, const Time& time)
|
||||
(
|
||||
lineSearchDict_.lookupOrDefault<scalar>("prevMeritDeriv", Zero)
|
||||
),
|
||||
initialStep_(dict.lookupOrDefault<scalar>("initialStep", 1)),
|
||||
initialStep_(dict.lookupOrDefault<scalar>("initialStep", 1.)),
|
||||
minStep_(dict.lookupOrDefault<scalar>("minStep", 0.3)),
|
||||
step_(Zero),
|
||||
iter_(lineSearchDict_.lookupOrDefault<label>("iter", 0)),
|
||||
maxIters_(dict.lookupOrDefault<scalar>("maxIters", 10)),
|
||||
maxIters_(dict.lookupOrDefault<label>("maxIters", 4)),
|
||||
extrapolateInitialStep_
|
||||
(
|
||||
dict.lookupOrDefault<bool>
|
||||
@ -85,7 +92,7 @@ lineSearch::lineSearch(const dictionary& dict, const Time& time)
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
autoPtr<lineSearch> lineSearch::New
|
||||
Foam::autoPtr<Foam::lineSearch> Foam::lineSearch::New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const Time& time
|
||||
@ -93,7 +100,7 @@ autoPtr<lineSearch> lineSearch::New
|
||||
{
|
||||
autoPtr<lineSearch> lineSrch(nullptr);
|
||||
|
||||
const word modelType(dict.getOrDefault<word>("lineSearchType", "none"));
|
||||
const word modelType(dict.getOrDefault<word>("type", "none"));
|
||||
|
||||
Info<< "lineSearch type : " << modelType << endl;
|
||||
|
||||
@ -126,34 +133,34 @@ autoPtr<lineSearch> lineSearch::New
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void lineSearch::setDeriv(const scalar deriv)
|
||||
void Foam::lineSearch::setDeriv(const scalar deriv)
|
||||
{
|
||||
directionalDeriv_ = deriv;
|
||||
stepUpdate_->setDeriv(deriv);
|
||||
}
|
||||
|
||||
|
||||
void lineSearch::setDirection(const scalarField& direction)
|
||||
void Foam::lineSearch::setDirection(const scalarField& direction)
|
||||
{
|
||||
direction_ = direction;
|
||||
}
|
||||
|
||||
|
||||
void lineSearch::setNewMeritValue(const scalar value)
|
||||
void Foam::lineSearch::setNewMeritValue(const scalar value)
|
||||
{
|
||||
newMeritValue_ = value;
|
||||
stepUpdate_->setNewMeritValue(value);
|
||||
}
|
||||
|
||||
|
||||
void lineSearch::setOldMeritValue(const scalar value)
|
||||
void Foam::lineSearch::setOldMeritValue(const scalar value)
|
||||
{
|
||||
oldMeritValue_ = value;
|
||||
stepUpdate_->setOldMeritValue(value);
|
||||
}
|
||||
|
||||
|
||||
void lineSearch::reset()
|
||||
void Foam::lineSearch::reset()
|
||||
{
|
||||
if (extrapolateInitialStep_ && iter_ != 0)
|
||||
{
|
||||
@ -173,44 +180,46 @@ void lineSearch::reset()
|
||||
}
|
||||
|
||||
|
||||
label lineSearch::maxIters() const
|
||||
Foam::label Foam::lineSearch::maxIters() const
|
||||
{
|
||||
return maxIters_;
|
||||
}
|
||||
|
||||
|
||||
scalar lineSearch::step() const
|
||||
Foam::scalar Foam::lineSearch::step() const
|
||||
{
|
||||
return step_;
|
||||
}
|
||||
|
||||
|
||||
void lineSearch::updateStep(const scalar newStep)
|
||||
void Foam::lineSearch::updateStep(const scalar newStep)
|
||||
{
|
||||
step_ = newStep;
|
||||
}
|
||||
|
||||
|
||||
lineSearch& lineSearch::operator++()
|
||||
Foam::lineSearch& Foam::lineSearch::operator++()
|
||||
{
|
||||
iter_++;
|
||||
prevMeritDeriv_ = directionalDeriv_;
|
||||
lineSearchDict_.add<scalar>("prevMeritDeriv_", prevMeritDeriv_, true);
|
||||
lineSearchDict_.add<scalar>("prevMeritDeriv", prevMeritDeriv_, true);
|
||||
lineSearchDict_.add<label>("iter", iter_, true);
|
||||
lineSearchDict_.regIOobject::write();
|
||||
lineSearchDict_.regIOobject::writeObject
|
||||
(
|
||||
IOstream::ASCII,
|
||||
IOstream::currentVersion,
|
||||
IOstream::UNCOMPRESSED,
|
||||
true
|
||||
);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
lineSearch& lineSearch::operator++(int)
|
||||
Foam::lineSearch& Foam::lineSearch::operator++(int)
|
||||
{
|
||||
return operator++();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -30,7 +30,7 @@ Class
|
||||
Foam::lineSearch
|
||||
|
||||
Description
|
||||
Abstract base class for optimisation methods
|
||||
Abstract base class for line search methods
|
||||
|
||||
SourceFiles
|
||||
lineSearch.C
|
||||
@ -51,7 +51,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class lineSearch Declaration
|
||||
Class lineSearch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class lineSearch
|
||||
@ -60,9 +60,16 @@ protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Subdict within updateMethod
|
||||
const dictionary dict_;
|
||||
|
||||
//- IOdictionary under time/uniform for continuation
|
||||
IOdictionary lineSearchDict_;
|
||||
|
||||
//- Directional derivative of the merit function
|
||||
scalar directionalDeriv_;
|
||||
|
||||
//- Update direction
|
||||
scalarField direction_;
|
||||
|
||||
//- Old merit value from this opt cycle
|
||||
@ -73,15 +80,37 @@ protected:
|
||||
|
||||
//- Merit directional deriv from the previous opt cycle
|
||||
scalar prevMeritDeriv_;
|
||||
|
||||
//- Correction multiplier at the first step of line search
|
||||
scalar initialStep_;
|
||||
|
||||
//- Minimum allowed correction multiplier
|
||||
scalar minStep_;
|
||||
|
||||
//- Correction multiplier
|
||||
scalar step_;
|
||||
|
||||
//- Inner line search iteration
|
||||
label iter_;
|
||||
|
||||
//- Maximum line search iterations
|
||||
label maxIters_;
|
||||
|
||||
//- Whether to extrapolate the correction multiplier for
|
||||
//- this optimisation cycle based on the previous ones.
|
||||
// Usefull for non-quasi Newton methods
|
||||
bool extrapolateInitialStep_;
|
||||
|
||||
//- Mechanism to update method if line search conditions are not set
|
||||
autoPtr<stepUpdate> stepUpdate_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Optional coeffs dict
|
||||
const dictionary& coeffsDict();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "bisection.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(bisection, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
stepUpdate,
|
||||
bisection,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::bisection::bisection(const dictionary& dict)
|
||||
:
|
||||
stepUpdate(dict),
|
||||
ratio_(coeffsDict().lookupOrDefault<scalar>("ratio", 0.7))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::bisection::updateStep(scalar& step)
|
||||
{
|
||||
step *= ratio_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,107 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::bisection
|
||||
|
||||
Description
|
||||
Reduces step by a given ratio
|
||||
|
||||
SourceFiles
|
||||
bisection.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef bisection_H
|
||||
#define bisection_H
|
||||
|
||||
#include "stepUpdate.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class bisection Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class bisection
|
||||
:
|
||||
public stepUpdate
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
scalar ratio_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
bisection(const bisection&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const bisection&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("bisection");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
bisection(const dictionary& dict);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~bisection() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Update step in given direction
|
||||
virtual void updateStep(scalar& step);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "quadratic.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(quadratic, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
stepUpdate,
|
||||
quadratic,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::quadratic::quadratic(const dictionary& dict)
|
||||
:
|
||||
stepUpdate(dict),
|
||||
minRatio_(coeffsDict().lookupOrDefault<scalar>("minRatio", 0.1)),
|
||||
firstMeritValue_(Zero),
|
||||
secondMeritValue_(Zero),
|
||||
meritDerivative_(Zero)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::quadratic::updateStep(scalar& step)
|
||||
{
|
||||
Info<< "f(0)" << firstMeritValue_ << endl;
|
||||
Info<< "f(a0)" << secondMeritValue_ << endl;
|
||||
Info<< "df(0)" << meritDerivative_ << endl;
|
||||
Info<< "a0 " << step << endl;
|
||||
scalar denom = 1./(step*step);
|
||||
scalar coeff1 =
|
||||
(secondMeritValue_ - meritDerivative_*step - firstMeritValue_)
|
||||
* denom;
|
||||
scalar tempStep = - 0.5*meritDerivative_/coeff1;
|
||||
if (tempStep < minRatio_*step)
|
||||
{
|
||||
step = minRatio_*step;
|
||||
}
|
||||
else
|
||||
{
|
||||
step = tempStep;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::quadratic::setDeriv(const scalar deriv)
|
||||
{
|
||||
meritDerivative_ = deriv;
|
||||
}
|
||||
|
||||
|
||||
void Foam::quadratic::setNewMeritValue(const scalar value)
|
||||
{
|
||||
secondMeritValue_ = value;
|
||||
}
|
||||
|
||||
|
||||
void Foam::quadratic::setOldMeritValue(const scalar value)
|
||||
{
|
||||
firstMeritValue_ = value;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::quadratic
|
||||
|
||||
Description
|
||||
Fits a quadratic polynomial of the merit function as a fuction of step
|
||||
and finds the "optimal" value
|
||||
|
||||
SourceFiles
|
||||
quadratic.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef quadratic_H
|
||||
#define quadratic_H
|
||||
|
||||
#include "stepUpdate.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class quadratic Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class quadratic
|
||||
:
|
||||
public stepUpdate
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
scalar minRatio_;
|
||||
scalar firstMeritValue_;
|
||||
scalar secondMeritValue_;
|
||||
scalar meritDerivative_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
quadratic(const quadratic&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const quadratic&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("quadratic");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
quadratic(const dictionary& dict);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~quadratic() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update step in given direction
|
||||
virtual void updateStep(scalar& step);
|
||||
|
||||
//- Set objective derivative
|
||||
virtual void setDeriv(const scalar deriv);
|
||||
|
||||
//- Set new merit value
|
||||
virtual void setNewMeritValue(const scalar value);
|
||||
|
||||
//- Set old merit value
|
||||
virtual void setOldMeritValue(const scalar value);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -29,19 +29,26 @@ License
|
||||
|
||||
#include "stepUpdate.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(stepUpdate, 0);
|
||||
defineRunTimeSelectionTable(stepUpdate, dictionary);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(stepUpdate, 0);
|
||||
defineRunTimeSelectionTable(stepUpdate, dictionary);
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
const Foam::dictionary& Foam::stepUpdate::coeffsDict()
|
||||
{
|
||||
return dict_.optionalSubDict(type() + "Coeffs");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
stepUpdate::stepUpdate(const dictionary& dict)
|
||||
Foam::stepUpdate::stepUpdate(const dictionary& dict)
|
||||
:
|
||||
dict_(dict)
|
||||
{}
|
||||
@ -49,14 +56,14 @@ stepUpdate::stepUpdate(const dictionary& dict)
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
|
||||
|
||||
autoPtr<stepUpdate> stepUpdate::New(const dictionary& dict)
|
||||
Foam::autoPtr<Foam::stepUpdate> Foam::stepUpdate::New(const dictionary& dict)
|
||||
{
|
||||
const word modelType =
|
||||
const word type =
|
||||
dict.lookupOrDefault<word>("stepUpdateType", "bisection");
|
||||
|
||||
Info<< "stepUpdate type : " << modelType << endl;
|
||||
Info<< "stepUpdate type : " << type << endl;
|
||||
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(type);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
@ -64,7 +71,7 @@ autoPtr<stepUpdate> stepUpdate::New(const dictionary& dict)
|
||||
(
|
||||
dict,
|
||||
"stepUpdate",
|
||||
modelType,
|
||||
type,
|
||||
*dictionaryConstructorTablePtr_
|
||||
) << exit(FatalIOError);
|
||||
}
|
||||
@ -75,32 +82,22 @@ autoPtr<stepUpdate> stepUpdate::New(const dictionary& dict)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void stepUpdate::setDeriv(const scalar deriv)
|
||||
void Foam::stepUpdate::setDeriv(const scalar deriv)
|
||||
{
|
||||
// Does nothing in base
|
||||
}
|
||||
|
||||
|
||||
void stepUpdate::setNewMeritValue(const scalar value)
|
||||
void Foam::stepUpdate::setNewMeritValue(const scalar value)
|
||||
{
|
||||
// Does nothing in base
|
||||
}
|
||||
|
||||
|
||||
void stepUpdate::setOldMeritValue(const scalar value)
|
||||
void Foam::stepUpdate::setOldMeritValue(const scalar value)
|
||||
{
|
||||
// Does nothing in base
|
||||
}
|
||||
|
||||
|
||||
void stepUpdate::setInitialStep(const scalar value)
|
||||
{
|
||||
// Does nothing in base
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -30,7 +30,7 @@ Class
|
||||
Foam::stepUpdate
|
||||
|
||||
Description
|
||||
Abstract base class for optimisation methods
|
||||
Abstract base class for step update methods used in line search
|
||||
|
||||
SourceFiles
|
||||
stepUpdate.C
|
||||
@ -49,7 +49,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class stepUpdate Declaration
|
||||
Class stepUpdate Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class stepUpdate
|
||||
@ -61,6 +61,12 @@ protected:
|
||||
const dictionary dict_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Optional coeffs dict
|
||||
const dictionary& coeffsDict();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
@ -116,14 +122,11 @@ public:
|
||||
//- Set objective derivative
|
||||
virtual void setDeriv(const scalar deriv);
|
||||
|
||||
//- Set new objective value
|
||||
//- Set new merit value
|
||||
virtual void setNewMeritValue(const scalar value);
|
||||
|
||||
//- Set old objective value
|
||||
//- Set old merit value
|
||||
virtual void setOldMeritValue(const scalar value);
|
||||
|
||||
//- Set old objective value
|
||||
virtual void setInitialStep(const scalar value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,207 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "optMeshMovement.H"
|
||||
#include "cellQuality.H"
|
||||
#include "createZeroField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(optMeshMovement, 0);
|
||||
defineRunTimeSelectionTable(optMeshMovement, dictionary);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::scalar Foam::optMeshMovement::getMaxAllowedDisplacement() const
|
||||
{
|
||||
if (maxAllowedDisplacement_.empty())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "maxAllowedDisplacement requested but not set" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return maxAllowedDisplacement_();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optMeshMovement::optMeshMovement
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
maxAllowedDisplacement_(nullptr),
|
||||
mesh_(mesh),
|
||||
dict_(dict),
|
||||
correction_(0),
|
||||
patchIDs_(patchIDs),
|
||||
pointsInit_(mesh.points()),
|
||||
displMethodPtr_(displacementMethod::New(mesh_, patchIDs_)),
|
||||
writeMeshQualityMetrics_
|
||||
(
|
||||
dict.lookupOrDefault("writeMeshQualityMetrics", false)
|
||||
)
|
||||
{
|
||||
//- Set maxAllowedDisplacement if provided
|
||||
if (dict.found("maxAllowedDisplacement"))
|
||||
{
|
||||
maxAllowedDisplacement_.reset
|
||||
(
|
||||
new scalar(dict.get<scalar>("maxAllowedDisplacement"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::optMeshMovement> Foam::optMeshMovement::New
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
{
|
||||
const word modelType(dict.get<word>("type"));
|
||||
|
||||
Info<< "optMeshMovement type : " << modelType << endl;
|
||||
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalIOErrorInLookup
|
||||
(
|
||||
dict,
|
||||
"type",
|
||||
modelType,
|
||||
*dictionaryConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<optMeshMovement>(cstrIter()(mesh, dict, patchIDs));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovement::setCorrection(const scalarField& correction)
|
||||
{
|
||||
correction_ = correction;
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovement::moveMesh()
|
||||
{
|
||||
// Move mesh
|
||||
displMethodPtr_->update();
|
||||
|
||||
// Check mesh quality
|
||||
mesh_.checkMesh(true);
|
||||
|
||||
// If needed, plot mesh quality metrics
|
||||
writeMeshQualityMetrics();
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::displacementMethod>&
|
||||
Foam::optMeshMovement::returnDisplacementMethod()
|
||||
{
|
||||
return displMethodPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelList& Foam::optMeshMovement::getPatchIDs()
|
||||
{
|
||||
return patchIDs_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovement::writeMeshQualityMetrics()
|
||||
{
|
||||
if (writeMeshQualityMetrics_)
|
||||
{
|
||||
cellQuality cellQualityEngine(mesh_);
|
||||
tmp<scalarField> cellNonOrtho = cellQualityEngine.nonOrthogonality();
|
||||
tmp<scalarField> cellSkewness = cellQualityEngine.skewness();
|
||||
Info<< "Average, Max cell non - orthogonality " << gAverage(cellNonOrtho())
|
||||
<< " " << gMax(cellNonOrtho()) << endl;
|
||||
Info<< "Average, Max cell skewness " << gAverage(cellSkewness())
|
||||
<< " " << gMax(cellSkewness()) << endl;
|
||||
autoPtr<volScalarField> nonOrthoPtr
|
||||
(
|
||||
createZeroFieldPtr<scalar>(mesh_, "nonOrtho", dimless)
|
||||
);
|
||||
autoPtr<volScalarField> skewnessPtr
|
||||
(
|
||||
createZeroFieldPtr<scalar>(mesh_, "skewness", dimless)
|
||||
);
|
||||
nonOrthoPtr().primitiveFieldRef() = cellNonOrtho();
|
||||
skewnessPtr().primitiveFieldRef() = cellSkewness();
|
||||
nonOrthoPtr().write();
|
||||
skewnessPtr().write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovement::storeDesignVariables()
|
||||
{
|
||||
pointsInit_ = mesh_.points();
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovement::resetDesignVariables()
|
||||
{
|
||||
Info<< "optMeshMovement:: reseting mesh points" << endl;
|
||||
mesh_.movePoints(pointsInit_);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::optMeshMovement::maxAllowedDisplacementSet() const
|
||||
{
|
||||
return maxAllowedDisplacement_.valid();
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::optMeshMovement::getActiveDesignVariables() const
|
||||
{
|
||||
NotImplemented;
|
||||
return labelList(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,201 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::optMeshMovement
|
||||
|
||||
Description
|
||||
Abstract base class for translating an update of the design variables
|
||||
into mesh movement
|
||||
|
||||
SourceFiles
|
||||
optMeshMovement.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef optMeshMovement_H
|
||||
#define optMeshMovement_H
|
||||
|
||||
#include "displacementMethod.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class optMeshMovement Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class optMeshMovement
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Max allowed boundary displacement for the first optimisation cycle
|
||||
autoPtr<scalar> maxAllowedDisplacement_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
optMeshMovement(const optMeshMovement&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const optMeshMovement&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
fvMesh& mesh_;
|
||||
const dictionary& dict_;
|
||||
|
||||
//- Correction of design variables
|
||||
scalarField correction_;
|
||||
|
||||
//- IDs of patches to be moved
|
||||
labelList patchIDs_;
|
||||
|
||||
//- Fall back points in case line-search is used
|
||||
vectorField pointsInit_;
|
||||
|
||||
//- Mesh movement engine and interface for applying mesh movement
|
||||
//- boundary conditions
|
||||
autoPtr<displacementMethod> displMethodPtr_;
|
||||
|
||||
//- Whether to write the mesh quality metrics to files each time the
|
||||
//- mesh is updated
|
||||
bool writeMeshQualityMetrics_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Get maxAllowedDisplacement, is set
|
||||
scalar getMaxAllowedDisplacement() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("optMeshMovement");
|
||||
|
||||
|
||||
// Declare run-time constructor selection table
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
optMeshMovement,
|
||||
dictionary,
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
),
|
||||
(
|
||||
mesh,
|
||||
dict,
|
||||
patchIDs
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
optMeshMovement
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
static autoPtr<optMeshMovement> New
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~optMeshMovement() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set design variable correction
|
||||
void setCorrection(const scalarField& correction);
|
||||
|
||||
//- Calculates mesh movemnt based on the correction of the design
|
||||
//- variables
|
||||
virtual void moveMesh();
|
||||
|
||||
//- Return displacementMethod
|
||||
autoPtr<displacementMethod>& returnDisplacementMethod();
|
||||
|
||||
//- Return patchIDs
|
||||
const labelList& getPatchIDs();
|
||||
|
||||
//- Write mesh quality metrics
|
||||
void writeMeshQualityMetrics();
|
||||
|
||||
//- Store design variables and mesh, to act as the starting point of
|
||||
//- line search
|
||||
virtual void storeDesignVariables();
|
||||
|
||||
//- Reset to starting point of line search
|
||||
virtual void resetDesignVariables();
|
||||
|
||||
//- Compute eta value based on max displacement
|
||||
virtual scalar computeEta(const scalarField& correction) = 0;
|
||||
|
||||
//- Whether maxAllowedDisplacement has been set
|
||||
bool maxAllowedDisplacementSet() const;
|
||||
|
||||
//- Return active design variables.
|
||||
// Implemented only for certain parametetisations
|
||||
virtual labelList getActiveDesignVariables() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,159 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "optMeshMovementBezier.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(optMeshMovementBezier, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
optMeshMovement,
|
||||
optMeshMovementBezier,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementBezier::computeBoundaryMovement
|
||||
(
|
||||
const scalarField& correction
|
||||
)
|
||||
{
|
||||
// Re-initialize movement to zero
|
||||
dx_.primitiveFieldRef() = vector::zero;
|
||||
|
||||
// Compute boundary mesh movement using derivatives of the control points
|
||||
// and parameterization information
|
||||
const label nBezier = Bezier_.nBezier();
|
||||
const boolList& confineXmovement = Bezier_.confineXmovement();
|
||||
const boolList& confineYmovement = Bezier_.confineYmovement();
|
||||
const boolList& confineZmovement = Bezier_.confineZmovement();
|
||||
vectorField actualMovement(nBezier, vector::zero);
|
||||
for (label iCP = 0; iCP < nBezier; iCP++)
|
||||
{
|
||||
// Confine x movement
|
||||
if (!confineXmovement[iCP])
|
||||
{
|
||||
actualMovement[iCP].x() = correction[iCP];
|
||||
}
|
||||
// Confine y movement
|
||||
if (!confineYmovement[iCP])
|
||||
{
|
||||
actualMovement[iCP].y() = correction[iCP + nBezier];
|
||||
}
|
||||
// Confine z movement
|
||||
if (!confineZmovement[iCP])
|
||||
{
|
||||
actualMovement[iCP].z() = correction[iCP + 2*nBezier];
|
||||
}
|
||||
dx_ += Bezier_.dxidXj()[iCP] & actualMovement[iCP];
|
||||
}
|
||||
|
||||
// Add to cumulative control point change (wrong in the first optimisation
|
||||
// cycle if initial eta not set)
|
||||
cumulativeChange_ += actualMovement;
|
||||
Info<< "Cumulative control point change " << cumulativeChange_ << endl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optMeshMovementBezier::optMeshMovementBezier
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
optMeshMovement(mesh, dict, patchIDs),
|
||||
Bezier_(mesh, mesh.lookupObject<IOdictionary>("optimisationDict")),
|
||||
dx_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dx",
|
||||
mesh_.time().timeName(),
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
pointMesh::New(mesh),
|
||||
dimensionedVector(dimless, Zero)
|
||||
),
|
||||
cumulativeChange_(Bezier_.nBezier(), vector::zero)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementBezier::moveMesh()
|
||||
{
|
||||
// Update the boundary movement
|
||||
computeBoundaryMovement(correction_);
|
||||
|
||||
// Set boundary movement of motion solver
|
||||
displMethodPtr_->setMotionField(dx_);
|
||||
|
||||
// Move the mesh and check quality
|
||||
optMeshMovement::moveMesh();
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar
|
||||
Foam::optMeshMovementBezier::computeEta(const scalarField& correction)
|
||||
{
|
||||
// Set unscaled correction
|
||||
computeBoundaryMovement(correction);
|
||||
|
||||
// Get maximum boundary movement
|
||||
const scalar maxDisplacement = gMax(mag(dx_.primitiveField()));
|
||||
|
||||
// Compute eta value
|
||||
Info<< "maxAllowedDisplacement/maxDisplacement \t"
|
||||
<< getMaxAllowedDisplacement() << "/" << maxDisplacement << endl;
|
||||
const scalar eta = getMaxAllowedDisplacement()/maxDisplacement;
|
||||
Info<< "Setting eta value to " << eta << endl;
|
||||
|
||||
return eta;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::optMeshMovementBezier::getActiveDesignVariables() const
|
||||
{
|
||||
return Bezier_.getActiveDesignVariables();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::optMeshMovementBezier
|
||||
|
||||
Description
|
||||
Converts NURBS control points update to actual mesh movement
|
||||
|
||||
SourceFiles
|
||||
optMeshMovementBezier.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef optMeshMovementBezier_H
|
||||
#define optMeshMovementBezier_H
|
||||
|
||||
#include "optMeshMovement.H"
|
||||
#include "Bezier.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class optMeshMovementBezier Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class optMeshMovementBezier
|
||||
:
|
||||
public optMeshMovement
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Parameterization based on NURBS curves
|
||||
Bezier Bezier_;
|
||||
|
||||
//- Boundary movement due to change of NURBS control points
|
||||
pointVectorField dx_;
|
||||
|
||||
//- Cumulative change of control points
|
||||
vectorField cumulativeChange_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
void computeBoundaryMovement(const scalarField& correction);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
optMeshMovementBezier(const optMeshMovementBezier&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const optMeshMovementBezier&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("Bezier");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
optMeshMovementBezier
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~optMeshMovementBezier() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculates surface mesh movement
|
||||
void moveMesh();
|
||||
|
||||
//- Compute eta value based on max displacement
|
||||
virtual scalar computeEta(const scalarField& correction);
|
||||
|
||||
//- Return active design variables
|
||||
virtual labelList getActiveDesignVariables() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "optMeshMovementNULL.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(optMeshMovementNULL, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
optMeshMovement,
|
||||
optMeshMovementNULL,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optMeshMovementNULL::optMeshMovementNULL
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
optMeshMovement(mesh, dict, patchIDs)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementNULL::moveMesh()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar
|
||||
Foam::optMeshMovementNULL::computeEta(const scalarField& correction)
|
||||
{
|
||||
return scalar(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,107 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::optMeshMovementNULL
|
||||
|
||||
Description
|
||||
A dummy optMeshMovement object
|
||||
|
||||
SourceFiles
|
||||
optMeshMovementNULL.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef optMeshMovementNULL_H
|
||||
#define optMeshMovementNULL_H
|
||||
|
||||
#include "optMeshMovement.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class optMeshMovementNULL Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class optMeshMovementNULL
|
||||
:
|
||||
public optMeshMovement
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
optMeshMovementNULL(const optMeshMovementNULL&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const optMeshMovementNULL&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("none");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
optMeshMovementNULL
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~optMeshMovementNULL() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculates surface mesh movement
|
||||
void moveMesh();
|
||||
|
||||
//- Compute eta value based on max displacement
|
||||
virtual scalar computeEta(const scalarField& correction);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "optMeshMovementVolumetricBSplines.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(optMeshMovementVolumetricBSplines, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
optMeshMovement,
|
||||
optMeshMovementVolumetricBSplines,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::vectorField Foam::optMeshMovementVolumetricBSplines::controlPointMovement
|
||||
(
|
||||
const scalarField& correction
|
||||
)
|
||||
{
|
||||
const label nControlPoints(correction.size()/3);
|
||||
vectorField cpMovement(nControlPoints, vector::zero);
|
||||
|
||||
for (label iCP = 0; iCP < nControlPoints; ++iCP)
|
||||
{
|
||||
cpMovement[iCP].x() = correction[3*iCP];
|
||||
cpMovement[iCP].y() = correction[3*iCP + 1];
|
||||
cpMovement[iCP].z() = correction[3*iCP + 2];
|
||||
}
|
||||
displMethodPtr_->boundControlField(cpMovement);
|
||||
|
||||
return cpMovement;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optMeshMovementVolumetricBSplines::optMeshMovementVolumetricBSplines
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
optMeshMovement(mesh, dict, patchIDs),
|
||||
volBSplinesBase_
|
||||
(
|
||||
const_cast<volBSplinesBase&>(volBSplinesBase::New(mesh))
|
||||
),
|
||||
cpsInit_(volBSplinesBase_.getNumberOfBoxes())
|
||||
{
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
|
||||
forAll(boxes, boxI)
|
||||
{
|
||||
cpsInit_[boxI].setSize
|
||||
(
|
||||
boxes[boxI].getControlPoints().size()
|
||||
);
|
||||
cpsInit_[boxI] = boxes[boxI].getControlPoints();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementVolumetricBSplines::moveMesh()
|
||||
{
|
||||
// Get controlPoint movement from correction
|
||||
vectorField cpMovement = controlPointMovement(correction_);
|
||||
|
||||
// Set movement of the B-Splines control points
|
||||
displMethodPtr_->setControlField(cpMovement);
|
||||
|
||||
// Move the mesh and check quality
|
||||
optMeshMovement::moveMesh();
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovementVolumetricBSplines::storeDesignVariables()
|
||||
{
|
||||
optMeshMovement::storeDesignVariables();
|
||||
const PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxes();
|
||||
forAll(boxes, boxI)
|
||||
{
|
||||
cpsInit_[boxI] = boxes[boxI].getControlPoints();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::optMeshMovementVolumetricBSplines::resetDesignVariables()
|
||||
{
|
||||
// Reset mesh points
|
||||
optMeshMovement::resetDesignVariables();
|
||||
|
||||
DebugInfo
|
||||
<< "optMeshMovementVolumetricBSplines:: reseting control points"
|
||||
<< endl;
|
||||
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, boxI)
|
||||
{
|
||||
boxes[boxI].setControlPoints(cpsInit_[boxI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::optMeshMovementVolumetricBSplines::computeEta
|
||||
(
|
||||
const scalarField& correction
|
||||
)
|
||||
{
|
||||
const vectorField cpMovement(controlPointMovement(correction));
|
||||
const scalar maxDisplacement
|
||||
(
|
||||
volBSplinesBase_.computeMaxBoundaryDisplacement
|
||||
(
|
||||
cpMovement,
|
||||
patchIDs_
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "maxAllowedDisplacement/maxDisplacement of boundary\t"
|
||||
<< getMaxAllowedDisplacement() << "/" << maxDisplacement << endl;
|
||||
scalar eta = getMaxAllowedDisplacement() / maxDisplacement;
|
||||
Info<< "Setting eta value to " << eta << endl;
|
||||
|
||||
return eta;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList
|
||||
Foam::optMeshMovementVolumetricBSplines::getActiveDesignVariables() const
|
||||
{
|
||||
return volBSplinesBase_.getActiveDesignVariables();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::optMeshMovementVolumetricBSplines
|
||||
|
||||
Description
|
||||
Converts NURBS volume control points update to actual mesh movement.
|
||||
Internal points are also moved based on the movement of the control points
|
||||
|
||||
SourceFiles
|
||||
optMeshMovementVolumetricBSplines.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef optMeshMovementVolumetricBSplines_H
|
||||
#define optMeshMovementVolumetricBSplines_H
|
||||
|
||||
#include "optMeshMovement.H"
|
||||
#include "volBSplinesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class optMeshMovementVolumetricBSplines Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class optMeshMovementVolumetricBSplines
|
||||
:
|
||||
public optMeshMovement
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to underlaying volumetric B-Splines morpher
|
||||
volBSplinesBase& volBSplinesBase_;
|
||||
|
||||
//- Backup of initial control points. Useful for line-search
|
||||
List<vectorField> cpsInit_;
|
||||
|
||||
|
||||
// Protected Fuctions
|
||||
|
||||
vectorField controlPointMovement(const scalarField& correction);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
optMeshMovementVolumetricBSplines
|
||||
(
|
||||
const optMeshMovementVolumetricBSplines&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const optMeshMovementVolumetricBSplines&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplines");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
optMeshMovementVolumetricBSplines
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~optMeshMovementVolumetricBSplines() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculates surface mesh movement
|
||||
void moveMesh();
|
||||
|
||||
//- Store design variables and mesh, to act as the starting point of
|
||||
//- line search
|
||||
virtual void storeDesignVariables();
|
||||
|
||||
//- Reset to starting point of line search
|
||||
virtual void resetDesignVariables();
|
||||
|
||||
//- Compute eta value based on max displacement
|
||||
virtual scalar computeEta(const scalarField& correction);
|
||||
|
||||
//- Return active design variables
|
||||
virtual labelList getActiveDesignVariables() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,190 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "optMeshMovementVolumetricBSplinesExternalMotionSolver.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug
|
||||
(
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver,
|
||||
0
|
||||
);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
optMeshMovement,
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementVolumetricBSplinesExternalMotionSolver::
|
||||
computeBoundaryMovement
|
||||
(
|
||||
const scalarField& correction
|
||||
)
|
||||
{
|
||||
const label nCPs(volBSplinesBase_.getTotalControlPointsNumber());
|
||||
dx_.primitiveFieldRef() = vector::zero;
|
||||
cpMovement_ = vector::zero;
|
||||
|
||||
for (label iCP = 0; iCP < nCPs; iCP++)
|
||||
{
|
||||
cpMovement_[iCP].x() = correction[3*iCP];
|
||||
cpMovement_[iCP].y() = correction[3*iCP + 1];
|
||||
cpMovement_[iCP].z() = correction[3*iCP + 2];
|
||||
}
|
||||
|
||||
// Bound control point movement for non-active CPs
|
||||
volBSplinesBase_.boundControlPointsMovement(cpMovement_);
|
||||
|
||||
// Compute boundary movement
|
||||
label passedCPs(0);
|
||||
PtrList<NURBS3DVolume>& boxes = volBSplinesBase_.boxesRef();
|
||||
forAll(boxes, iNURB)
|
||||
{
|
||||
const label nb = boxes[iNURB].getControlPoints().size();
|
||||
for (label cpI = 0; cpI < nb; ++cpI)
|
||||
{
|
||||
const label globalCP = passedCPs + cpI;
|
||||
forAll(patchIDs_, pI)
|
||||
{
|
||||
const label patchI = patchIDs_[pI];
|
||||
vectorField boundaryMovement
|
||||
(
|
||||
boxes[iNURB].patchDxDb(patchI, cpI)
|
||||
& cpMovement_[globalCP]
|
||||
);
|
||||
dx_.boundaryField()[patchI].addToInternalField
|
||||
(
|
||||
dx_.primitiveFieldRef(),
|
||||
boundaryMovement
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Increment number of passed sensitivities
|
||||
passedCPs += nb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optMeshMovementVolumetricBSplinesExternalMotionSolver::
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
)
|
||||
:
|
||||
optMeshMovement(mesh, dict, patchIDs),
|
||||
volBSplinesBase_
|
||||
(
|
||||
const_cast<volBSplinesBase&>(volBSplinesBase::New(mesh))
|
||||
),
|
||||
dx_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dx",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
pointMesh::New(mesh),
|
||||
dimensionedVector(dimless, Zero)
|
||||
),
|
||||
cpMovement_(volBSplinesBase_.getTotalControlPointsNumber(), vector::zero)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::optMeshMovementVolumetricBSplinesExternalMotionSolver::moveMesh()
|
||||
{
|
||||
// Compute boundary movement
|
||||
computeBoundaryMovement(correction_);
|
||||
|
||||
// Set boundary movement of motion solver
|
||||
displMethodPtr_->setMotionField(dx_);
|
||||
|
||||
// Positions of control points have not changed since only the boundary dx
|
||||
// has been computed.
|
||||
// Use correction to update them
|
||||
volBSplinesBase_.moveControlPoints(cpMovement_);
|
||||
|
||||
// Write control points to files
|
||||
volBSplinesBase_.writeControlPoints();
|
||||
|
||||
// Move the mesh and check quality
|
||||
optMeshMovement::moveMesh();
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar
|
||||
Foam::optMeshMovementVolumetricBSplinesExternalMotionSolver::computeEta
|
||||
(
|
||||
const scalarField& correction
|
||||
)
|
||||
{
|
||||
computeBoundaryMovement(correction);
|
||||
|
||||
// Get maximum boundary movement
|
||||
scalar maxDisplacement = gMax(mag(dx_.primitiveField()));
|
||||
|
||||
// Compute eta value
|
||||
Info<< "maxAllowedDisplacement/maxDisplacement \t"
|
||||
<< getMaxAllowedDisplacement() << "/" << maxDisplacement << endl;
|
||||
scalar eta = getMaxAllowedDisplacement() / maxDisplacement;
|
||||
Info<< "Setting eta value to " << eta << endl;
|
||||
|
||||
return eta;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList
|
||||
Foam::optMeshMovementVolumetricBSplinesExternalMotionSolver::getActiveDesignVariables()
|
||||
const
|
||||
{
|
||||
return volBSplinesBase_.getActiveDesignVariables();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::optMeshMovementVolumetricBSplinesExternalMotionSolver
|
||||
|
||||
Description
|
||||
Converts NURBS volume control points update to actual mesh movement.
|
||||
Internal points are moved based on a motionSolver other than
|
||||
volumetricBSplinesExternalMotionSolver.
|
||||
|
||||
SourceFiles
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef optMeshMovementVolumetricBSplinesExternalMotionSolver_H
|
||||
#define optMeshMovementVolumetricBSplinesExternalMotionSolver_H
|
||||
|
||||
#include "optMeshMovement.H"
|
||||
#include "volBSplinesBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class optMeshMovementVolumetricBSplinesExternalMotionSolver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class optMeshMovementVolumetricBSplinesExternalMotionSolver
|
||||
:
|
||||
public optMeshMovement
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Reference to underlaying volumetric B-Splines morpher
|
||||
volBSplinesBase& volBSplinesBase_;
|
||||
|
||||
//- Boundary movement due to change of NURBS control points
|
||||
pointVectorField dx_;
|
||||
|
||||
//- Movement of control points
|
||||
vectorField cpMovement_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
void computeBoundaryMovement(const scalarField& correction);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver
|
||||
(
|
||||
const optMeshMovementVolumetricBSplinesExternalMotionSolver&
|
||||
) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=
|
||||
(
|
||||
const optMeshMovementVolumetricBSplinesExternalMotionSolver&
|
||||
) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("volumetricBSplinesExternalMotionSolver");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
optMeshMovementVolumetricBSplinesExternalMotionSolver
|
||||
(
|
||||
fvMesh& mesh,
|
||||
const dictionary& dict,
|
||||
const labelList& patchIDs
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~optMeshMovementVolumetricBSplinesExternalMotionSolver() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculates surface mesh movement
|
||||
void moveMesh();
|
||||
|
||||
//- Compute eta value based on max displacement
|
||||
virtual scalar computeEta(const scalarField& correction);
|
||||
|
||||
//- Return active design variables
|
||||
virtual labelList getActiveDesignVariables() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,250 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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 "steadyOptimisation.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(steadyOptimisation, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
optimisationManager,
|
||||
steadyOptimisation,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::steadyOptimisation::updateOptTypeSource()
|
||||
{
|
||||
forAll(primalSolvers_, pI)
|
||||
{
|
||||
primalSolvers_[pI].updateOptTypeSource(optType_->sourcePtr());
|
||||
}
|
||||
|
||||
forAll(adjointSolverManagers_, asmI)
|
||||
{
|
||||
PtrList<adjointSolver>& adjointSolvers =
|
||||
adjointSolverManagers_[asmI].adjointSolvers();
|
||||
|
||||
forAll(adjointSolvers, aI)
|
||||
{
|
||||
adjointSolvers[aI].updateOptTypeSource(optType_->sourcePtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::steadyOptimisation::lineSearchUpdate(scalarField& direction)
|
||||
{
|
||||
autoPtr<lineSearch>& lineSrch = optType_->getLineSearch();
|
||||
|
||||
// Store starting point
|
||||
optType_->storeDesignVariables();
|
||||
|
||||
// Compute merit function before update
|
||||
scalar meritFunction = optType_->computeMeritFunction();
|
||||
lineSrch->setOldMeritValue(meritFunction);
|
||||
|
||||
// Get merit function derivative
|
||||
const scalar dirDerivative =
|
||||
optType_->meritFunctionDirectionalDerivative();
|
||||
lineSrch->setDeriv(dirDerivative);
|
||||
lineSrch->setDirection(direction);
|
||||
|
||||
// Reset initial step.
|
||||
// Might be interpolated from previous optimisation cycles
|
||||
lineSrch->reset();
|
||||
|
||||
// Perform line search
|
||||
for (label iter = 0; iter < lineSrch->maxIters(); ++iter)
|
||||
{
|
||||
Info<< "\n- - - - - - - - - - - - - - -" << endl;
|
||||
Info<< "Line search iteration " << iter << endl;
|
||||
Info<< "- - - - - - - - - - - - - - -\n" << endl;
|
||||
|
||||
// Update design variables. Multiplication with line search step
|
||||
// happens inside the update(direction) function
|
||||
optType_->update(direction);
|
||||
|
||||
// Solve all primal equations
|
||||
solvePrimalEquations();
|
||||
|
||||
// Compute and set new merit function
|
||||
meritFunction = optType_->computeMeritFunction();
|
||||
lineSrch->setNewMeritValue(meritFunction);
|
||||
|
||||
if (lineSrch->converged())
|
||||
{
|
||||
// If line search criteria have been met, proceed
|
||||
Info<< "Line search converged in " << iter + 1
|
||||
<< " iterations." << endl;
|
||||
scalarField scaledCorrection(lineSrch->step()*direction);
|
||||
optType_->updateOldCorrection(scaledCorrection);
|
||||
optType_->write();
|
||||
lineSrch()++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If maximum number of iteration has been reached, continue
|
||||
if (iter == lineSrch->maxIters()-1)
|
||||
{
|
||||
Info<< "Line search reached max. number of iterations.\n"
|
||||
<< "Proceeding to the next optimisation cycle" << endl;
|
||||
scalarField scaledCorrection(lineSrch->step()*direction);
|
||||
optType_->updateOldCorrection(scaledCorrection);
|
||||
optType_->write();
|
||||
lineSrch()++;
|
||||
}
|
||||
// Reset to initial design variables and update step
|
||||
else
|
||||
{
|
||||
optType_->resetDesignVariables();
|
||||
lineSrch->updateStep();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::steadyOptimisation::fixedStepUpdate(scalarField& direction)
|
||||
{
|
||||
// Update based on fixed step
|
||||
optType_->update(direction);
|
||||
|
||||
// If direction has been scaled (say by setting the initial eta), the
|
||||
// old correction has to be updated
|
||||
optType_->updateOldCorrection(direction);
|
||||
optType_->write();
|
||||
|
||||
// Solve primal equations
|
||||
solvePrimalEquations();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::steadyOptimisation::steadyOptimisation(fvMesh& mesh)
|
||||
:
|
||||
optimisationManager(mesh)
|
||||
{
|
||||
optType_.reset
|
||||
(
|
||||
incompressible::optimisationType::New
|
||||
(
|
||||
mesh,
|
||||
subDict("optimisation"),
|
||||
adjointSolverManagers_
|
||||
).ptr()
|
||||
);
|
||||
|
||||
// Update source ptrs in all solvers to look at the source held in optType
|
||||
// Possible problem if mesh is adapted
|
||||
updateOptTypeSource();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::optimisationManager& Foam::steadyOptimisation::operator++()
|
||||
{
|
||||
time_++;
|
||||
if (!end())
|
||||
{
|
||||
Info<< "\n* * * * * * * * * * * * * * * * *" << endl;
|
||||
Info<< "Optimisation cycle " << time_.value() << endl;
|
||||
Info<< "* * * * * * * * * * * * * * * * *\n" << endl;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Foam::optimisationManager& Foam::steadyOptimisation::operator++(int)
|
||||
{
|
||||
return operator++();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::steadyOptimisation::checkEndOfLoopAndUpdate()
|
||||
{
|
||||
if (update())
|
||||
{
|
||||
optType_->update();
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::steadyOptimisation::end()
|
||||
{
|
||||
return time_.end();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::steadyOptimisation::update()
|
||||
{
|
||||
return (time_.timeIndex() != 1 && !end());
|
||||
}
|
||||
|
||||
|
||||
void Foam::steadyOptimisation::updateDesignVariables()
|
||||
{
|
||||
// Compute direction of update
|
||||
tmp<scalarField> tdirection = optType_->computeDirection();
|
||||
scalarField& direction = tdirection.ref();
|
||||
autoPtr<lineSearch>& lineSrch = optType_->getLineSearch();
|
||||
|
||||
// Update design variables using either a line-search scheme or
|
||||
// a fixed-step update
|
||||
if (lineSrch.valid())
|
||||
{
|
||||
lineSearchUpdate(direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixedStepUpdate(direction);
|
||||
}
|
||||
|
||||
// Reset adjoint sensitivities in all adjoint solver managers
|
||||
for (adjointSolverManager& adjSolverManager : adjointSolverManagers_)
|
||||
{
|
||||
adjSolverManager.clearSensitivities();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,132 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2007-2019 PCOpt/NTUA
|
||||
Copyright (C) 2013-2019 FOSS GP
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more 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::steadyOptimisation
|
||||
|
||||
Description
|
||||
Iterate the optimisation cycles. For steady state opt, this coinsides
|
||||
with evolving Time
|
||||
|
||||
SourceFiles
|
||||
steadyOptimisation.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef steadyOptimisation_H
|
||||
#define steadyOptimisation_H
|
||||
|
||||
#include "optimisationManager.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class steadyOptimisation Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class steadyOptimisation
|
||||
:
|
||||
public optimisationManager
|
||||
{
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Update optimisationType source for all primal and adjoint solvers
|
||||
void updateOptTypeSource();
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
steadyOptimisation(const steadyOptimisation&) = delete;
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const steadyOptimisation&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Update design variables using a line-search
|
||||
void lineSearchUpdate(scalarField& direction);
|
||||
|
||||
//- Update design variables using a fixed step
|
||||
void fixedStepUpdate(scalarField& direction);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("steadyOptimisation");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
steadyOptimisation(fvMesh& mesh);
|
||||
|
||||
|
||||
// Destructor
|
||||
virtual ~steadyOptimisation() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Prefix increment
|
||||
virtual optimisationManager& operator++();
|
||||
|
||||
//- Postfix increment, this is identical to the prefix increment
|
||||
virtual optimisationManager& operator++(int);
|
||||
|
||||
//- Return true if end of optimisation run
|
||||
// Also, updates the design variables if needed
|
||||
virtual bool checkEndOfLoopAndUpdate();
|
||||
|
||||
//- Return true if end of optimisation run
|
||||
virtual bool end();
|
||||
|
||||
//- Whether to update the design variables
|
||||
virtual bool update();
|
||||
|
||||
//- Do a line search to find a correction satisfying the step
|
||||
//- convergence criteria
|
||||
virtual void updateDesignVariables();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // 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