47 namespace incompressible
73 createZeroBoundaryPointFieldPtr<vector>(
mesh_)
77 createZeroBoundaryPointFieldPtr<vector>(
mesh_)
81 for (
const label patchI : sensitivityPatchIDs_)
92 for (
auto& fun : functions)
94 dSdbMultiplierTot += fun.weight()*fun.dSdbMultiplier(patchI);
95 dndbMultiplierTot += fun.weight()*fun.dndbMultiplier(patchI);
106 const label patchStartIndex =
patch.start();
114 const labelList& pointFaces = patchPointFaces[ppI];
115 for (label localFaceIndex : pointFaces)
117 label globalFaceIndex = patchStartIndex + localFaceIndex;
118 const face& faceI = faces[globalFaceIndex];
124 if (faceI[facePointI] == meshPoints[ppI])
131 dBoundary.makeFaceCentresAndAreas_d(
p, p_d)
135 const tensor& deltaSf = deltaNormals[1];
137 dSdbMultiplierTot[localFaceIndex] & deltaSf;
140 const tensor& deltaNf = deltaNormals[2];
142 dndbMultiplierTot[localFaceIndex] & deltaNf;
150 for (
const label patchI : sensitivityPatchIDs_)
156 const label globaPointI = meshPoints[ppI];
157 dSdbGlobal[globaPointI] += pointSensdSdb()[patchI][ppI];
158 dndbGlobal[globaPointI] += pointSensdndb()[patchI][ppI];
164 mesh_, dSdbGlobal, plusEqOp<vector>(), vector::zero
168 mesh_, dndbGlobal, plusEqOp<vector>(), vector::zero
171 for (
const label patchI : sensitivityPatchIDs_)
176 pointSensdSdb()[patchI].map(dSdbGlobal, meshPoints);
177 pointSensdndb()[patchI].map(dndbGlobal, meshPoints);
180 PrimitivePatchInterpolation<polyPatch> patchInter(
patch.patch());
183 patchInter.pointToFaceInterpolate(pointSensdSdb()[patchI])
189 tmp<vectorField> tdndbFace =
190 patchInter.pointToFaceInterpolate(pointSensdndb()[patchI]);
194 wallFaceSensVecPtr_()[patchI] += dSdbFace + dndbFace;
224 const label
iters(
dict().getOrDefault<label>(
"iters", 500));
225 const scalar tolerance(
dict().getOrDefault<scalar>(
"tolerance", 1.
e-06));
246 Info<<
"Reading the already constructed faMesh" <<
endl;
252 dictionary faMeshDefinition;
254 IOobject faMeshDefinitionDict
264 if (faMeshDefinitionDict.typeHeaderOk<IOdictionary>(
false))
266 Info<<
"Reading faMeshDefinition from system " <<
endl;
267 faMeshDefinition = IOdictionary(faMeshDefinitionDict);
273 Info<<
"Constructing faMeshDefinition from sensitivity patches" 275 wordList polyMeshPatches(sensitivityPatchIDs_.size());
277 for (
const label
patchID : sensitivityPatchIDs_)
281 faMeshDefinition.add<
wordList>(
"polyMeshPatches", polyMeshPatches);
282 (void)faMeshDefinition.subDictOrAdd(
"boundary");
286 aMeshPtr.
reset(
new faMesh(
mesh_, faMeshDefinition));
292 const scalar Rphysical
295 <<
"Physical radius of the sensitivity smoothing " 296 << Rphysical <<
nl <<
endl;
328 vsm.mapToSurface<scalar>(wallFaceSensNormalPtr_());
333 for (label iter = 0; iter <
iters; ++iter)
335 Info<<
"Sensitivity smoothing iteration " << iter <<
endl;
347 const scalar residual(
mag(smoothEqn.solve().initialResidual()));
350 <<
"Max smoothSens " <<
gMax(
mag(smoothedSens)()) <<
endl;
356 if (residual < tolerance)
358 Info<<
"\n***Reached smoothing equation convergence limit, " 359 "iteration " << iter <<
"***\n\n";
369 "smoothedSurfaceSens" + surfaceFieldSuffix_,
380 vsm.mapToVolume(smoothedSens, volSmoothedSens.boundaryFieldRef());
381 volSmoothedSens.write();
392 if (geometricD[iDir] == -1)
394 averageArea /= bounds.
span()[iDir];
405 sensitivitySurface::sensitivitySurface
414 includeSurfaceArea_(false),
415 includePressureTerm_(false),
416 includeGradStressTerm_(false),
417 includeTransposeStresses_(false),
418 useSnGradInTranposeStresses_(false),
419 includeDivTerm_(false),
420 includeDistance_(false),
421 includeMeshMovement_(false),
422 includeObjective_(false),
423 writeGeometricInfo_(false),
424 smoothSensitivities_(false),
425 eikonalSolver_(nullptr),
426 meshMovementSolver_(nullptr),
428 nfOnPatchPtr_(nullptr),
429 SfOnPatchPtr_(nullptr),
430 CfOnPatchPtr_(nullptr)
436 wallFaceSensVecPtr_.reset(createZeroBoundaryPtr<vector>(
mesh_));
437 wallFaceSensNormalPtr_.reset(createZeroBoundaryPtr<scalar>(
mesh_));
438 wallFaceSensNormalVecPtr_.reset(createZeroBoundaryPtr<vector>(
mesh_));
450 mesh.time().timeName(),
467 mesh.time().timeName(),
484 mesh.time().timeName(),
549 new adjointMeshMovementSolver
554 sensitivityPatchIDs_,
586 for (
const label patchI : sensitivityPatchIDs_)
618 adjointTurbulence->wallShapeSensitivities();
621 <<
" Calculating adjoint sensitivity. " <<
endl;
623 tmp<volScalarField> tnuEff = adjointTurbulence->nuEff();
641 for (
const label patchI : sensitivityPatchIDs_)
644 tmp<vectorField> tnf =
patch.nf();
646 wallFaceSensVecPtr_()[patchI] -=
647 (Uab & tnf)*gradp.boundaryField()[patchI]*dt;
658 tmp<volTensorField> tgradU =
667 if (isA<wallFvPatch>(
patch))
670 gradUbf[patchI] = tnf*
U.boundaryField()[patchI].snGrad();
674 tmp<volSymmTensorField> tstress = nuEff*
twoSymm(tgradU);
676 autoPtr<volVectorField> ptemp
679 for (label idir = 0; idir < pTraits<vector>::nComponents; ++idir)
683 for (
const label patchI : sensitivityPatchIDs_)
686 tmp<vectorField> tnf =
patch.nf();
688 wallFaceSensVecPtr_()[patchI] +=
691 *(gradStressDir.boundaryField()[patchI] & tnf)
701 tmp<volTensorField> tgradUa =
fvc::grad(Ua);
703 tgradUa.cref().boundaryField();
705 for (
const label patchI : sensitivityPatchIDs_)
708 tmp<vectorField> tnf =
patch.nf();
714 : (gradUabf[patchI] & nf)
716 wallFaceSensVecPtr_()[patchI] -=
717 nuEff.boundaryField()[patchI]
718 *(gradUaNf &
U.boundaryField()[patchI].snGrad())*nf;
722 for (
const label patchI : sensitivityPatchIDs_)
725 tmp<vectorField> tnf =
patch.nf();
745 &
U.boundaryField()[patchI].snGrad()
747 * nuEff.boundaryField()[patchI]
754 scalar(1./3.)*nuEff.boundaryField()[patchI]
757 &
U.boundaryField()[patchI].snGrad()
769 &
U.boundaryField()[patchI].snGrad()
773 PtrList<objective>& functions
783 functions[funcI].weight()
785 functions[funcI].dxdbDirectMultiplier(patchI)
791 wallFaceSensVecPtr_()[patchI] +=
795 + adjointTMsensitivities[patchI]
802 (wallFaceSensVecPtr_(), sensitivityPatchIDs_, dt);
815 for (
const label patchI : sensitivityPatchIDs_)
831 autoPtr<boundaryVectorField> distanceSensPtr(
nullptr);
835 distanceSensPtr.reset(createZeroBoundaryPtr<vector>(
mesh_));
838 for (
const label patchI : sensitivityPatchIDs_)
840 distanceSensPtr()[patchI] = sens[patchI];
844 autoPtr<boundaryVectorField> meshMovementSensPtr(
nullptr);
848 meshMovementSensPtr.reset(createZeroBoundaryPtr<vector>(
mesh_));
851 for (
const label patchI : sensitivityPatchIDs_)
853 meshMovementSensPtr()[patchI] = sens[patchI];
859 label nPassedFaces(0);
860 for (
const label patchI : sensitivityPatchIDs_)
863 tmp<vectorField> tnf(
patch.nf());
869 wallFaceSensVecPtr_()[patchI] += distanceSensPtr()[patchI];
875 wallFaceSensVecPtr_()[patchI] += meshMovementSensPtr()[patchI];
880 wallFaceSensVecPtr_()[patchI] *=
patch.magSf();
883 wallFaceSensNormalPtr_()[patchI] = wallFaceSensVecPtr_()[patchI] & nf;
884 wallFaceSensNormalVecPtr_()[patchI] =
885 wallFaceSensNormalPtr_()[patchI] * nf;
890 = wallFaceSensNormalPtr_()[patchI][fI];
892 nPassedFaces +=
patch.size();
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
autoPtr< volVectorField > nfOnPatchPtr_
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
void size(const label n)
Older name for setAddressableSize.
const incompressibleVars & primalVars_
void setSuffix(const word &suffix)
Set suffix.
autoPtr< volVectorField > SfOnPatchPtr_
virtual bool readDict(const dictionary &dict)
Read dictionary if changed.
defineTypeNameAndDebug(adjointEikonalSolver, 0)
bool useSnGradInTranposeStresses_
Use snGrad in the transpose part of the adjoint stresses.
fvPatchField< vector > fvPatchVectorField
virtual void additionalSensitivityMapTerms(boundaryVectorField &sensitivityMap, const labelHashSet &patchIDs, const scalar dt)
Terms to be added to the sensitivity map, depending on the adjoint solver.
const volSurfaceMapping vsm(aMesh)
bool includeObjective_
Include terms directly emerging from the objective function.
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
word findInstance(const fileName &dir, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null) const
Return time instance (location) of dir that contains the file name (eg, used in reading mesh data)...
label nPoints() const noexcept
Number of mesh points.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
PtrList< objective > & getObjectiveFunctions()
Return reference to objective functions.
autoPtr< volVectorField > CfOnPatchPtr_
autoPtr< adjointMeshMovementSolver > meshMovementSolver_
virtual void write(const word &baseName=word::null)
Write sensitivity maps.
GeometricField< tensor, fvPatchField, volMesh > volTensorField
dimensionedSymmTensor sqr(const dimensionedVector &dv)
volVectorField::Boundary boundaryVectorField
constexpr char nl
The newline '\n' character (0x0a)
void addGeometricSens()
Add sensitivities from dSd/db and dnf/db computed at points and mapped to faces.
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
virtual void write(const word &baseName=word::null)
Write sensitivity fields.
void smoothSensitivities()
Smooth sensitivity derivatives based on the computation of the 'Sobolev gradient'.
Differentiation of the mesh data structure.
void unzipRow(const FieldField< Field, SymmTensor< Cmpt >> &input, const direction idx, FieldField< Field, Vector< Cmpt >> &result)
Extract a symmTensor field field row (x,y,z) == (0,1,2)
Base class for adjoint solvers.
A bounding box defined in terms of min/max extrema points.
bool includeTransposeStresses_
Include the transpose part of the adjoint stresses.
incompressibleAdjointSolver & adjointSolver_
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
GeometricBoundaryField< tensor, fvPatchField, volMesh > Boundary
Type of boundary fields.
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
const Time & time() const
Return the top-level database.
void read()
Read controls and update solver pointers if necessary.
GeometricField< vector, fvPatchField, volMesh > volVectorField
labelList faceLabels(nFaceLabels)
autoPtr< adjointEikonalSolver > eikonalSolver_
bool includeDivTerm_
Include the term from the deviatoric part of the stresses.
label nGeometricD() const
Return the number of valid geometric dimensions in the mesh.
bool includeGradStressTerm_
Include the term containing the grad of the stress at the boundary.
static const word & zeroGradientType() noexcept
The type name for zeroGradient patch fields.
addToRunTimeSelectionTable(adjointSensitivity, sensitivityBezier, dictionary)
Macros for easy insertion into run-time selection tables.
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
objectiveManager & objectiveManager_
Base class for incompressibleAdjoint solvers.
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
tmp< faMatrix< Type > > laplacian(const GeometricField< Type, faPatchField, areaMesh > &vf)
fileName caseSystem() const
Return the system name for the case, which is ../system() for parallel runs.
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
const dictionary & dict() const
Return the construction dictionary.
pointField points(const UList< point > &pts) const
Return the points corresponding to this face.
zeroField Sp(const Foam::zero, const GeometricField< Type, faPatchField, areaMesh > &)
A no-op source.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
const volScalarField & pa() const
Return const reference to pressure.
static const Identity< scalar > I
autoPtr< adjointEikonalSolver > & getAdjointEikonalSolver()
Get adjoint eikonal solver.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
Abstract base class for adjoint-based sensitivities in incompressible flows.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual bool readDict(const dictionary &dict)
Read dict if changed.
bool includeSurfaceArea_
Include surface area in sens computation.
label size() const noexcept
The number of entries in the list.
void computeDerivativesSize()
Compute the number of faces on sensitivityPatchIDs_.
const volVectorField & Ua() const
Return const reference to velocity.
const volScalarField & p() const
Return const reference to pressure.
bool includeMeshMovement_
Include mesh movement variation in sens computation.
Reading is optional [identical to LAZY_READ].
static const word null
An empty word.
virtual void accumulateIntegrand(const scalar dt)
Accumulate sensitivity integrands.
virtual void assembleSensitivities()
Assemble sensitivities.
const autoPtr< incompressibleAdjoint::adjointRASModel > & adjointTurbulence() const
Return const reference to the adjointRASModel.
virtual const faceList & faces() const
Return raw faces.
bool writeGeometricInfo_
Write geometric info for use by external programs.
bool includeDistance_
Include distance variation in sens computation.
const word & solverName() const
Return solver name.
Calculate the matrix for the laplacian of the field.
#define DebugInfo
Report an information message using Foam::Info.
const volVectorField & U() const
Return const reference to velocity.
Calculate the finiteArea matrix for implicit and explicit sources.
static word timeName(const scalar t, const int precision=precision_)
Return time name of given scalar time formatted with the given precision.
Type gMax(const FieldField< Field, Type > &f)
void write()
Write sensitivity fields.
Ostream & printExecutionTime(OSstream &os) const
Print the elapsed ExecutionTime (cpu-time), ClockTime.
T & ref()
Return reference to the managed object without nullptr checking.
const autoPtr< incompressible::RASModelVariables > & RASModelVariables() const
Return const reference to the turbulence model variables.
bool includePressureTerm_
Include the adjoint pressure term in sens computation.
faMatrix< scalar > faScalarMatrix
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
List< word > wordList
List of word.
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Type gAverage(const FieldField< Field, Type > &f)
void clearSensitivities()
Zero sensitivity fields and their constituents.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Mesh data needed to do the Finite Volume discretisation.
loopControl iters(runTime, aMesh.solutionDict(), "solution")
Automatically write from objectRegistry::writeObject()
Calculation of adjoint based sensitivities at wall faces.
const std::string patch
OpenFOAM patch number as a std::string.
vector span() const
The bounding box span (from minimum to maximum)
void setSuffixName()
Set suffix name for sensitivity fields.
scalar computeRadius(const faMesh &aMesh)
Compute the physical smoothing radius based on the average boundary face 'length'.
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef()
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
bool smoothSensitivities_
Smooth sensitivity derivatives based on the computation of the 'Sobolev gradient'.
const boundBox & bounds() const noexcept
Return mesh bounding box.
Field< vector > vectorField
Specialisation of Field<T> for vector.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
A class for managing temporary objects.
incompressibleAdjointVars & adjointVars_
static tmp< GeometricField< tensor, fvPatchField, volMesh > > New(const word &name, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=fvPatchField< tensor >::calculatedType())
Return tmp field from name, mesh, dimensions and patch type.
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Base class supporting shape sensitivity derivatives for incompressible flows.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
const dimensionSet dimArea(sqr(dimLength))
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
Solver of the adjoint to the eikonal PDE.
static constexpr const zero Zero
Global zero (0)
const dimensionSet dimVelocity