BezierDesignVariables.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-2023 PCOpt/NTUA
9  Copyright (C) 2013-2023 FOSS GP
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "BezierDesignVariables.H"
30 #include "IOmanip.H"
32 
33 // * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(BezierDesignVariables, 0);
39  (
40  shapeDesignVariables,
41  BezierDesignVariables,
42  dictionary
43  );
44 }
45 
46 
47 // * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
48 
50 (
51  autoPtr<scalar> lowerBoundPtr,
52  autoPtr<scalar> upperBoundPtr
53 )
54 {
55  designVariables::readBounds(lowerBoundPtr, upperBoundPtr);
56 
57  if (dict_.found("lowerCPBounds"))
58  {
59  vector lowerCPBounds(dict_.get<vector>("lowerCPBounds"));
60  lowerBounds_.reset(new scalarField(getVars().size(), Zero));
61  setBounds(lowerBounds_, lowerCPBounds);
62  }
63 
64  if (dict_.found("upperCPBounds"))
65  {
66  vector upperCPBounds(dict_.get<vector>("upperCPBounds"));
68  setBounds(upperBounds_, upperCPBounds);
69  }
70 }
71 
72 
74 (
75  autoPtr<scalarField>& bounds,
76  const vector& cpBounds
77 )
78 {
79  bounds.reset(new scalarField(getVars().size(), Zero));
80  const label nCPs(bezier_.nBezier());
81  for (label iCP = 0; iCP < nCPs; ++iCP)
82  {
83  bounds()[iCP] = cpBounds.x();
84  bounds()[nCPs + iCP] = cpBounds.y();
85  bounds()[2*nCPs + iCP] = cpBounds.z();
86  }
87 }
88 
89 
92 (
93  const scalarField& correction
94 )
95 {
96  // Reset boundary movement field
97  dx_.primitiveFieldRef() = Zero;
98 
99  // Compute boundary movement using the derivatives of grid nodes
100  // wrt to the Bezier control points and the correction
101  const label nCPs(bezier_.nBezier());
102  auto tcpMovement(tmp<vectorField>::New(nCPs, Zero));
103  vectorField& cpMovement = tcpMovement.ref();
104  const boolListList& confineMovement = bezier_.confineMovement();
105 
106  forAll(cpMovement, cpI)
107  {
108  if (!confineMovement[0][cpI])
109  {
110  cpMovement[cpI].x() = correction[cpI];
111  }
112  if (!confineMovement[1][cpI])
113  {
114  cpMovement[cpI].y() = correction[nCPs + cpI];
115  }
116  if (!confineMovement[2][cpI])
117  {
118  cpMovement[cpI].z() = correction[2*nCPs + cpI];
119  }
120 
121  dx_ += (bezier_.dxidXj()[cpI] & cpMovement[cpI]);
122  }
123 
124  return tcpMovement;
125 }
126 
127 
129 (
130  label& cpI,
131  label& dir,
132  const label varID
133 ) const
134 {
135  const label nBezier = bezier_.nBezier();
136  cpI = varID%nBezier;
137  dir = varID/nBezier;
138 }
139 
140 
141 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
142 
143 Foam::BezierDesignVariables::BezierDesignVariables
144 (
145  fvMesh& mesh,
146  const dictionary& dict
147 )
148 :
150  bezier_
151  (
152  mesh,
154  (
155  IOobject
156  (
157  "optimisationDict",
158  mesh_.time().globalPath()/"system",
159  mesh,
160  IOobject::MUST_READ,
161  IOobject::NO_WRITE,
162  IOobject::NO_REGISTER
163  )
164  )
165  ),
166  dx_
167  (
168  IOobject
169  (
170  "dx",
171  mesh_.time().timeName(),
172  mesh_,
173  IOobject::NO_READ,
174  IOobject::NO_WRITE
175  ),
176  pointMesh::New(mesh_),
178  )
179 {
180  // Set the size of the design variables field
182 
183  // Set the active design variables
185 
186  // Read bounds
187  readBounds();
188 }
189 
190 
191 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
192 
194 {
195  // Translate the correction field to control point movements
196  computeBoundaryDisplacement(correction);
197 
198  // Transfer movement to the displacementMethod
199  displMethodPtr_->setMotionField(dx_);
200 
201  // Update the design variables
203 
204  // Do the actual mesh movement
205  moveMesh();
206 }
207 
208 
210 {
211  // Transfer the correction field to control point movement
212  computeBoundaryDisplacement(correction);
213 
214  const scalar maxDisplacement(max(mag(dx_)).value());
215 
216  Info<< "maxAllowedDisplacement/maxDisplacement at the boundary\t"
217  << maxInitChange_() << "/" << maxDisplacement << endl;
218 
219  const scalar eta = maxInitChange_()/maxDisplacement;
220  Info<< "Setting eta value to " << eta << endl;
221  correction *= eta;
222 
223  return eta;
224 }
225 
226 
228 {
229  return false;
230 }
231 
232 
234 (
235  const label patchI,
236  const label varID
237 ) const
238 {
239  label cpI(-1), dir(-1);
240  decomposeVarID(cpI, dir, varID);
241  return bezier_.dxdbFace(patchI, cpI, dir);
242 }
243 
244 
246 (
247  const label patchI,
248  const label varID
249 ) const
250 {
251  label cpI(-1), dir(-1);
252  decomposeVarID(cpI, dir, varID);
253  return bezier_.dndbBasedSensitivities(patchI, cpI, dir, false);
254 }
255 
256 
258 (
259  const label patchI,
260  const label varID
261 ) const
262 {
263  label cpI(-1), dir(-1);
264  decomposeVarID(cpI, dir, varID);
265  return bezier_.dndbBasedSensitivities(patchI, cpI, dir, true);
266 }
267 
268 
270 Foam::BezierDesignVariables::dCdb(const label varID) const
271 {
272  label cpI(-1), dir(-1);
273  decomposeVarID(cpI, dir, varID);
274  label patchI(-1);
275  // There is no mechanism in place to identify the parametertised patch.
276  // Look over all patches and grab one with a non-zero dxdb
277  for (const label pI : parametertisedPatches_)
278  {
279  tmp<vectorField> dxdbFace = bezier_.dxdbFace(pI, cpI, dir);
280  if (gSum(mag(dxdbFace)) > SMALL)
281  {
282  patchI = pI;
283  }
284  }
285  return solveMeshMovementEqn(patchI, varID);
286 }
287 
288 
289 // ************************************************************************* //
labelList activeDesignVariables_
Which of the design variables will be updated.
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix by subtracting the matrix multiplied by the current fi...
dictionary dict
List< List< bool > > boolListList
List of boolList.
Definition: boolList.H:36
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
virtual bool globalSum() const
Whether to use global sum when computing matrix-vector products.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
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.
virtual scalar computeEta(scalarField &correction)
Compute eta if not set in the first step.
virtual tmp< vectorField > dxdbFace(const label patchI, const label varID) const
Get dxdb for given design variable and patch.
const dimensionSet dimless
Dimensionless.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
const labelList & getActiveDesignVariables() const
Return active design variables.
Definition: Bezier.C:421
Macros for easy insertion into run-time selection tables.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:104
void decomposeVarID(label &cpI, label &dir, const label varID) const
Decompose varID to cpID and direction.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:45
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
word timeName
Definition: getTimeIndex.H:3
void setSize(const label n)
Alias for resize()
Definition: List.H:320
dynamicFvMesh & mesh
Type gSum(const FieldField< Field, Type > &f)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
label nBezier() const
Number of Bezier control points.
Definition: Bezier.C:120
void readBounds(autoPtr< scalar > lowerBoundPtr=nullptr, autoPtr< scalar > upperBoundPtr=nullptr)
Read bounds for design variables, if present.
Vector< scalar > vector
Definition: vector.H:57
virtual const scalarField & getVars() const
Get the design variables.
void setBounds(autoPtr< scalarField > &bounds, const vector &cpBounds)
Set uniform bounds for all control points.
Istream and Ostream manipulators taking arguments.
tmp< vectorField > computeBoundaryDisplacement(const scalarField &correction)
Transform the correction of design variables to control points&#39; movement.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
label size() const noexcept
The number of elements in the container.
Definition: UList.H:680
defineTypeNameAndDebug(combustionModel, 0)
virtual tmp< volVectorField > dCdb(const label varID) const
Get dCdb for given design variable.
virtual void update(scalarField &correction)
Update design variables based on a given correction.
autoPtr< scalarField > lowerBounds_
Lower bounds of the design variables.
Abstract base class for defining design variables for shape optimisation.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
autoPtr< scalarField > upperBounds_
Upper bounds of the design variables.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
void operator+=(const UList< scalar > &)
Definition: Field.C:799
virtual tmp< vectorField > dndb(const label patchI, const label varID) const
Get dndb for given design variable and patch.
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Bezier bezier_
The Bezier control points and auxiliary functions.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
void readBounds(autoPtr< scalar > lowerBoundPtr=nullptr, autoPtr< scalar > upperBoundPtr=nullptr)
Read bounds for design variables, if present.
Namespace for OpenFOAM.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
virtual tmp< vectorField > dSdb(const label patchI, const label varID) const
Get dSdb for given design variable and patch.