fvMeshTopoChangersMovingCone.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "Time.H"
28 #include "polyTopoChangeMap.H"
29 #include "layerAdditionRemoval.H"
30 #include "meshTools.H"
31 #include "OFstream.H"
32 #include "mathematicalConstants.H"
34 
35 using namespace Foam::constant::mathematical;
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace fvMeshTopoChangers
42 {
43  defineTypeNameAndDebug(movingCone, 0);
44  addToRunTimeSelectionTable(fvMeshTopoChanger, movingCone, fvMesh);
45 }
46 }
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
51 Foam::tmp<Foam::scalarField> Foam::fvMeshTopoChangers::movingCone::vertexMarkup
52 (
53  const pointField& p,
54  const scalar curLeft,
55  const scalar curRight
56 ) const
57 {
58  Info<< "Updating vertex markup. curLeft: "
59  << curLeft << " curRight: " << curRight << endl;
60 
61  tmp<scalarField> tvertexMarkup(new scalarField(p.size()));
62  scalarField& vertexMarkup = tvertexMarkup.ref();
63 
64  forAll(p, pI)
65  {
66  if (p[pI].x() < curLeft - small)
67  {
68  vertexMarkup[pI] = -1;
69  }
70  else if (p[pI].x() > curRight + small)
71  {
72  vertexMarkup[pI] = 1;
73  }
74  else
75  {
76  vertexMarkup[pI] = 0;
77  }
78  }
79 
80  return tvertexMarkup;
81 }
82 
83 
84 void Foam::fvMeshTopoChangers::movingCone::addZonesAndModifiers()
85 {
86  // Add zones and modifiers for motion action
87 
88  if
89  (
90  mesh().pointZones().size()
91  || mesh().faceZones().size()
92  || mesh().cellZones().size()
93  || topoChanger_.size()
94  )
95  {
97  << "Zones and modifiers already present. Skipping."
98  << endl;
99 
100  return;
101  }
102 
103  Info<< "Time = " << mesh().time().timeName() << endl
104  << "Adding zones and modifiers to the mesh" << endl;
105 
106  const vectorField& fc = mesh().faceCentres();
107  const vectorField& fa = mesh().faceAreas();
108 
109  labelList zone1(fc.size());
110  boolList flipZone1(fc.size(), false);
111  label nZoneFaces1 = 0;
112 
113  labelList zone2(fc.size());
114  boolList flipZone2(fc.size(), false);
115  label nZoneFaces2 = 0;
116 
117  forAll(fc, facei)
118  {
119  if
120  (
121  fc[facei].x() > -0.003501
122  && fc[facei].x() < -0.003499
123  )
124  {
125  if ((fa[facei] & vector(1, 0, 0)) < 0)
126  {
127  flipZone1[nZoneFaces1] = true;
128  }
129 
130  zone1[nZoneFaces1] = facei;
131  Info<< "face " << facei << " for zone 1. Flip: "
132  << flipZone1[nZoneFaces1] << endl;
133  nZoneFaces1++;
134  }
135  else if
136  (
137  fc[facei].x() > -0.00701
138  && fc[facei].x() < -0.00699
139  )
140  {
141  zone2[nZoneFaces2] = facei;
142 
143  if ((fa[facei] & vector(1, 0, 0)) > 0)
144  {
145  flipZone2[nZoneFaces2] = true;
146  }
147 
148  Info<< "face " << facei << " for zone 2. Flip: "
149  << flipZone2[nZoneFaces2] << endl;
150  nZoneFaces2++;
151  }
152  }
153 
154  zone1.setSize(nZoneFaces1);
155  flipZone1.setSize(nZoneFaces1);
156 
157  zone2.setSize(nZoneFaces2);
158  flipZone2.setSize(nZoneFaces2);
159 
160  Info<< "zone: " << zone1 << endl;
161  Info<< "zone: " << zone2 << endl;
162 
163  List<pointZone*> pz(0);
164  List<faceZone*> fz(2);
165  List<cellZone*> cz(0);
166 
167  label nFz = 0;
168 
169  fz[nFz] =
170  new faceZone
171  (
172  "rightExtrusionFaces",
173  zone1,
174  flipZone1,
175  nFz,
176  mesh().faceZones()
177  );
178  nFz++;
179 
180  fz[nFz] =
181  new faceZone
182  (
183  "leftExtrusionFaces",
184  zone2,
185  flipZone2,
186  nFz,
187  mesh().faceZones()
188  );
189  nFz++;
190 
191  fz.setSize(nFz);
192 
193  Info<< "Adding mesh zones." << endl;
194  mesh().addZones(pz, fz, cz);
195 
196 
197  // Add layer addition/removal interfaces
198 
199  List<polyMeshModifier*> tm(2);
200  label nMods = 0;
201 
202  tm[nMods] =
203  new layerAdditionRemoval
204  (
205  "right",
206  nMods,
207  topoChanger_,
208  "rightExtrusionFaces",
209  motionDict_.subDict("right").lookup<scalar>("minThickness"),
210  motionDict_.subDict("right").lookup<scalar>("maxThickness")
211  );
212  nMods++;
213 
214  tm[nMods] = new layerAdditionRemoval
215  (
216  "left",
217  nMods,
218  topoChanger_,
219  "leftExtrusionFaces",
220  motionDict_.subDict("left").lookup<scalar>("minThickness"),
221  motionDict_.subDict("left").lookup<scalar>("maxThickness")
222  );
223  nMods++;
224  tm.setSize(nMods);
225 
226  Info<< "Adding " << nMods << " mesh modifiers" << endl;
227  topoChanger_.addTopologyModifiers(tm);
228 
229  write();
230 }
231 
232 
233 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
234 
236 (
237  fvMesh& mesh,
238  const dictionary& dict
239 )
240 :
241  fvMeshTopoChanger(mesh),
242  topoChanger_(mesh),
243  motionDict_(dict),
244  motionVelAmplitude_(motionDict_.lookup("motionVelAmplitude")),
245  motionVelPeriod_(motionDict_.lookup<scalar>("motionVelPeriod")),
246  curMotionVel_
247  (
248  motionVelAmplitude_*sin(mesh.time().value()*pi/motionVelPeriod_)
249  ),
250  leftEdge_(motionDict_.lookup<scalar>("leftEdge")),
251  curLeft_(motionDict_.lookup<scalar>("leftObstacleEdge")),
252  curRight_(motionDict_.lookup<scalar>("rightObstacleEdge"))
253 {
254  Pout<< "Initial time:" << mesh.time().value()
255  << " Initial curMotionVel_:" << curMotionVel_
256  << endl;
257 
258  addZonesAndModifiers();
259 
260  curLeft_ = average
261  (
262  mesh.faceZones()
263  [
264  mesh.faceZones().findZoneID("leftExtrusionFaces")
265  ]().localPoints()
266  ).x() - small;
267 
268  curRight_ = average
269  (
270  mesh.faceZones()
271  [
272  mesh.faceZones().findZoneID("rightExtrusionFaces")
273  ]().localPoints()
274  ).x() + small;
275 
276  motionMask_ = vertexMarkup
277  (
278  mesh.points(),
279  curLeft_,
280  curRight_
281  );
282 }
283 
284 
285 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
286 
288 {}
289 
290 
291 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
292 
294 {
295  // Do mesh changes (use inflation - put new points in topoChangeMap)
296  autoPtr<polyTopoChangeMap> topoChangeMap = topoChanger_.changeMesh(true);
297 
298  // Calculate the new point positions depending on whether the
299  // topological change has happened or not
300  pointField newPoints;
301 
302  vector curMotionVel_ =
303  motionVelAmplitude_*sin(mesh().time().value()*pi/motionVelPeriod_);
304 
305  Pout<< "time:" << mesh().time().value()
306  << " curMotionVel_:" << curMotionVel_
307  << " curLeft:" << curLeft_
308  << " curRight:" << curRight_
309  << endl;
310 
311  if (topoChangeMap.valid())
312  {
313  Info<< "Topology change. Calculating motion points" << endl;
314 
315  if (topoChangeMap().hasMotionPoints())
316  {
317  Info<< "Topology change. Has premotion points" << endl;
318 
319  motionMask_ =
320  vertexMarkup
321  (
322  topoChangeMap().preMotionPoints(),
323  curLeft_,
324  curRight_
325  );
326 
327  // Move points inside the motionMask
328  newPoints =
329  topoChangeMap().preMotionPoints()
330  + (
331  pos0(0.5 - mag(motionMask_)) // cells above the body
332  )*curMotionVel_*mesh().time().deltaT().value();
333  }
334  else
335  {
336  Info<< "Topology change. Already set mesh points" << endl;
337 
338  motionMask_ =
339  vertexMarkup
340  (
341  mesh().points(),
342  curLeft_,
343  curRight_
344  );
345 
346  // Move points inside the motionMask
347  newPoints =
348  mesh().points()
349  + (
350  pos0(0.5 - mag(motionMask_)) // cells above the body
351  )*curMotionVel_*mesh().time().deltaT().value();
352  }
353  }
354  else
355  {
356  Info<< "No topology change" << endl;
357  // Set the mesh motion
358  newPoints =
359  mesh().points()
360  + (
361  pos0(0.5 - mag(motionMask_)) // cells above the body
362  )*curMotionVel_*mesh().time().deltaT().value();
363  }
364 
365  // The mesh now contains the cells with zero volume
366  Info << "Executing mesh motion" << endl;
367  mesh().movePoints(newPoints);
368 
369  // The mesh now has got non-zero volume cells
370 
371  curLeft_ = average
372  (
373  mesh().faceZones()
374  [
375  mesh().faceZones().findZoneID("leftExtrusionFaces")
376  ]().localPoints()
377  ).x() - small;
378 
379  curRight_ = average
380  (
381  mesh().faceZones()
382  [
383  mesh().faceZones().findZoneID("rightExtrusionFaces")
384  ]().localPoints()
385  ).x() + small;
386 
387  return true;
388 }
389 
390 
392 (
393  const polyTopoChangeMap& map
394 )
395 {}
396 
397 
399 (
400  const polyMeshMap& map
401 )
402 {}
403 
404 
406 (
407  const polyDistributionMap& map
408 )
409 {}
410 
411 
412 // ************************************************************************* //
label findZoneID(const word &zoneName) const
Find zone index given a name.
Definition: MeshZones.C:341
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
virtual void distribute(const polyDistributionMap &)
Update corresponding to the given distribution map.
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
virtual bool update()
Update the mesh for both mesh motion and topology change.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:372
fvMesh & mesh
Macros for easy insertion into run-time selection tables.
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1211
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
const pointField & points
mathematical constants.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
movingCone(fvMesh &mesh, const dictionary &dict)
Construct from fvMesh and dictionary.
const Type & value() const
Return const reference to value.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
List< label > labelList
A List of labels.
Definition: labelList.H:56
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
dimensionedScalar pos0(const dimensionedScalar &ds)
dimensionedScalar sin(const dimensionedScalar &ds)
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
const meshFaceZones & faceZones() const
Return face zones.
Definition: polyMesh.H:495
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:95
messageStream Info
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:52
A class for managing temporary objects.
Definition: PtrList.H:53
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:50
virtual void topoChange(const polyTopoChangeMap &)
Update corresponding to the given map.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Abstract base class for fvMesh movers.
Namespace for OpenFOAM.
#define InfoInFunction
Report an information message using Foam::Info.