mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-adjoint-shapeOptimisation' into 'develop'
ENH: New adjont shape optimisation functionality See merge request Development/openfoam!307
This commit is contained in:
@ -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