Loading...
Searching...
No Matches
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 * * * * * * * * * * * //
44template<class Type>
45template<class Type2>
46tmp
47<
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 labelUList& 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
64 mesh.lookupObject<volVectorField>(name);
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_.good())
176 {
177 addATCUaGradUTerm_ = bool(isA<ATCUaGradU>(getATC()));
178 }
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 ),
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_(Switch::INVALID)
225{
226 // Set the boundaryContribution pointer
231// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
232
233template<class Type>
238
239
240template<class Type>
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."
282 }
283}
284
285
286template<class Type>
287boundaryAdjointContribution&
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}
309
310template<class Type>
311tmp
312<
314>
316{
317 return nullptr;
318}
319
320
321// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
322
323} // End namespace Foam
324
325// ************************************************************************* //
Base class for selecting the adjoint transpose convection model. Inherits from regIOobject to add loo...
Definition ATCModel.H:59
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
Generic GeometricField class.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition Switch.H:81
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.
autoPtr< boundaryAdjointContribution > boundaryContrPtr_
Engine to manage contributions of the objective functions to the adjoint boundary conditions.
const word & simulationType() const
Return the simulationType.
adjointBoundaryCondition(const fvPatch &p, const DimensionedField< Type, volMesh > &iF, const word &solverName)
Construct from field and base name.
word adjointSolverName_
adjointSolver name corresponding to field
virtual void updatePrimalBasedQuantities()
Update the primal based quantities related to the adjoint boundary conditions.
tmp< Field< typename Foam::outerProduct< Foam::vector, Type2 >::type > > computePatchGrad(word name)
Get gradient of field on a specific boundary.
Switch addATCUaGradUTerm_
Whether to add the extra term from the UaGradU formulation.
const fvPatch & patch_
Reference to patch.
virtual tmp< Field< typename Foam::outerProduct< Foam::vector, Type >::type > > dxdbMult() const
Return contribution to sensitivity derivatives.
word simulationType_
simulationType corresponding to field.
word managerName_
objectiveManager name corresponding to field
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...
static autoPtr< boundaryAdjointContribution > New(const word &managerName, const word &adjointSolverName, const word &simulationType, const fvPatch &patch)
Return a reference to the selected turbulence model.
A cell is defined as a list of faces with extra functionality.
Definition cell.H:56
Smooth ATC in cells next to a set of patches supplied by type.
Definition faceCells.H:55
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition fvPatch.H:71
label start() const noexcept
The patch start within the polyMesh face list.
Definition fvPatch.H:226
bool foundObject(const word &name, const bool recursive=false) const
Contains the named Type?
typeOfRank< typenamepTraits< arg1 >::cmptType, direction(pTraits< arg1 >::rank)+direction(pTraits< arg2 >::rank)>::type type
Definition products.H:118
const polyMesh & mesh() const noexcept
Return the mesh reference.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition polyMesh.H:609
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition regIOobject.H:71
bool store()
Register object with its registry and transfer ownership to the registry.
static void cachePrintMessage(const char *message, const word &name, const FieldType &fld)
Helper for printing cache message.
static tmp< surfaceInterpolationScheme< Type > > New(const fvMesh &mesh, Istream &schemeData)
Return new tmp interpolation scheme.
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
rDeltaTY field()
dynamicFvMesh & mesh
const cellShapeList & cells
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
GeometricField< vector, fvPatchField, volMesh > volVectorField
Tensor< scalar > tensor
Definition symmTensor.H:57
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
List< cell > cellList
List of cell.
Definition cellListFwd.H:41
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
Definition curveTools.C:75
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299