movingConeTopoFvMesh.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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2018-2020 OpenCFD Ltd.
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 "movingConeTopoFvMesh.H"
30 #include "Time.H"
31 #include "mapPolyMesh.H"
32 #include "layerAdditionRemoval.H"
34 #include "meshTools.H"
35 #include "OFstream.H"
36 #include "mathematicalConstants.H"
37 
38 using namespace Foam::constant::mathematical;
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  defineTypeNameAndDebug(movingConeTopoFvMesh, 0);
45 
47  (
48  topoChangerFvMesh,
49  movingConeTopoFvMesh,
50  IOobject
51  );
53  (
54  topoChangerFvMesh,
55  movingConeTopoFvMesh,
56  doInit
57  );
58 }
59 
60 
61 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
62 
63 Foam::tmp<Foam::scalarField> Foam::movingConeTopoFvMesh::vertexMarkup
64 (
65  const pointField& p,
66  const scalar curLeft,
67  const scalar curRight
68 ) const
69 {
70  Info<< "Updating vertex markup. curLeft: "
71  << curLeft << " curRight: " << curRight << endl;
72 
73  tmp<scalarField> tvertexMarkup(new scalarField(p.size()));
74  scalarField& vertexMarkup = tvertexMarkup.ref();
75 
76  forAll(p, pI)
77  {
78  if (p[pI].x() < curLeft - SMALL)
79  {
80  vertexMarkup[pI] = -1;
81  }
82  else if (p[pI].x() > curRight + SMALL)
83  {
84  vertexMarkup[pI] = 1;
85  }
86  else
87  {
88  vertexMarkup[pI] = 0;
89  }
90  }
91 
92  return tvertexMarkup;
93 }
94 
95 
96 void Foam::movingConeTopoFvMesh::addZonesAndModifiers()
97 {
98  // Add zones and modifiers for motion action
99 
100  if
101  (
102  pointZones().size()
103  || faceZones().size()
104  || cellZones().size()
105  || topoChanger_.size()
106  )
107  {
109  << "Zones and modifiers already present. Skipping."
110  << endl;
111 
112  return;
113  }
114 
115  Info<< "Time = " << time().timeName() << endl
116  << "Adding zones and modifiers to the mesh" << endl;
117 
118  const vectorField& fc = faceCentres();
119  const vectorField& fa = faceAreas();
120 
121  labelList zone1(fc.size());
122  boolList flipZone1(fc.size(), false);
123  label nZoneFaces1 = 0;
124 
125  labelList zone2(fc.size());
126  boolList flipZone2(fc.size(), false);
127  label nZoneFaces2 = 0;
128 
129  forAll(fc, facei)
130  {
131  if
132  (
133  fc[facei].x() > -0.003501
134  && fc[facei].x() < -0.003499
135  )
136  {
137  if ((fa[facei] & vector(1, 0, 0)) < 0)
138  {
139  flipZone1[nZoneFaces1] = true;
140  }
141 
142  zone1[nZoneFaces1] = facei;
143  Info<< "face " << facei << " for zone 1. Flip: "
144  << flipZone1[nZoneFaces1] << endl;
145  ++nZoneFaces1;
146  }
147  else if
148  (
149  fc[facei].x() > -0.00701
150  && fc[facei].x() < -0.00699
151  )
152  {
153  zone2[nZoneFaces2] = facei;
154 
155  if ((fa[facei] & vector(1, 0, 0)) > 0)
156  {
157  flipZone2[nZoneFaces2] = true;
158  }
159 
160  Info<< "face " << facei << " for zone 2. Flip: "
161  << flipZone2[nZoneFaces2] << endl;
162  ++nZoneFaces2;
163  }
164  }
165 
166  zone1.setSize(nZoneFaces1);
167  flipZone1.setSize(nZoneFaces1);
168 
169  zone2.setSize(nZoneFaces2);
170  flipZone2.setSize(nZoneFaces2);
171 
172  Info<< "zone: " << zone1 << endl;
173  Info<< "zone: " << zone2 << endl;
174 
175  List<pointZone*> pz(0);
176  List<faceZone*> fz(2);
177  List<cellZone*> cz(0);
178 
179  label nFz = 0;
180 
181  fz[nFz] =
182  new faceZone
183  (
184  "rightExtrusionFaces",
185  std::move(zone1),
186  std::move(flipZone1),
187  nFz,
188  faceZones()
189  );
190  ++nFz;
191 
192  fz[nFz] =
193  new faceZone
194  (
195  "leftExtrusionFaces",
196  std::move(zone2),
197  std::move(flipZone2),
198  nFz,
199  faceZones()
200  );
201  ++nFz;
202 
203  fz.setSize(nFz);
204 
205  Info<< "Adding mesh zones." << endl;
206  addZones(pz, fz, cz);
207 
208 
209  // Add layer addition/removal interfaces
210 
211  List<polyMeshModifier*> tm(2);
212  label nMods = 0;
213 
214  tm[nMods] =
215  new layerAdditionRemoval
216  (
217  "right",
218  nMods,
219  topoChanger_,
220  "rightExtrusionFaces",
221  motionDict_.subDict("right").get<scalar>("minThickness"),
222  motionDict_.subDict("right").get<scalar>("maxThickness")
223  );
224  ++nMods;
225 
226  tm[nMods] = new layerAdditionRemoval
227  (
228  "left",
229  nMods,
230  topoChanger_,
231  "leftExtrusionFaces",
232  motionDict_.subDict("left").get<scalar>("minThickness"),
233  motionDict_.subDict("left").get<scalar>("maxThickness")
234  );
235  ++nMods;
236  tm.setSize(nMods);
237 
238  Info<< "Adding " << nMods << " mesh modifiers" << endl;
239  topoChanger_.addTopologyModifiers(tm);
240 
241  write();
242 }
243 
244 
245 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
246 
247 Foam::movingConeTopoFvMesh::movingConeTopoFvMesh
248 (
249  const IOobject& io,
250  const bool doInit
251 )
252 :
253  topoChangerFvMesh(io, doInit),
254  motionDict_
255  (
256  IOdictionary::readContents
257  (
258  IOobject
259  (
260  "dynamicMeshDict",
261  time().constant(),
262  *this,
263  IOobject::MUST_READ
264  )
265  ).optionalSubDict(typeName + "Coeffs")
266  )
267 {
268  if (doInit)
269  {
270  init(false); // do not initialise lower levels
271  }
272 }
273 
274 
275 bool Foam::movingConeTopoFvMesh::init(const bool doInit)
276 {
277  if (doInit)
278  {
279  topoChangerFvMesh::init(doInit);
280  }
281 
282  motionVelAmplitude_ = motionDict_.get<vector>("motionVelAmplitude");
283  motionVelPeriod_ = motionDict_.get<scalar>("motionVelPeriod");
284  curMotionVel_ =
285  motionVelAmplitude_*sin(time().value()*pi/motionVelPeriod_);
286  leftEdge_ = motionDict_.get<scalar>("leftEdge");
287  curLeft_ = motionDict_.get<scalar>("leftObstacleEdge");
288  curRight_ = motionDict_.get<scalar>("rightObstacleEdge");
289 
290  Pout<< "Initial time:" << time().value()
291  << " Initial curMotionVel_:" << curMotionVel_
292  << endl;
293 
294  addZonesAndModifiers();
295 
296  curLeft_ = average
297  (
298  faceZones()
299  [
300  faceZones().findZoneID("leftExtrusionFaces")
301  ]().localPoints()
302  ).x() - SMALL;
303 
304  curRight_ = average
305  (
306  faceZones()
307  [
308  faceZones().findZoneID("rightExtrusionFaces")
309  ]().localPoints()
310  ).x() + SMALL;
311 
312  motionMask_ = vertexMarkup
313  (
314  points(),
315  curLeft_,
316  curRight_
317  );
318 
319  // Assume something changed
320  return true;
321 }
322 
323 
324 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
327 {}
328 
329 
330 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
331 
333 {
334  // Do mesh changes (use inflation - put new points in topoChangeMap)
335  autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh(true);
336 
337  // Calculate the new point positions depending on whether the
338  // topological change has happened or not
339  pointField newPoints;
340 
341  vector curMotionVel_ =
342  motionVelAmplitude_*sin(time().value()*pi/motionVelPeriod_);
343 
344  Pout<< "time:" << time().value() << " curMotionVel_:" << curMotionVel_
345  << " curLeft:" << curLeft_ << " curRight:" << curRight_
346  << endl;
347 
348  if (topoChangeMap)
349  {
350  Info<< "Topology change. Calculating motion points" << endl;
351 
352  if (topoChangeMap().hasMotionPoints())
353  {
354  Info<< "Topology change. Has premotion points" << endl;
355 
356  motionMask_ =
357  vertexMarkup
358  (
359  topoChangeMap().preMotionPoints(),
360  curLeft_,
361  curRight_
362  );
363 
364  // Move points inside the motionMask
365  newPoints =
366  topoChangeMap().preMotionPoints()
367  + (
368  pos0(0.5 - mag(motionMask_)) // cells above the body
369  )*curMotionVel_*time().deltaTValue();
370  }
371  else
372  {
373  Info<< "Topology change. Already set mesh points" << endl;
374 
375  motionMask_ =
376  vertexMarkup
377  (
378  points(),
379  curLeft_,
380  curRight_
381  );
382 
383  // Move points inside the motionMask
384  newPoints =
385  points()
386  + (
387  pos0(0.5 - mag(motionMask_)) // cells above the body
388  )*curMotionVel_*time().deltaTValue();
389  }
390  }
391  else
392  {
393  Info<< "No topology change" << endl;
394  // Set the mesh motion
395  newPoints =
396  points()
397  + (
398  pos0(0.5 - mag(motionMask_)) // cells above the body
399  )*curMotionVel_*time().deltaTValue();
400  }
401 
402  // The mesh now contains the cells with zero volume
403  Info << "Executing mesh motion" << endl;
404  movePoints(newPoints);
405 
406  // The mesh now has got non-zero volume cells
407 
408  curLeft_ = average
409  (
410  faceZones()
411  [
412  faceZones().findZoneID("leftExtrusionFaces")
413  ]().localPoints()
414  ).x() - SMALL;
415 
416  curRight_ = average
417  (
418  faceZones()
419  [
420  faceZones().findZoneID("rightExtrusionFaces")
421  ]().localPoints()
422  ).x() + SMALL;
423 
424  return true;
425 }
426 
427 
428 // ************************************************************************* //
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
Definition: dynamicFvMesh.C:84
virtual bool update()
Update the mesh for both mesh motion and topology change.
Macros for easy insertion into run-time selection tables.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const pointField & points
Mathematical constants.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Abstract base class for a topology changing fvMesh.
constexpr scalar pi(M_PI)
Vector< scalar > vector
Definition: vector.H:57
dimensionedScalar pos0(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
defineTypeNameAndDebug(combustionModel, 0)
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
A class for managing temporary objects.
Definition: HashPtrTable.H:50
virtual ~movingConeTopoFvMesh()
Destructor.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
List< bool > boolList
A List of bools.
Definition: List.H:60
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Namespace for OpenFOAM.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
#define InfoInFunction
Report an information message using Foam::Info.