FreeFOAM The Cross-Platform CFD Toolkit
motionSmoother.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
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 Class
25  Foam::motionSmoother
26 
27 Description
28  Given a displacement moves the mesh by scaling the displacement back
29  until there are no more mesh errors.
30 
31  Holds displacement field (read upon construction since need boundary
32  conditions) and scaling factor and optional patch number on which to
33  scale back displacement.
34 
35  E.g.
36  @verbatim
37  // Construct iterative mesh mover.
38  motionSmoother meshMover(mesh, labelList(1, patchI));
39 
40  // Set desired displacement:
41  meshMover.displacement() = ..
42 
43  for (label iter = 0; iter < maxIter; iter++)
44  {
45  if (meshMover.scaleMesh(true))
46  {
47  Info<< "Successfully moved mesh" << endl;
48  return true;
49  }
50  }
51  @endverbatim
52 
53 Note
54  - Shared points (parallel): a processor can have points which are part of
55  pp on another processor but have no pp itself (i.e. it has points
56  and/or edges but no faces of pp). Hence we have to be careful when e.g.
57  synchronising displacements that the value from the processor which has
58  faces of pp get priority. This is currently handled in setDisplacement
59  by resetting the internal displacement to zero before doing anything
60  else. The combine operator used will give preference to non-zero
61  values.
62 
63  - Various routines take baffles. These are sets of boundary faces that
64  are treated as a single internal face. This is a hack used to apply
65  movement to internal faces.
66 
67  - Mesh constraints are looked up from the supplied dictionary. (uses
68  recursive lookup)
69 
70 SourceFiles
71  motionSmoother.C
72  motionSmootherTemplates.C
73 
74 \*---------------------------------------------------------------------------*/
75 
76 #ifndef motionSmoother_H
77 #define motionSmoother_H
78 
79 #include <OpenFOAM/pointFields.H>
80 #include <OpenFOAM/HashSet.H>
83 #include <OpenFOAM/className.H>
85 
86 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
87 
88 namespace Foam
89 {
90 
91 class polyMeshGeometry;
92 class faceSet;
93 
94 /*---------------------------------------------------------------------------*\
95  Class motionSmoother Declaration
96 \*---------------------------------------------------------------------------*/
97 
99 {
100  // Private class
101 
102  //- To synchronise displacements. We want max displacement since
103  // this is what is specified on pp and internal mesh will have
104  // zero displacement.
105  class maxMagEqOp
106  {
107 
108  public:
109 
110  void operator()(vector& x, const vector& y) const
111  {
112  for (direction i = 0; i < vector::nComponents; i++)
113  {
114  scalar magX = mag(x[i]);
115  scalar magY = mag(y[i]);
116 
117  if (magX < magY)
118  {
119  x[i] = y[i];
120  }
121  else if (magX == magY)
122  {
123  if (y[i] > x[i])
124  {
125  x[i] = y[i];
126  }
127  }
128  }
129  }
130  };
131 
132 
133  // Private data
134 
135  //- Reference to polyMesh. Non-const since we move mesh.
136  polyMesh& mesh_;
137 
138  //- Reference to pointMesh
139  pointMesh& pMesh_;
140 
141  //- Reference to face subset of all adaptPatchIDs
143 
144  //- Indices of fixedValue patches that we're allowed to modify the
145  // displacement on.
146  const labelList adaptPatchIDs_;
147 
148 
149  // Smoothing and checking parameters
150  dictionary paramDict_;
151 
152  // Internal data
153 
154  //- Displacement field
155  pointVectorField displacement_;
156 
157  //- Scale factor for displacement
158  pointScalarField scale_;
159 
160  //- Starting mesh position
161  pointField oldPoints_;
162 
163  //- Is mesh point on boundary or not
164  PackedBoolList isInternalPoint_;
165 
166  //- Is edge master (always except if on coupled boundary and on
167  // lower processor)
168  PackedBoolList isMasterEdge_;
169 
170  //- 2-D motion corrector
171  twoDPointCorrector twoDCorrector_;
172 
173  // Muli-patch constraints (from pointPatchInterpolation)
174 
175  labelList patchPatchPointConstraintPoints_;
176  tensorField patchPatchPointConstraintTensors_;
177 
178 
179  // Private Member Functions
180 
181  //- Average of connected points.
182  template <class Type>
184  (
186  const scalarField& edgeWeight,
187  const bool separation
188  ) const;
189 
190  //- Check constraints
191  template<class Type>
192  static void checkConstraints
193  (
195  );
196 
197  //- Multi-patch constraints
198  template<class Type>
199  void applyCornerConstraints
200  (
202  ) const;
203 
204  //- Test synchronisation of pointField
205  template<class Type, class CombineOp>
206  void testSyncField
207  (
208  const Field<Type>&,
209  const CombineOp& cop,
210  const Type& zero,
211  const bool separation,
212  const scalar maxMag
213  ) const;
214 
215  //- Assemble tensors for multi-patch constraints
216  void makePatchPatchAddressing();
217 
218  static void checkFld(const pointScalarField&);
219 
220  //- Get points used by given faces
221  labelHashSet getPoints(const labelHashSet&) const;
222 
223  //- explicit smoothing and min on all affected internal points
224  void minSmooth
225  (
226  const PackedBoolList& isAffectedPoint,
227  const pointScalarField& fld,
228  pointScalarField& newFld
229  ) const;
230 
231  //- same but only on selected points (usually patch points)
232  void minSmooth
233  (
234  const PackedBoolList& isAffectedPoint,
235  const labelList& meshPoints,
236  const pointScalarField& fld,
237  pointScalarField& newFld
238  ) const;
239 
240  //- Scale certain (internal) points of a field
241  void scaleField
242  (
243  const labelHashSet& pointLabels,
244  const scalar scale,
246  ) const;
247 
248  //- As above but points have to be in meshPoints as well
249  // (usually to scale patch points)
250  void scaleField
251  (
252  const labelList& meshPoints,
253  const labelHashSet& pointLabels,
254  const scalar scale,
256  ) const;
257 
258  //- Helper function. Is point internal?
259  bool isInternalPoint(const label pointI) const;
260 
261  //- Given a set of faces that cause smoothing and a number of
262  // iterations determine the maximum set of points who are affected
263  // and the accordingly affected faces.
264  void getAffectedFacesAndPoints
265  (
266  const label nPointIter,
267  const faceSet& wrongFaces,
268 
269  labelList& affectedFaces,
270  PackedBoolList& isAffectedPoint
271  ) const;
272 
273  //- Disallow default bitwise copy construct
275 
276  //- Disallow default bitwise assignment
277  void operator=(const motionSmoother&);
278 
279 
280 public:
281 
282  ClassName("motionSmoother");
283 
284  // Constructors
285 
286  //- Construct from mesh, patches to work on and smoothing parameters.
287  // Reads displacement field (only boundary conditions used)
289  (
290  polyMesh&,
291  pointMesh&,
292  indirectPrimitivePatch& pp, // 'outside' points
293  const labelList& adaptPatchIDs, // patches forming 'outside'
294  const dictionary& paramDict
295  );
296 
297  //- Construct from mesh, patches to work on and smoothing parameters and
298  // displacementfield (only boundary conditions used)
300  (
301  polyMesh&,
302  indirectPrimitivePatch& pp, // 'outside' points
303  const labelList& adaptPatchIDs, // patches forming 'outside'
304  const pointVectorField&,
305  const dictionary& paramDict
306  );
307 
308 
309  // Destructor
310 
311  ~motionSmoother();
312 
313 
314  // Member Functions
315 
316  // Access
317 
318  //- Reference to mesh
319  const polyMesh& mesh() const;
320 
321  //- Reference to pointMesh
322  const pointMesh& pMesh() const;
323 
324  //- Reference to patch
325  const indirectPrimitivePatch& patch() const;
326 
327  //- Patch labels that are being adapted
328  const labelList& adaptPatchIDs() const;
329 
330  const dictionary& paramDict() const;
331 
332  //- Reference to displacement field
334 
335  //- Reference to displacement field
336  const pointVectorField& displacement() const;
337 
338  //- Reference to scale field
339  const pointScalarField& scale() const;
340 
341  //- Starting mesh position
342  const pointField& oldPoints() const;
343 
344  //- Return reference to 2D point motion correction
346  {
347  return twoDCorrector_;
348  }
349 
350 
351 
352  // Edit
353 
354  //- Take over existing mesh position.
355  void correct();
356 
357  //- Set displacement field from displacement on patch points.
358  // Modify provided displacement to be consistent with actual
359  // boundary conditions on displacement. Note: resets the
360  // displacement to be 0 on coupled patches beforehand
361  // to make sure shared points
362  // partially on pp (on some processors) and partially not
363  // (on other processors) get the value from pp.
364  void setDisplacement(pointField& patchDisp);
365 
366  //- Special correctBoundaryConditions which evaluates fixedValue
367  // patches first so they get overwritten with any constraint
368  // bc's.
370 
371  //- Move mesh. Does 2D correction (modifies passed pointField) and
372  // polyMesh::movePoints. Returns swept volumes.
374 
375  //- Set the errorReduction (by how much to scale the displacement
376  // at error locations) parameter. Returns the old value.
377  // Set to 0 (so revert to old mesh) grows out one cell layer
378  // from error faces.
379  scalar setErrorReduction(const scalar);
380 
381  //- Move mesh with given scale. Return true if mesh ok or has
382  // less than nAllow errors, false
383  // otherwise and locally update scale. Smoothmesh=false means only
384  // patch points get moved.
385  // Parallel ok (as long as displacement field is consistent
386  // across patches)
387  bool scaleMesh
388  (
389  labelList& checkFaces,
390  const bool smoothMesh = true,
391  const label nAllow = 0
392  );
393 
394  //- Move mesh (with baffles) with given scale.
395  bool scaleMesh
396  (
397  labelList& checkFaces,
398  const List<labelPair>& baffles,
399  const bool smoothMesh = true,
400  const label nAllow = 0
401  );
402 
403  //- Move mesh with externally provided mesh constraints
404  bool scaleMesh
405  (
406  labelList& checkFaces,
407  const List<labelPair>& baffles,
408  const dictionary& paramDict,
409  const dictionary& meshQualityDict,
410  const bool smoothMesh = true,
411  const label nAllow = 0
412  );
413 
414  //- Update topology
415  void updateMesh();
416 
417  //- Check mesh with mesh settings in dict. Collects incorrect faces
418  // in set. Returns true if one or more faces in error.
419  // Parallel ok.
420  static bool checkMesh
421  (
422  const bool report,
423  const polyMesh& mesh,
424  const dictionary& dict,
425  labelHashSet& wrongFaces
426  );
427 
428  //- Check (subset of mesh) with mesh settings in dict.
429  // Collects incorrect faces in set. Returns true if one
430  // or more faces in error. Parallel ok.
431  static bool checkMesh
432  (
433  const bool report,
434  const polyMesh& mesh,
435  const dictionary& dict,
436  const labelList& checkFaces,
437  labelHashSet& wrongFaces
438  );
439 
440  //- Check (subset of mesh including baffles) with mesh settings
441  // in dict. Collects incorrect faces in set. Returns true if one
442  // or more faces in error. Parallel ok.
443  static bool checkMesh
444  (
445  const bool report,
446  const polyMesh& mesh,
447  const dictionary& dict,
448  const labelList& checkFaces,
449  const List<labelPair>& baffles,
450  labelHashSet& wrongFaces
451  );
452 
453  //- Check part of mesh with mesh settings in dict.
454  // Collects incorrect faces in set. Returns true if one or
455  // more faces in error. Parallel ok.
456  static bool checkMesh
457  (
458  const bool report,
459  const dictionary& dict,
460  const polyMeshGeometry&,
461  const labelList& checkFaces,
462  labelHashSet& wrongFaces
463  );
464 
465  //- Check part of mesh including baffles with mesh settings in dict.
466  // Collects incorrect faces in set. Returns true if one or
467  // more faces in error. Parallel ok.
468  static bool checkMesh
469  (
470  const bool report,
471  const dictionary& dict,
472  const polyMeshGeometry&,
473  const labelList& checkFaces,
474  const List<labelPair>& baffles,
475  labelHashSet& wrongFaces
476  );
477 
478  // Helper functions to manipulate displacement vector.
479 
480  //- Fully explicit smoothing of internal points with varying
481  // diffusivity.
482  template <class Type>
483  void smooth
484  (
486  const scalarField& edgeWeight,
487  const bool separation,
489  ) const;
490 };
491 
492 
493 template<>
494 void motionSmoother::applyCornerConstraints<scalar>
495 (
496  GeometricField<scalar, pointPatchField, pointMesh>& pf
497 ) const;
498 
499 
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
501 
502 } // End namespace Foam
503 
504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
505 
506 #ifdef NoRepository
507 # include "motionSmootherTemplates.C"
508 #endif
509 
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
511 
512 #endif
513 
514 // ************************ vim: set sw=4 sts=4 et: ************************ //