sensitivitySurfacePointsIncompressible.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-2020 PCOpt/NTUA
9  Copyright (C) 2013-2020 FOSS GP
10  Copyright (C) 2019-2020 OpenCFD Ltd.
11 -------------------------------------------------------------------------------
12 License
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 
32 #include "syncTools.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 namespace incompressible
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 defineTypeNameAndDebug(sensitivitySurfacePoints, 0);
46 (
47  adjointSensitivity,
48  sensitivitySurfacePoints,
49  dictionary
50 );
51 
52 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
53 
55 {
57  dict().getOrDefault<bool>("includeSurfaceArea", false);
59  dict().getOrDefault<bool>("includePressure", true);
61  dict().getOrDefault<bool>("includeGradStressTerm", true);
63  dict().getOrDefault<bool>("includeTransposeStresses", true);
65  dict().getOrDefault<bool>("includeDivTerm", false);
67  dict().getOrDefault<bool>
68  (
69  "includeDistance",
70  adjointVars_.adjointTurbulence().ref().includeDistance()
71  );
73  dict().getOrDefault<bool>("includeMeshMovement", true);
75  dict().getOrDefault<bool>("includeObjectiveContribution", true);
76 
77  // Allocate new solvers if necessary
78  if (includeDistance_ && eikonalSolver_.empty())
79  {
80  eikonalSolver_.reset
81  (
83  (
84  mesh_,
85  dict(),
88  sensitivityPatchIDs_
89  )
90  );
91  }
92 
94  {
96  (
98  (
99  mesh_,
100  dict(),
101  *this,
102  sensitivityPatchIDs_,
104  )
105  );
106  }
107 }
108 
109 
111 {
112  // Solve extra equations if necessary
113  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
114  autoPtr<boundaryVectorField> distanceSensPtr(nullptr);
115  if (includeDistance_)
116  {
117  eikonalSolver_->solve();
118  distanceSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
119  const boundaryVectorField& sens =
120  eikonalSolver_->distanceSensitivities();
121  for (const label patchI : sensitivityPatchIDs_)
122  {
123  distanceSensPtr()[patchI] = sens[patchI];
124  }
125  }
126 
127  autoPtr<boundaryVectorField> meshMovementSensPtr(nullptr);
129  {
130  meshMovementSolver_->solve();
131  meshMovementSensPtr.reset(createZeroBoundaryPtr<vector>(mesh_));
132  const boundaryVectorField& sens =
133  meshMovementSolver_->meshMovementSensitivities();
134  for (const label patchI : sensitivityPatchIDs_)
135  {
136  meshMovementSensPtr()[patchI] = sens[patchI];
137  }
138  }
139 
140  // Add to other terms multiplying dxFace/dxPoints
141  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142  for (const label patchI : sensitivityPatchIDs_)
143  {
144  const fvPatch& patch = mesh_.boundary()[patchI];
145  tmp<vectorField> tnf = patch.nf();
146  const scalarField& magSf = patch.magSf();
147  // Distance related terms
148  if (includeDistance_)
149  {
150  wallFaceSens_()[patchI] += distanceSensPtr()[patchI];
151  }
152 
153  // Mesh movement related terms
155  {
156  wallFaceSens_()[patchI] += meshMovementSensPtr()[patchI];
157  }
158 
159  // Add local face area
160  //~~~~~~~~~~~~~~~~~~~~
161  // Sensitivities DO include locale surface area, to get
162  // the correct weighting from the contributions of various faces.
163  // Normalized at the end.
164  // dSfdbMult already includes the local area. No need to re-multiply
165  wallFaceSens_()[patchI] *= magSf;
166  dnfdbMult_()[patchI] *= magSf;
167  }
168 }
169 
170 
172 {
173  // Geometric (or "direct") sensitivities are better computed directly on
174  // the points. Compute them and add the ones that depend on dxFace/dxPoint
175  for (const label patchI : sensitivityPatchIDs_)
176  {
177  const fvPatch& patch = mesh_.boundary()[patchI];
178  vectorField nf(patch.nf());
179 
180  // Point sens result for patch
181  vectorField& pointPatchSens = wallPointSensVecPtr_()[patchI];
182 
183  // Face sens for patch
184  const vectorField& facePatchSens = wallFaceSens_()[patchI];
185 
186  // Geometry variances
187  const vectorField& dSfdbMultPatch = dSfdbMult_()[patchI];
188  const vectorField& dnfdbMultPatch = dnfdbMult_()[patchI];
189 
190  // Correspondance of local point addressing to global point addressing
191  const labelList& meshPoints = patch.patch().meshPoints();
192 
193  // List with mesh faces. Global addressing
194  const faceList& faces = mesh_.faces();
195 
196  // Each local patch point belongs to these local patch faces
197  // (local numbering)
198  const labelListList& patchPointFaces = patch.patch().pointFaces();
199 
200  // Index of first face in patch
201  const label patchStartIndex = patch.start();
202 
203  // Geometry differentiation engine
204  deltaBoundary dBoundary(mesh_);
205 
206  // Loop over patch points.
207  // Collect contributions from each boundary face this point belongs to
208  forAll(meshPoints, ppI)
209  {
210  const labelList& pointFaces = patchPointFaces[ppI];
211  forAll(pointFaces, pfI)
212  {
213  label localFaceIndex = pointFaces[pfI];
214  label globalFaceIndex = patchStartIndex + localFaceIndex;
215  const face& faceI = faces[globalFaceIndex];
216 
217  // Point coordinates. All indices in global numbering
218  pointField p(faceI.points(mesh_.points()));
219  tensorField p_d(faceI.size(), Zero);
220  forAll(faceI, facePointI)
221  {
222  if (faceI[facePointI] == meshPoints[ppI])
223  {
224  p_d[facePointI] = tensor::I;
225  }
226  }
227  tensorField deltaNormals =
228  dBoundary.makeFaceCentresAndAreas_d(p, p_d);
229 
230  // Element [0] is the variation in the face center
231  // (dxFace/dxPoint)
232  const tensor& deltaCf = deltaNormals[0];
233  pointPatchSens[ppI] += facePatchSens[localFaceIndex] & deltaCf;
234 
235  // Term multiplying d(Sf)/d(point displacement) and
236  // d(nf)/d(point displacement)
237  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238  if (includeObjective_)
239  {
240  // Element [1] is the variation in the (dimensional) normal
241  const tensor& deltaSf = deltaNormals[1];
242  pointPatchSens[ppI] +=
243  dSfdbMultPatch[localFaceIndex] & deltaSf;
244 
245  // Element [2] is the variation in the unit normal
246  const tensor& deltaNf = deltaNormals[2];
247  pointPatchSens[ppI] +=
248  dnfdbMultPatch[localFaceIndex] & deltaNf;
249  }
250  }
251  }
252  }
253 }
254 
255 
257 (
258  vectorField& pointNormals,
259  scalarField& pointMagSf
260 )
261 {
262  for (const label patchI : sensitivityPatchIDs_)
263  {
264  const fvPatch& patch = mesh_.boundary()[patchI];
265  const scalarField& magSf = patch.magSf();
266  vectorField nf(patch.nf());
267 
268  // Correspondance of local point addressing to global point addressing
269  const labelList& meshPoints = patch.patch().meshPoints();
270 
271  // Each local patch point belongs to these local patch faces
272  // (local numbering)
273  const labelListList& patchPointFaces = patch.patch().pointFaces();
274 
275  // Loop over patch points
276  forAll(meshPoints, ppI)
277  {
278  const labelList& pointFaces = patchPointFaces[ppI];
279  forAll(pointFaces, pfI)
280  {
281  const label localFaceIndex = pointFaces[pfI];
282 
283  // Accumulate information for point normals
284  pointNormals[meshPoints[ppI]] += nf[localFaceIndex];
285  pointMagSf[meshPoints[ppI]] += magSf[localFaceIndex];
286  }
287  }
288  }
289 
291  (
292  mesh_,
293  pointNormals,
296  );
298  (
299  mesh_,
300  pointMagSf,
302  scalar(0)
303  );
304 }
305 
306 
308 {
309  word suffix(dict().getOrDefault<word>("suffix", word::null));
310  // Determine suffix for fields holding the sens
312  {
314  (
315  adjointVars_.solverName() + "ESI" + suffix
316  );
317  }
318  else
319  {
321  (
322  adjointVars_.solverName() + "SI" + suffix
323  );
324  }
325 }
326 
327 
328 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
329 
330 sensitivitySurfacePoints::sensitivitySurfacePoints
331 (
332  const fvMesh& mesh,
333  const dictionary& dict,
334  incompressibleVars& primalVars,
335  incompressibleAdjointVars& adjointVars,
338 )
339 :
341  (
342  mesh,
343  dict,
344  primalVars,
345  adjointVars,
348  ),
350  includeSurfaceArea_(false),
351  includePressureTerm_(false),
352  includeGradStressTerm_(false),
353  includeTransposeStresses_(false),
354  includeDivTerm_(false),
355  includeDistance_(false),
356  includeMeshMovement_(false),
357  includeObjective_(false),
358  eikonalSolver_(nullptr),
359  meshMovementSolver_(nullptr),
360  wallFaceSens_(createZeroBoundaryPtr<vector>(mesh_)),
361  dSfdbMult_(createZeroBoundaryPtr<vector>(mesh_)),
362  dnfdbMult_(createZeroBoundaryPtr<vector>(mesh_))
363 
364 {
365  read();
366 
367  // Allocate boundary field pointer
368  wallPointSensVecPtr_.reset(createZeroBoundaryPointFieldPtr<vector>(mesh_));
369  wallPointSensNormalPtr_.reset
370  (
371  createZeroBoundaryPointFieldPtr<scalar>(mesh_)
372  );
373  wallPointSensNormalVecPtr_.reset
374  (
375  createZeroBoundaryPointFieldPtr<vector>(mesh_)
376  );
377 
378  // Allocate appropriate space for sensitivities
379  label nTotalPoints(0);
380  for (const label patchI : sensitivityPatchIDs_)
381  {
382  label nPoints = mesh_.boundaryMesh()[patchI].nPoints();
383  nTotalPoints += returnReduce(nPoints, sumOp<label>());
384  }
385 
386  // Derivatives for all (x,y,z) components of the displacement are kept
387  derivatives_ = scalarField(3*nTotalPoints, Zero);
388 }
389 
390 
391 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
392 
394 {
396  {
397  if (eikonalSolver_.valid())
398  {
399  eikonalSolver_().readDict(dict);
400  }
401 
402  if (meshMovementSolver_.valid())
403  {
404  meshMovementSolver_().readDict(dict);
405  }
406 
407  return true;
408  }
409 
410  return false;
411 }
412 
413 
415 {
416  // Grab references
417  const volScalarField& p = primalVars_.p();
418  const volVectorField& U = primalVars_.U();
419 
420  const volScalarField& pa = adjointVars_.pa();
421  const volVectorField& Ua = adjointVars_.Ua();
424 
425  DebugInfo
426  << " Calculating auxilary quantities " << endl;
427 
428  // Fields needed to calculate adjoint sensitivities
429  volScalarField nuEff(adjointTurbulence->nuEff());
430  volTensorField gradUa(fvc::grad(Ua));
431  volTensorField gradU(fvc::grad(U));
432 
433  // Explicitly correct the boundary gradient to get rid of the
434  // tangential component
435  forAll(mesh_.boundary(), patchI)
436  {
437  const fvPatch& patch = mesh_.boundary()[patchI];
438  if (isA<wallFvPatch>(patch))
439  {
440  tmp<vectorField> tnf = mesh_.boundary()[patchI].nf();
441  const vectorField& nf = tnf();
442  gradU.boundaryFieldRef()[patchI] =
443  nf*U.boundaryField()[patchI].snGrad();
444  }
445  }
446 
447  // Auxiliary terms
448  volVectorField gradp(fvc::grad(p));
449  volTensorField stress(nuEff*(gradU + T(gradU)));
450  autoPtr<volVectorField> stressXPtr
451  (
452  createZeroFieldPtr<vector>(mesh_, "stressX", stress.dimensions())
453  );
454  autoPtr<volVectorField> stressYPtr
455  (
456  createZeroFieldPtr<vector>(mesh_, "stressY", stress.dimensions())
457  );
458  autoPtr<volVectorField> stressZPtr
459  (
460  createZeroFieldPtr<vector>(mesh_, "stressZ", stress.dimensions())
461  );
462 
463  stressXPtr().replace(0, stress.component(0));
464  stressXPtr().replace(1, stress.component(1));
465  stressXPtr().replace(2, stress.component(2));
466 
467  stressYPtr().replace(0, stress.component(3));
468  stressYPtr().replace(1, stress.component(4));
469  stressYPtr().replace(2, stress.component(5));
470 
471  stressZPtr().replace(0, stress.component(6));
472  stressZPtr().replace(1, stress.component(7));
473  stressZPtr().replace(2, stress.component(8));
474 
475  volTensorField gradStressX(fvc::grad(stressXPtr()));
476  volTensorField gradStressY(fvc::grad(stressYPtr()));
477  volTensorField gradStressZ(fvc::grad(stressZPtr()));
478 
479  // Solve extra equations if necessary
480  if (includeDistance_)
481  {
482  eikonalSolver_->accumulateIntegrand(dt);
483  }
484 
485  autoPtr<boundaryVectorField> meshMovementSensPtr(nullptr);
487  {
488  meshMovementSolver_->accumulateIntegrand(dt);
489  }
490 
491  // Terms from the adjoint turbulence model
492  const boundaryVectorField& adjointTMsensitivities =
493  adjointTurbulence->wallShapeSensitivities();
494 
495  // Objective references
497 
498  DebugInfo
499  << " Calculating adjoint sensitivity. " << endl;
500 
501  // The face-based part of the sensitivities, i.e. terms that multiply
502  // dxFace/dxPoint.
503  for (const label patchI : sensitivityPatchIDs_)
504  {
505  const fvPatch& patch = mesh_.boundary()[patchI];
506  tmp<vectorField> tnf = patch.nf();
507  const vectorField& nf = tnf();
508 
509  // Adjoint stress term
510  // vectorField stressTerm
511  // (
512  // -(nf & DUa.boundaryField()[patchI])
513  // *nuEff.boundaryField()[patchI]
514  // & gradU.boundaryField()[patchI].T();
515  // )
516 
517  vectorField stressTerm
518  (
519  - (
520  Ua.boundaryField()[patchI].snGrad()
521  & U.boundaryField()[patchI].snGrad()
522  )
523  * nuEff.boundaryField()[patchI]
524  * nf
525  );
526 
527  vectorField gradStressTerm(patch.size(), Zero);
529  {
530  // Terms corresponding to contributions from converting delta to
531  // thetas are added through the corresponding adjoint boundary
532  // conditions instead of grabing contributions from the objective
533  // function. Useful to have a unified formulation for low- and
534  // high-re meshes
535  const fvPatchVectorField& Uab = Ua.boundaryField()[patchI];
536  gradStressTerm = (-((Uab & nf)*gradp.boundaryField()[patchI]));
537  gradStressTerm +=
538  (
539  Uab.component(0)*gradStressX.boundaryField()[patchI]
540  + Uab.component(1)*gradStressY.boundaryField()[patchI]
541  + Uab.component(2)*gradStressZ.boundaryField()[patchI]
542  ) & nf;
543  }
544 
546  {
547  stressTerm -=
548  nuEff.boundaryField()[patchI]
549  *(
550  // Note: in case of laminar or low-Re flows,
551  // includes a spurious tangential gradUa component
552  // (gradUa.boundaryField()[patchI] & nf)
553  ((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
554  & U.boundaryField()[patchI].snGrad()
555  )
556  * nf;
557  }
558 
559  if (includeDivTerm_)
560  {
561  stressTerm +=
562  scalar(1./3.)*nuEff.boundaryField()[patchI]
563  * (
564  ((Ua.boundaryField()[patchI].snGrad() &nf)*nf)
565  & U.boundaryField()[patchI].snGrad()
566  )
567  *nf;
568  }
569 
570  // Adjoint pressure terms
571  vectorField pressureTerm(patch.size(), Zero);
573  {
574  pressureTerm =
575  (
576  (nf * pa.boundaryField()[patchI])
577  & U.boundaryField()[patchI].snGrad()
578  )
579  *nf;
580  }
581 
582  vectorField dxdbMultiplierTot(patch.size(), Zero);
583  if (includeObjective_)
584  {
585  // Term from objectives multiplying dxdb
586  forAll(functions, funcI)
587  {
588  const scalar wei = functions[funcI].weight();
589  // dt added in wallFaceSens_
590  dxdbMultiplierTot +=
591  wei*functions[funcI].dxdbDirectMultiplier(patchI);
592 
593  // Fill in multipliers of d(Sf)/db and d(nf)/db
594  dSfdbMult_()[patchI] +=
595  wei*dt*functions[funcI].dSdbMultiplier(patchI);
596  dnfdbMult_()[patchI] +=
597  wei*dt*functions[funcI].dndbMultiplier(patchI);
598  }
599  }
600 
601  // Fill in dxFace/dxPoint multiplier.
602  // Missing geometric contributions which are directly computed on the
603  // points
604  wallFaceSens_()[patchI] +=
605  (
606  stressTerm
607  + gradStressTerm
608  + pressureTerm
609  + adjointTMsensitivities[patchI]
610  + dxdbMultiplierTot
611  )*dt;
612  }
613 }
614 
615 
617 {
618  // Add remaining parts to term multiplying dxFace/dxPoints
619  // Solves for post-processing PDEs
621 
622  // Geometric (or "direct") sensitivities are better computed directly on
623  // the points. Compute them and add the ones that depend on dxFace/dxPoint
625 
626  // polyPatch::pointNormals will give the wrong result for points
627  // belonging to multiple patches or patch-processorPatch intersections.
628  // Keeping a mesh-wide field to allow easy reduction using syncTools.
629  // A bit expensive? Better way?
630  vectorField pointNormals(mesh_.nPoints(), Zero);
631  scalarField pointMagSf(mesh_.nPoints(), Zero);
632  constructGlobalPointNormalsAndAreas(pointNormals, pointMagSf);
633 
634  // Do parallel communications to avoid wrong values at processor boundaries
635  // Global field for accumulation
636  vectorField pointSensGlobal(mesh_.nPoints(), Zero);
637  for (const label patchI : sensitivityPatchIDs_)
638  {
639  const labelList& meshPoints = mesh_.boundaryMesh()[patchI].meshPoints();
640  forAll(meshPoints, ppI)
641  {
642  const label globaPointI = meshPoints[ppI];
643  pointSensGlobal[globaPointI] +=
644  wallPointSensVecPtr_()[patchI][ppI];
645  }
646  }
647 
648  // Accumulate dJ/dx_i
650  (
651  mesh_,
652  pointSensGlobal,
655  );
656 
657  // Transfer back to local fields
658  for (const label patchI : sensitivityPatchIDs_)
659  {
660  const labelList& meshPoints =
661  mesh_.boundaryMesh()[patchI].meshPoints();
662  wallPointSensVecPtr_()[patchI].map(pointSensGlobal, meshPoints);
663  }
664 
665  // Compute normal sens and append to return field
666  label nPassedDVs(0);
667  for (const label patchI : sensitivityPatchIDs_)
668  {
669  const polyPatch& patch = mesh_.boundaryMesh()[patchI];
670  List<scalarField> procPatchSens(Pstream::nProcs());
671  //if (patch.size()>0)
672  {
673  const labelList& meshPoints = patch.meshPoints();
674 
675  // Avoid storing unit point normals in the global list since we
676  // might divide multiple times with the number of faces belonging
677  // to the point. Instead do the division locally, per patch use
678  vectorField patchPointNormals(pointNormals, meshPoints);
679  patchPointNormals /= mag(patchPointNormals) + VSMALL;
680  if (!includeSurfaceArea_)
681  {
682  wallPointSensVecPtr_()[patchI] /=
683  scalarField(pointMagSf, meshPoints);
684  }
685  wallPointSensNormalPtr_()[patchI] =
686  wallPointSensVecPtr_()[patchI]
687  & patchPointNormals;
688  wallPointSensNormalVecPtr_()[patchI] =
689  wallPointSensNormalPtr_()[patchI]
690  *patchPointNormals;
691 
692  // 1. Gather sens from all processors for this patch and communicate
693  // them back. Potentially large memory overhead but the rest of the
694  // code structure assumes that all procs know all sensitivity
695  // derivatives
696  //
697  // 2. Transfer vectorial sensitivities to scalarField.
698  // Needed since the normal point vector is wrongly computed at patch
699  // boundaries and cannot be used to reconstruct a vectorial movement
700  // from just its normal component
701  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
702 
703  procPatchSens[Pstream::myProcNo()].setSize
704  (
705  3*wallPointSensNormalVecPtr_()[patchI].size()
706  );
707  scalarField& patchScalarSens = procPatchSens[Pstream::myProcNo()];
708  forAll(wallPointSensNormalVecPtr_()[patchI], ptI)
709  {
710  patchScalarSens[3*ptI] =
711  wallPointSensNormalVecPtr_()[patchI][ptI].x();
712  patchScalarSens[3*ptI + 1] =
713  wallPointSensNormalVecPtr_()[patchI][ptI].y();
714  patchScalarSens[3*ptI + 2] =
715  wallPointSensNormalVecPtr_()[patchI][ptI].z();
716  }
717  Pstream::gatherList(procPatchSens);
718  Pstream::scatterList(procPatchSens);
719 
720  forAll(procPatchSens, procI)
721  {
722  const scalarField& procSens = procPatchSens[procI];
723  forAll(procSens, dvI)
724  {
725  derivatives_[nPassedDVs + dvI] = procSens[dvI];
726  }
727  nPassedDVs += procSens.size();
728  }
729  }
730  }
731 }
732 
733 
735 {
736  // Reset terms in post-processing PDEs
737  if (includeDistance_)
738  {
739  eikonalSolver_->reset();
740  }
742  {
743  meshMovementSolver_->reset();
744  }
745 
746  // Reset local fields to zero
750 
751  // Reset sensitivity fields
754 }
755 
756 
758 {
759  setSuffixName();
762 }
763 
764 
765 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
766 
767 } // End namespace Foam
768 } // End namespace incompressible
769 
770 // ************************************************************************* //
Foam::fvPatchField< vector >
Foam::incompressible::sensitivitySurfacePoints::wallFaceSens_
autoPtr< boundaryVectorField > wallFaceSens_
The face-based part of the sensitivities.
Definition: sensitivitySurfacePointsIncompressible.H:102
Foam::sensitivity::dict
const dictionary & dict() const
Return the construction dictionary.
Definition: sensitivity.C:57
Foam::incompressible::adjointSensitivity::derivatives_
scalarField derivatives_
Definition: adjointSensitivityIncompressible.H:84
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:109
Foam::Tensor< scalar >
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1038
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::objectiveManager
class for managing incompressible objective functions.
Definition: objectiveManager.H:54
Foam::incompressible::sensitivitySurfacePoints::includeTransposeStresses_
bool includeTransposeStresses_
Include the transpose part of the adjoint stresses.
Definition: sensitivitySurfacePointsIncompressible.H:79
Foam::GeometricField::component
tmp< GeometricField< cmptType, PatchField, GeoMesh > > component(const direction) const
Return a component of the field.
Foam::variablesSet::solverName
const word & solverName() const
Return solver name.
Definition: variablesSet.C:84
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::fvc::grad
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:54
Foam::deltaBoundary
Differentiation of the mesh data structure.
Definition: deltaBoundary.H:58
Foam::face::points
pointField points(const UList< point > &points) const
Return the points corresponding to this face.
Definition: faceI.H:85
sensitivitySurfacePointsIncompressible.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::incompressible::sensitivitySurfacePoints::dnfdbMult_
autoPtr< boundaryVectorField > dnfdbMult_
Definition: sensitivitySurfacePointsIncompressible.H:106
Foam::Tensor< scalar >::I
static const Tensor I
Definition: Tensor.H:85
Foam::incompressible::defineTypeNameAndDebug
defineTypeNameAndDebug(adjointEikonalSolver, 0)
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::incompressible::sensitivitySurfacePoints::accumulateIntegrand
virtual void accumulateIntegrand(const scalar dt)
Accumulate sensitivity integrands.
Definition: sensitivitySurfacePointsIncompressible.C:414
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::incompressible::sensitivitySurfacePoints::constructGlobalPointNormalsAndAreas
void constructGlobalPointNormalsAndAreas(vectorField &pointNormals, scalarField &pointMagSf)
Construct globally correct point normals and point areas.
Definition: sensitivitySurfacePointsIncompressible.C:257
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:215
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:107
Foam::incompressible::sensitivitySurfacePoints::includePressureTerm_
bool includePressureTerm_
Include the adjoint pressure term in sens computation.
Definition: sensitivitySurfacePointsIncompressible.H:73
Foam::incompressible::sensitivitySurfacePoints::meshMovementSolver_
autoPtr< adjointMeshMovementSolver > meshMovementSolver_
Definition: sensitivitySurfacePointsIncompressible.H:95
Foam::incompressible::sensitivitySurfacePoints::dSfdbMult_
autoPtr< boundaryVectorField > dSfdbMult_
Multipliers of d(Sf)/db and d(nf)/db.
Definition: sensitivitySurfacePointsIncompressible.H:105
Foam::incompressible::sensitivitySurfacePoints::read
void read()
Read controls and update solver pointers if necessary.
Definition: sensitivitySurfacePointsIncompressible.C:54
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::incompressibleVars::p
const volScalarField & p() const
Return const reference to pressure.
Definition: incompressibleVars.C:305
syncTools.H
Foam::incompressibleAdjointVars
Class including all adjoint fields for incompressible flows.
Definition: incompressibleAdjointVars.H:52
Foam::fv::optionAdjointList
Definition: fvOptionAdjointList.H:59
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:747
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::incompressibleVars::RASModelVariables
const autoPtr< incompressible::RASModelVariables > & RASModelVariables() const
Return const reference to the turbulence model variables.
Definition: incompressibleVars.C:444
Foam::shapeSensitivitiesBase
Definition: shapeSensitivitiesBase.H:63
Foam::incompressible::sensitivitySurfacePoints::includeDivTerm_
bool includeDivTerm_
Include the term from the deviatoric part of the stresses.
Definition: sensitivitySurfacePointsIncompressible.H:82
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::incompressible::adjointEikonalSolver
Solver of the adjoint to the eikonal PDE.
Definition: adjointEikonalSolverIncompressible.H:146
Foam::incompressible::addToRunTimeSelectionTable
addToRunTimeSelectionTable(adjointSensitivity, sensitivityBezier, dictionary)
Foam::shapeSensitivitiesBase::write
void write()
Write sensitivity fields.
Definition: shapeSensitivitiesBase.C:216
Foam::incompressible::adjointSensitivity
Abstract base class for adjoint-based sensitivities in incompressible flows.
Definition: adjointSensitivityIncompressible.H:76
Foam::sensitivity::mesh_
const fvMesh & mesh_
Definition: sensitivity.H:69
Foam::Field< scalar >
Foam::sensitivity::readDict
virtual bool readDict(const dictionary &dict)
Read dictionary if changed.
Definition: sensitivity.C:63
Foam::incompressible::sensitivitySurfacePoints::eikonalSolver_
autoPtr< adjointEikonalSolver > eikonalSolver_
Definition: sensitivitySurfacePointsIncompressible.H:93
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:67
Foam::incompressible::sensitivitySurfacePoints::readDict
virtual bool readDict(const dictionary &dict)
Read dict if changed.
Definition: sensitivitySurfacePointsIncompressible.C:393
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::incompressibleAdjointMeanFlowVars::pa
const volScalarField & pa() const
Return const reference to pressure.
Definition: incompressibleAdjointMeanFlowVars.C:147
Foam::incompressibleVars::U
const volVectorField & U() const
Return const reference to velocity.
Definition: incompressibleVars.C:331
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
Foam::incompressible::adjointSensitivity::clearSensitivities
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
Definition: adjointSensitivityIncompressible.C:130
Foam::incompressible::sensitivitySurfacePoints::includeMeshMovement_
bool includeMeshMovement_
Include mesh movement variation in sens computation.
Definition: sensitivitySurfacePointsIncompressible.H:88
Foam::incompressibleAdjointMeanFlowVars::Ua
const volVectorField & Ua() const
Return const reference to velocity.
Definition: incompressibleAdjointMeanFlowVars.C:173
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::incompressible::sensitivitySurfacePoints::includeSurfaceArea_
bool includeSurfaceArea_
Include surface area in sens computation.
Definition: sensitivitySurfacePointsIncompressible.H:70
Foam::incompressible::sensitivitySurfacePoints::includeObjective_
bool includeObjective_
Include terms directly emerging from the objective function.
Definition: sensitivitySurfacePointsIncompressible.H:91
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::deltaBoundary::makeFaceCentresAndAreas_d
vectorField makeFaceCentresAndAreas_d(const pointField &p, const pointField &p_d)
Definition: deltaBoundary.C:72
Foam::incompressible::adjointSensitivity::adjointVars_
incompressibleAdjointVars & adjointVars_
Definition: adjointSensitivityIncompressible.H:86
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::incompressible::adjointSensitivity::primalVars_
incompressibleVars & primalVars_
Definition: adjointSensitivityIncompressible.H:85
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:445
Foam::incompressible::sensitivitySurfacePoints::write
virtual void write(const word &baseName=word::null)
Write sensitivity fields.
Definition: sensitivitySurfacePointsIncompressible.C:757
Foam::fvMesh::boundary
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:555
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
U
U
Definition: pEqn.H:72
Foam::incompressible::sensitivitySurfacePoints::includeDistance_
bool includeDistance_
Include distance variation in sens computation.
Definition: sensitivitySurfacePointsIncompressible.H:85
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1063
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::incompressible::sensitivitySurfacePoints::includeGradStressTerm_
bool includeGradStressTerm_
Include the term containing the grad of the stress at the boundary.
Definition: sensitivitySurfacePointsIncompressible.H:76
Foam::GeometricField::Boundary
Definition: GeometricField.H:114
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:354
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::GeometricField::boundaryFieldRef
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
Definition: GeometricField.C:783
Foam::incompressibleAdjointVars::adjointTurbulence
const autoPtr< incompressibleAdjoint::adjointRASModel > & adjointTurbulence() const
Return const reference to the adjointRASModel.
Definition: incompressibleAdjointVars.C:70
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::incompressible::adjointMeshMovementSolver
Solver of the adjoint to the Laplace grid displacement equation.
Definition: adjointMeshMovementSolverIncompressible.H:68
Foam::shapeSensitivitiesBase::clearSensitivities
void clearSensitivities()
Zero sensitivity fields and their constituents.
Definition: shapeSensitivitiesBase.C:175
Foam::primitiveMesh::nPoints
label nPoints() const
Number of mesh points.
Definition: primitiveMeshI.H:37
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::incompressible::sensitivitySurfacePoints::setSuffixName
void setSuffixName()
Set suffix name for sensitivity fields.
Definition: sensitivitySurfacePointsIncompressible.C:307
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::plusEqOp
Definition: ops.H:72
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:122
Foam::shapeSensitivitiesBase::setSuffix
void setSuffix(const word &suffix)
Set suffix.
Definition: shapeSensitivitiesBase.C:223
Foam::GeometricField< scalar, fvPatchField, volMesh >
fvOptionsAdjoint
fv::IOoptionListAdjoint fvOptionsAdjoint(mesh)
Foam::incompressible::sensitivitySurfacePoints::finaliseFaceMultiplier
void finaliseFaceMultiplier()
Definition: sensitivitySurfacePointsIncompressible.C:110
Foam::incompressible::sensitivitySurfacePoints::clearSensitivities
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
Definition: sensitivitySurfacePointsIncompressible.C:734
Foam::incompressible::sensitivitySurfacePoints::finalisePointSensitivities
void finalisePointSensitivities()
Definition: sensitivitySurfacePointsIncompressible.C:171
Foam::incompressible::sensitivitySurfacePoints::assembleSensitivities
virtual void assembleSensitivities()
Assemble sensitivities.
Definition: sensitivitySurfacePointsIncompressible.C:616
Foam::incompressibleVars
Base class for solution control classes.
Definition: incompressibleVars.H:54
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
Foam::incompressible::adjointSensitivity::write
virtual void write(const word &baseName=word::null)
Write sensitivity fields.
Definition: adjointSensitivityIncompressible.C:140
Foam::objectiveManager::getObjectiveFunctions
PtrList< objective > & getObjectiveFunctions()
Return reference to objective functions.
Definition: objectiveManager.C:247
Foam::incompressible::adjointSensitivity::objectiveManager_
objectiveManager & objectiveManager_
Definition: adjointSensitivityIncompressible.H:87