sensitivityVolBSplinesIncompressible.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-2019 PCOpt/NTUA
9  Copyright (C) 2013-2019 FOSS GP
10  Copyright (C) 2019 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 "IOmanip.H"
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 namespace incompressible
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 defineTypeNameAndDebug(sensitivityVolBSplines, 0);
46 (
47  adjointSensitivity,
48  sensitivityVolBSplines,
49  dictionary
50 );
51 
52 // * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
53 
55 {
57  {
58  label passedCPs = 0;
60  forAll(boxes, iNURB)
61  {
62  label nb = boxes[iNURB].getControlPoints().size();
63  for (label cpI = 0; cpI < nb; cpI++)
64  {
65  vector dSdbSensCP(Zero);
66  vector dndbSensCP(Zero);
67  for (const label patchI : sensitivityPatchIDs_)
68  {
69  tensorField dSdb
70  (
71  boxes[iNURB].dndbBasedSensitivities(patchI, cpI)
72  );
73  dSdbSensCP += gSum(dSfdbMult_()[patchI] & dSdb);
74 
75  tensorField dndb
76  (
77  boxes[iNURB].dndbBasedSensitivities
78  (
79  patchI,
80  cpI,
81  false
82  )
83  );
84  dndbSensCP += gSum((dnfdbMult_()[patchI] & dndb));
85  }
86  dSdbSens_[passedCPs + cpI] = dSdbSensCP;
87  dndbSens_[passedCPs + cpI] = dndbSensCP;
88  }
89  boxes[iNURB].boundControlPointMovement(dSdbSens_);
90  boxes[iNURB].boundControlPointMovement(dndbSens_);
91  passedCPs += nb;
92  }
93 
94  passedCPs = 0;
95  forAll(boxes, iNURB)
96  {
97  vectorField sensDxDbDirect =
98  boxes[iNURB].computeControlPointSensitivities
99  (
100  dxdbDirectMult_(),
101  sensitivityPatchIDs_.toc()
102  );
103 
104  // Transfer to global list
105  forAll(sensDxDbDirect, cpI)
106  {
107  dxdbDirectSens_[passedCPs + cpI] = sensDxDbDirect[cpI];
108  }
109  boxes[iNURB].boundControlPointMovement(dxdbDirectSens_);
110  passedCPs += sensDxDbDirect.size();
111  }
112  }
113 }
114 
115 
116 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
117 
118 sensitivityVolBSplines::sensitivityVolBSplines
119 (
120  const fvMesh& mesh,
121  const dictionary& dict,
122  incompressibleVars& primalVars,
123  incompressibleAdjointVars& adjointVars,
126 )
127 :
128  SIBase
129  (
130  mesh,
131  dict,
132  primalVars,
133  adjointVars,
136  ),
137  volBSplinesBase_
138  (
140  ),
141 
142  flowSens_(0),
143  dSdbSens_(0),
144  dndbSens_(0),
145  dxdbDirectSens_(0),
146 
147  derivativesFolder_("optimisation"/type() + "Derivatives")
148 {
149  // No boundary field pointers need to be allocated
150  label nCPs = volBSplinesBase_.getTotalControlPointsNumber();
151  derivatives_ = scalarField(3*nCPs, Zero);
152  flowSens_ = vectorField(nCPs, Zero);
153  dSdbSens_ = vectorField(nCPs, Zero);
154  dndbSens_ = vectorField(nCPs, Zero);
155  dxdbDirectSens_ = vectorField(nCPs, Zero);
156 
157  // Create folder to store sensitivities
158  mkDir(derivativesFolder_);
159 }
160 
161 
162 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
163 
165 {
166  // Assemble the sensitivity map
167  // Solves for the post-processing equations and adds their contribution to
168  // the sensitivity map
170 
171  // Finalise sensitivities including dxFace/db
172  const boundaryVectorField& faceSens =
173  surfaceSensitivity_.getWallFaceSensVecBoundary();
174 
175  label passedCPs(0);
177  forAll(boxes, iNURB)
178  {
179  vectorField sens =
180  boxes[iNURB].computeControlPointSensitivities
181  (
182  faceSens,
183  sensitivityPatchIDs_.toc()
184  );
185  // Transfer to global list
186  forAll(sens, cpI)
187  {
188  flowSens_[passedCPs + cpI] = sens[cpI];
189  }
190  passedCPs += sens.size();
191 
192  boxes[iNURB].boundControlPointMovement(flowSens_);
193  }
194 
195  // Contribution from objective function
196  // Note:
197  // includeObjectiveContribution has to be set to false (false by default)
198  // in surfaceSensitivity, in order to avoid computing this term twice.
199  // Optionally avoided altogether if includeObjectiveContribution is set to
200  // false for sensitivityVolBSplines
202 
203  // Transform sensitivites to scalarField in order to cooperate with
204  // updateMethod
205  forAll(flowSens_, cpI)
206  {
207  derivatives_[3*cpI] =
208  flowSens_[cpI].x()
209  + dSdbSens_[cpI].x()
210  + dndbSens_[cpI].x()
211  + dxdbDirectSens_[cpI].x();
212  derivatives_[3*cpI + 1] =
213  flowSens_[cpI].y()
214  + dSdbSens_[cpI].y()
215  + dndbSens_[cpI].y()
216  + dxdbDirectSens_[cpI].y();
217  derivatives_[3*cpI + 2] =
218  flowSens_[cpI].z()
219  + dSdbSens_[cpI].z()
220  + dndbSens_[cpI].z()
221  + dxdbDirectSens_[cpI].z();
222  }
223 }
224 
225 
227 {
232 
234 }
235 
236 
237 void sensitivityVolBSplines::write(const word& baseName)
238 {
239  Info<< "Writing control point sensitivities to file" << endl;
240  if (Pstream::master())
241  {
242  OFstream derivFile
243  (
245  baseName + adjointVars_.solverName() + mesh_.time().timeName()
246  );
247  unsigned int widthDV =
248  max(int(Foam::name(derivatives_.size()).size()), int(3));
249  unsigned int width = IOstream::defaultPrecision() + 7;
250  derivFile
251  << setw(widthDV) << "#cp" << " "
252  << setw(width) << "total::x"<< " "
253  << setw(width) << "total::y"<< " "
254  << setw(width) << "total::z"<< " "
255  << setw(width) << "flow::x" << " "
256  << setw(width) << "flow::y" << " "
257  << setw(width) << "flow::z" << " "
258  << setw(width) << "dSdb::x" << " "
259  << setw(width) << "dSdb::y" << " "
260  << setw(width) << "dSdb::z" << " "
261  << setw(width) << "dndb::x" << " "
262  << setw(width) << "dndb::y" << " "
263  << setw(width) << "dndb::z" << " "
264  << setw(width) << "dxdbDirect::x" << " "
265  << setw(width) << "dxdbDirect::y" << " "
266  << setw(width) << "dxdbDirect::z" << endl;
267 
268  label passedCPs(0);
269  label lastActive(-1);
271  forAll(boxes, iNURB)
272  {
273  label nb = boxes[iNURB].getControlPoints().size();
274  const boolList& activeCPs = boxes[iNURB].getActiveCPs();
275  for (label iCP = 0; iCP < nb; iCP++)
276  {
277  if (activeCPs[iCP])
278  {
279  label globalCP = passedCPs + iCP;
280  if (globalCP!=lastActive + 1)
281  {
282  derivFile << "\n";
283  }
284  lastActive = globalCP;
285 
286  derivFile
287  << setw(widthDV) << globalCP << " "
288  << setw(width) << derivatives_[3*globalCP] << " "
289  << setw(width) << derivatives_[3*globalCP + 1] << " "
290  << setw(width) << derivatives_[3*globalCP + 2] << " "
291  << setw(width) << flowSens_[globalCP].x() << " "
292  << setw(width) << flowSens_[globalCP].y() << " "
293  << setw(width) << flowSens_[globalCP].z() << " "
294  << setw(width) << dSdbSens_[globalCP].x() << " "
295  << setw(width) << dSdbSens_[globalCP].y() << " "
296  << setw(width) << dSdbSens_[globalCP].z() << " "
297  << setw(width) << dndbSens_[globalCP].x() << " "
298  << setw(width) << dndbSens_[globalCP].y() << " "
299  << setw(width) << dndbSens_[globalCP].z() << " "
300  << setw(width) << dxdbDirectSens_[globalCP].x() << " "
301  << setw(width) << dxdbDirectSens_[globalCP].y() << " "
302  << setw(width) << dxdbDirectSens_[globalCP].z()
303  << endl;
304  }
305  }
306  passedCPs += nb;
307  }
308  }
309 }
310 
311 
312 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
313 
314 } // End namespace incompressible
315 } // End namespace Foam
316 
317 // ************************************************************************* //
Foam::incompressible::SIBase::dxdbDirectMult_
autoPtr< boundaryVectorField > dxdbDirectMult_
Definition: SIBaseIncompressible.H:73
Foam::incompressible::adjointSensitivity::derivatives_
scalarField derivatives_
Definition: adjointSensitivityIncompressible.H:84
Foam::incompressible::sensitivityVolBSplines::assembleSensitivities
virtual void assembleSensitivities()
Assemble sensitivities.
Definition: sensitivityVolBSplinesIncompressible.C:164
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::sensitivitySurface::assembleSensitivities
virtual void assembleSensitivities()
Assemble sensitivities.
Definition: sensitivitySurfaceIncompressible.C:610
Foam::variablesSet::solverName
const word & solverName() const
Return solver name.
Definition: variablesSet.C:84
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::incompressible::sensitivityVolBSplines::write
virtual void write(const word &baseName=word::null)
Write sensitivities to file.
Definition: sensitivityVolBSplinesIncompressible.C:237
Foam::incompressible::defineTypeNameAndDebug
defineTypeNameAndDebug(adjointEikonalSolver, 0)
Foam::volBSplinesBase
Class constructing a number of volumetric B-Splines boxes, read from dynamicMeshDict....
Definition: volBSplinesBase.H:59
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
sensitivityVolBSplinesIncompressible.H
Foam::incompressible::sensitivityVolBSplines::clearSensitivities
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
Definition: sensitivityVolBSplinesIncompressible.C:226
Foam::incompressible::sensitivityVolBSplines::volBSplinesBase_
volBSplinesBase & volBSplinesBase_
Reference to underlaying volumetric B-Splines morpher.
Definition: sensitivityVolBSplinesIncompressible.H:66
Foam::MeshObject< fvMesh, UpdateableMeshObject, volBSplinesBase >::New
static const volBSplinesBase & New(const fvMesh &mesh, Args &&... args)
Get existing or create a new MeshObject.
Definition: MeshObject.C:48
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:764
Foam::incompressible::SIBase
Base class for Surface Integral-based sensitivity derivatives.
Definition: SIBaseIncompressible.H:58
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::incompressible::SIBase::surfaceSensitivity_
sensitivitySurface surfaceSensitivity_
Surface sensitivities.
Definition: SIBaseIncompressible.H:68
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:594
Foam::incompressible::sensitivityVolBSplines::computeObjectiveContributions
void computeObjectiveContributions()
Definition: sensitivityVolBSplinesIncompressible.C:54
Foam::incompressibleAdjointVars
Class including all adjoint fields for incompressible flows.
Definition: incompressibleAdjointVars.H:52
Foam::fv::optionAdjointList
Definition: fvOptionAdjointList.H:59
Foam::incompressible::sensitivityVolBSplines::flowSens_
vectorField flowSens_
Flow related term.
Definition: sensitivityVolBSplinesIncompressible.H:69
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::incompressible::sensitivityVolBSplines::derivativesFolder_
fileName derivativesFolder_
Definition: sensitivityVolBSplinesIncompressible.H:81
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:54
Foam::incompressible::SIBase::clearSensitivities
virtual void clearSensitivities()
Zero sensitivity fields and their constituents.
Definition: SIBaseIncompressible.C:164
Foam::incompressible::sensitivityVolBSplines::dxdbDirectSens_
vectorField dxdbDirectSens_
Definition: sensitivityVolBSplinesIncompressible.H:79
Foam::incompressible::addToRunTimeSelectionTable
addToRunTimeSelectionTable(adjointSensitivity, sensitivityBezier, dictionary)
Foam::sensitivity::mesh_
const fvMesh & mesh_
Definition: sensitivity.H:69
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::Field< tensor >
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:65
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::incompressible::sensitivityVolBSplines::dndbSens_
vectorField dndbSens_
Term depending on delta (n)/delta b.
Definition: sensitivityVolBSplinesIncompressible.H:75
Foam::volBSplinesBase::boxesRef
PtrList< NURBS3DVolume > & boxesRef()
Get non-const reference to the vol. B-splines boxes.
Definition: volBSplinesBase.C:121
dict
dictionary dict
Definition: searchingEngine.H:14
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::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::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:99
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
Foam::incompressible::SIBase::includeObjective_
bool includeObjective_
Definition: SIBaseIncompressible.H:75
Foam::incompressible::sensitivityVolBSplines::dSdbSens_
vectorField dSdbSens_
Term depending on delta(n dS)/delta b.
Definition: sensitivityVolBSplinesIncompressible.H:72
Foam::incompressible::SIBase::dSfdbMult_
autoPtr< boundaryVectorField > dSfdbMult_
Fields related to direct sensitivities.
Definition: SIBaseIncompressible.H:71
Foam::GeometricField::Boundary
Definition: GeometricField.H:114
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision()
Return the default precision.
Definition: IOstream.H:325
Foam::Vector< scalar >
Foam::List< bool >
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::incompressible::SIBase::dnfdbMult_
autoPtr< boundaryVectorField > dnfdbMult_
Definition: SIBaseIncompressible.H:72
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:246
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::zero
static const Vector< scalar > zero
Definition: VectorSpace.H:115
fvOptionsAdjoint
fv::IOoptionListAdjoint fvOptionsAdjoint(mesh)
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
Foam::incompressibleVars
Base class for solution control classes.
Definition: incompressibleVars.H:54