adjointBoundaryCondition.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2007-2021 PCOpt/NTUA
9 Copyright (C) 2013-2021 FOSS GP
10 Copyright (C) 2019-2020 OpenCFD Ltd.
11-------------------------------------------------------------------------------
12License
13 This file is part of OpenFOAM.
14
15 OpenFOAM is free software: you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27
28\*---------------------------------------------------------------------------*/
29
31#include "emptyFvPatch.H"
33#include "HashTable.H"
35#include "ATCUaGradU.H"
36
37// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38
39namespace Foam
40{
41
42// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43
44template<class Type>
45template<class Type2>
46tmp
47<
48 Field<typename Foam::outerProduct<Foam::vector, Type2>::type>
49>
51{
52 // Return field
53 typedef typename outerProduct<vector, Type2>::type GradType;
54 auto tresGrad = tmp<Field<GradType>>::New(patch_.size(), Zero);
55 auto& resGrad = tresGrad.ref();
56
57 const labelList& faceCells = patch_.faceCells();
58 const fvMesh& mesh = patch_.boundaryMesh().mesh();
59 const cellList& cells = mesh.cells();
60
61 // Go through the surfaceInterpolation scheme defined in gradSchemes for
62 // consistency
65
66 // Gives problems when grad(AdjointVar) is computed using a limited scheme,
67 // since it is not possible to know a priori how many words to expect in the
68 // stream.
69 // Interpolation scheme is now read through interpolation schemes.
70 /*
71 word gradSchemeName("grad(" + name + ')');
72 ITstream& is = mesh.gradScheme(gradSchemeName);
73 word schemeData(is);
74 */
75
76 // If there are many patches calling this function, the computation of
77 // the surface field might be a significant computational
78 // burden. Cache the interpolated field and fetch from the registry when
79 // possible.
80 const word surfFieldName("interpolated" + name + "ForBoundaryGrad");
82 surfFieldType* surfFieldPtr =
83 mesh.objectRegistry::template getObjectPtr<surfFieldType>(surfFieldName);
84
85 if (!surfFieldPtr)
86 {
87 solution::cachePrintMessage("Calculating and caching", name, field);
88
89 surfFieldPtr =
91 (
92 mesh, mesh.interpolationScheme("interpolate(" + name + ")")
93 )().interpolate(field).ptr();
94 surfFieldPtr->rename(surfFieldName);
95 regIOobject::store(surfFieldPtr);
96 }
97 else
98 {
99 if (surfFieldPtr->upToDate(field))
100 {
102 }
103 else
104 {
106 delete surfFieldPtr;
107
108 surfFieldPtr =
110 (
111 mesh, mesh.interpolationScheme("interpolate(" + name + ")")
112 )().interpolate(field).ptr();
113 surfFieldPtr->rename(surfFieldName);
114 regIOobject::store(surfFieldPtr);
115 }
116 }
117 surfFieldType& surfField = *surfFieldPtr;
118
119 // Auxiliary fields
120 const surfaceVectorField& Sf = mesh.Sf();
121 tmp<vectorField> tnf = patch_.nf();
122 const vectorField& nf = tnf();
123 const scalarField& V = mesh.V();
124 const labelUList& owner = mesh.owner();
125
126 // Compute grad value of cell adjacent to the boundary
127 forAll(faceCells, fI)
128 {
129 const label cI = faceCells[fI];
130 const cell& cellI = cells[cI];
131 for (const label faceI : cellI) // global face numbering
132 {
133 label patchID = mesh.boundaryMesh().whichPatch(faceI);
134 if (patchID == -1) //face is internal
135 {
136 const label own = owner[faceI];
137 tensor flux = Sf[faceI]*surfField[faceI];
138 if (cI == own)
139 {
140 resGrad[fI] += flux;
141 }
142 else
143 {
144 resGrad[fI] -= flux;
145 }
146 }
147 else // Face is boundary. Covers coupled patches as well
148 {
149 if (!isA<emptyFvPatch>(mesh.boundary()[patchID]))
150 {
151 const fvPatch& patchForFlux = mesh.boundary()[patchID];
152 const label boundaryFaceI = faceI - patchForFlux.start();
153 const vectorField& Sfb = Sf.boundaryField()[patchID];
154 resGrad[fI] +=
155 Sfb[boundaryFaceI]
156 *surfField.boundaryField()[patchID][boundaryFaceI];
157 }
158 }
159 }
160 resGrad[fI] /= V[cI];
161 }
162
163 // This has concluded the computation of the grad at the cell next to the
164 // boundary. We now need to compute the grad at the boundary face
165 const fvPatchField<Type2>& bField = field.boundaryField()[patch_.index()];
166 resGrad = nf*bField.snGrad() + (resGrad - nf*(nf & resGrad));
167
168 return tresGrad;
169}
170
171
172template<class Type>
174{
175 if (!addATCUaGradUTerm_)
176 {
177 addATCUaGradUTerm_.reset(new bool(isA<ATCUaGradU>(getATC())));
178 }
179 return addATCUaGradUTerm_();
180}
181
182
183// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
184
185template<class Type>
187(
188 const adjointBoundaryCondition<Type>& adjointBC
189)
190:
191 patch_(adjointBC.patch_),
192 managerName_(adjointBC.managerName_),
193 adjointSolverName_(adjointBC.adjointSolverName_),
194 simulationType_(adjointBC.simulationType_),
195 boundaryContrPtr_
196 (
198 (
199 adjointBC.managerName_,
200 adjointBC.adjointSolverName_,
201 adjointBC.simulationType_,
202 adjointBC.patch_
203 )
204 ),
205 addATCUaGradUTerm_(adjointBC.addATCUaGradUTerm_)
206{}
207
208
209// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
210
211template<class Type>
213(
214 const fvPatch& p,
216 const word& solverName
217)
218:
219 patch_(p),
220 managerName_("objectiveManager" + solverName),
221 adjointSolverName_(solverName),
222 simulationType_("incompressible"),
223 boundaryContrPtr_(nullptr),
224 addATCUaGradUTerm_(nullptr)
225{
226 // Set the boundaryContribution pointer
228}
229
230
231// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
232
233template<class Type>
235{
236 return managerName_;
237}
238
239
240template<class Type>
242{
243 return adjointSolverName_;
244}
245
246
247template<class Type>
249{
250 return simulationType_;
251}
252
253
254template<class Type>
256{
257 // Note:
258 // Check whether there is an objectiveFunctionManager object in the registry
259 // Necessary for decomposePar if the libadjoint is loaded
260 // through controlDict. A nicer way should be found
261 const fvMesh& meshRef = patch_.boundaryMesh().mesh();
262 if (meshRef.foundObject<regIOobject>(managerName_))
263 {
264 boundaryContrPtr_.reset
265 (
267 (
268 managerName_,
269 adjointSolverName_,
270 simulationType_,
271 patch_
272 ).ptr()
273 );
274 }
275 else
276 {
278 << "No objectiveManager " << managerName_ << " available." << nl
279 << "Setting boundaryAdjointContributionPtr to nullptr. " << nl
280 << "OK for decomposePar."
281 << endl;
282 }
283}
284
285
286template<class Type>
289{
290 return boundaryContrPtr_();
291}
292
293
294template<class Type>
296{
297 return
298 patch_.boundaryMesh().mesh().template
299 lookupObject<ATCModel>("ATCModel" + adjointSolverName_);
300}
301
302
303template<class Type>
305{
306 // Does nothing in base
307}
308
309
310template<class Type>
311tmp
312<
314>
316{
317 return
319 (
320 patch_.size(),
321 Zero
322 );
323}
324
325
326// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
327
328} // End namespace Foam
329
330// ************************************************************************* //
Base class for selecting the adjoint transpose convection model. Inherits from regIOobject to add loo...
Definition: ATCModel.H:63
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
Base class for solution control classes.
const word & objectiveManagerName() const
Return objectiveManager name.
const ATCModel & getATC() const
ATC type might be useful for a number of BCs. Return here.
const word & adjointSolverName() const
Return adjointSolverName.
boundaryAdjointContribution & getBoundaryAdjContribution()
Get boundaryContribution.
const word & simulationType() const
Return the simulationType.
tmp< Field< typename Foam::outerProduct< Foam::vector, Type2 >::type > > computePatchGrad(word name)
Get gradient of field on a specific boundary.
virtual tmp< Field< typename Foam::outerProduct< Foam::vector, Type >::type > > dxdbMult() const
Return contribution to sensitivity derivatives.
void setBoundaryContributionPtr()
Set the ptr to the correct boundaryAdjointContribution.
bool addATCUaGradUTerm()
Whether to add the extra term from the UaGradU formulation.
Abstract base class for computing contributions of the objective functions to the adjoint boundary co...
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:57
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:59
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:712
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
Definition: fvMesh.H:417
const surfaceVectorField & Sf() const
Return cell face area vectors.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:82
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
Definition: fvPatchField.C:229
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:71
virtual label start() const
Return start label of this patch in the polyMesh face list.
Definition: fvPatch.H:179
bool foundObject(const word &name, const bool recursive=false) const
Is the named Type found?
const Type & lookupObject(const word &name, const bool recursive=false) const
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
const polyMesh & mesh() const noexcept
Return the mesh reference.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
void reset(const label nPoints, const label nInternalFaces, const label nFaces, const label nCells)
Reset this primitiveMesh given the primitive array sizes.
const cellList & cells() const
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:76
ITstream & interpolationScheme(const word &name) const
Get interpolation scheme for given name, or default.
static void cachePrintMessage(const char *message, const word &name, const FieldType &vf)
Helper for printing cache message.
A class for managing temporary objects.
Definition: tmp.H:65
type
Volume classification types.
Definition: volumeType.H:66
A class for handling words, derived from Foam::string.
Definition: word.H:68
volScalarField & p
rDeltaTY field()
dynamicFvMesh & mesh
const cellShapeList & cells
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
Definition: curveTools.C:75
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333