Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / dynamicMesh / motionSmoother / motionSmoother.H
blobf228d44e9768ec95341f9593ceb873c2436df4bb
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2011 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 Class
25     Foam::motionSmoother
27 Description
28     Given a displacement moves the mesh by scaling the displacement back
29     until there are no more mesh errors.
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.
35     E.g.
36     \verbatim
37         // Construct iterative mesh mover.
38         motionSmoother meshMover(mesh, labelList(1, patchI));
40         // Set desired displacement:
41         meshMover.displacement() = ..
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
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.
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.
67     - Mesh constraints are looked up from the supplied dictionary. (uses
68     recursive lookup)
70 SourceFiles
71     motionSmoother.C
72     motionSmootherTemplates.C
74 \*---------------------------------------------------------------------------*/
76 #ifndef motionSmoother_H
77 #define motionSmoother_H
79 #include "pointFields.H"
80 #include "HashSet.H"
81 #include "PackedBoolList.H"
82 #include "indirectPrimitivePatch.H"
83 #include "className.H"
84 #include "twoDPointCorrector.H"
86 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
88 namespace Foam
91 class polyMeshGeometry;
92 class faceSet;
94 /*---------------------------------------------------------------------------*\
95                            Class motionSmoother Declaration
96 \*---------------------------------------------------------------------------*/
98 class motionSmoother
100     // Private class
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         {
108         public:
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]);
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         };
133     // Private data
135         //- Reference to polyMesh. Non-const since we move mesh.
136         polyMesh& mesh_;
138         //- Reference to pointMesh
139         pointMesh& pMesh_;
141         //- Reference to face subset of all adaptPatchIDs
142         indirectPrimitivePatch& pp_;
144         //- Indices of fixedValue patches that we're allowed to modify the
145         // displacement on.
146         const labelList adaptPatchIDs_;
149         // Smoothing and checking parameters
150         dictionary paramDict_;
152         // Internal data
154         //- Displacement field
155         pointVectorField displacement_;
157         //- Scale factor for displacement
158         pointScalarField scale_;
160         //- Starting mesh position
161         pointField oldPoints_;
163         //- Is mesh point on boundary or not
164         PackedBoolList isInternalPoint_;
166         //- Is edge master (always except if on coupled boundary and on
167         //  lower processor)
168         PackedBoolList isMasterEdge_;
170         //- 2-D motion corrector
171         twoDPointCorrector twoDCorrector_;
173         // Muli-patch constraints (from pointPatchInterpolation)
175             labelList patchPatchPointConstraintPoints_;
176             tensorField patchPatchPointConstraintTensors_;
179     // Private Member Functions
181         //- Average of connected points.
182         template <class Type>
183         tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
184         (
185             const GeometricField<Type, pointPatchField, pointMesh>& fld,
186             const scalarField& edgeWeight
187         ) const;
189         //- Average postion of connected points.
190         template <class Type>
191         tmp<GeometricField<Type, pointPatchField, pointMesh> > avgPositions
192         (
193             const GeometricField<Type, pointPatchField, pointMesh>& fld,
194             const scalarField& edgeWeight
195         ) const;
197         //- Check constraints
198         template<class Type>
199         static void checkConstraints
200         (
201             GeometricField<Type, pointPatchField, pointMesh>&
202         );
204         //- Multi-patch constraints
205         template<class Type>
206         void applyCornerConstraints
207         (
208             GeometricField<Type, pointPatchField, pointMesh>&
209         ) const;
211         //- Test synchronisation of generic field (not positions!) on points
212         template<class Type, class CombineOp>
213         void testSyncField
214         (
215             const Field<Type>&,
216             const CombineOp& cop,
217             const Type& zero,
218             const scalar maxMag
219         ) const;
221         //- Test synchronisation of points
222         void testSyncPositions(const pointField&, const scalar maxMag) const;
224         //- Assemble tensors for multi-patch constraints
225         void makePatchPatchAddressing();
227         static void checkFld(const pointScalarField&);
229         //- Get points used by given faces
230         labelHashSet getPoints(const labelHashSet&) const;
232         //- explicit smoothing and min on all affected internal points
233         void minSmooth
234         (
235             const PackedBoolList& isAffectedPoint,
236             const pointScalarField& fld,
237             pointScalarField& newFld
238         ) const;
240         //- same but only on selected points (usually patch points)
241         void minSmooth
242         (
243             const PackedBoolList& isAffectedPoint,
244             const labelList& meshPoints,
245             const pointScalarField& fld,
246             pointScalarField& newFld
247         ) const;
249         //- Scale certain (internal) points of a field
250         void scaleField
251         (
252             const labelHashSet& pointLabels,
253             const scalar scale,
254             pointScalarField&
255         ) const;
257         //- As above but points have to be in meshPoints as well
258         //  (usually to scale patch points)
259         void scaleField
260         (
261             const labelList& meshPoints,
262             const labelHashSet& pointLabels,
263             const scalar scale,
264             pointScalarField&
265         ) const;
267         //- Helper function. Is point internal?
268         bool isInternalPoint(const label pointI) const;
270         //- Given a set of faces that cause smoothing and a number of
271         //  iterations determine the maximum set of points who are affected
272         //  and the accordingly affected faces.
273         void getAffectedFacesAndPoints
274         (
275             const label nPointIter,
276             const faceSet& wrongFaces,
278             labelList& affectedFaces,
279             PackedBoolList& isAffectedPoint
280         ) const;
282         //- Disallow default bitwise copy construct
283         motionSmoother(const motionSmoother&);
285         //- Disallow default bitwise assignment
286         void operator=(const motionSmoother&);
289 public:
291     ClassName("motionSmoother");
293     // Constructors
295         //- Construct from mesh, patches to work on and smoothing parameters.
296         //  Reads displacement field (only boundary conditions used)
297         motionSmoother
298         (
299             polyMesh&,
300             pointMesh&,
301             indirectPrimitivePatch& pp,         // 'outside' points
302             const labelList& adaptPatchIDs,     // patches forming 'outside'
303             const dictionary& paramDict
304         );
306         //- Construct from mesh, patches to work on and smoothing parameters and
307         //  displacementfield (only boundary conditions used)
308         motionSmoother
309         (
310             polyMesh&,
311             indirectPrimitivePatch& pp,         // 'outside' points
312             const labelList& adaptPatchIDs,     // patches forming 'outside'
313             const pointVectorField&,
314             const dictionary& paramDict
315         );
318     //- Destructor
319     ~motionSmoother();
322     // Member Functions
324         // Access
326             //- Reference to mesh
327             const polyMesh& mesh() const;
329             //- Reference to pointMesh
330             const pointMesh& pMesh() const;
332             //- Reference to patch
333             const indirectPrimitivePatch& patch() const;
335             //- Patch labels that are being adapted
336             const labelList& adaptPatchIDs() const;
338             const dictionary& paramDict() const;
340             //- Reference to displacement field
341             pointVectorField& displacement();
343             //- Reference to displacement field
344             const pointVectorField& displacement() const;
346             //- Reference to scale field
347             const pointScalarField& scale() const;
349             //- Starting mesh position
350             const pointField& oldPoints() const;
352             //- Return reference to 2D point motion correction
353             twoDPointCorrector& twoDCorrector()
354             {
355                 return twoDCorrector_;
356             }
360         // Edit
362             //- Take over existing mesh position.
363             void correct();
365             //- Set displacement field from displacement on patch points.
366             //  Modify provided displacement to be consistent with actual
367             //  boundary conditions on displacement. Note: resets the
368             //  displacement to be 0 on coupled patches beforehand
369             //  to make sure shared points
370             //  partially on pp (on some processors) and partially not
371             //  (on other processors) get the value from pp.
372             void setDisplacement(pointField& patchDisp);
374             //- Special correctBoundaryConditions which evaluates fixedValue
375             //  patches first so they get overwritten with any constraint
376             //  bc's.
377             void correctBoundaryConditions(pointVectorField&) const;
379             //- Move mesh. Does 2D correction (modifies passed pointField) and
380             //  polyMesh::movePoints. Returns swept volumes.
381             tmp<scalarField> movePoints(pointField&);
383             //- Set the errorReduction (by how much to scale the displacement
384             //  at error locations) parameter. Returns the old value.
385             //  Set to 0 (so revert to old mesh) grows out one cell layer
386             //  from error faces.
387             scalar setErrorReduction(const scalar);
389             //- Move mesh with given scale. Return true if mesh ok or has
390             //  less than nAllow errors, false
391             //  otherwise and locally update scale. Smoothmesh=false means only
392             //  patch points get moved.
393             //  Parallel ok (as long as displacement field is consistent
394             //  across patches)
395             bool scaleMesh
396             (
397                 labelList& checkFaces,
398                 const bool smoothMesh = true,
399                 const label nAllow = 0
400             );
402             //- Move mesh (with baffles) with given scale.
403             bool scaleMesh
404             (
405                 labelList& checkFaces,
406                 const List<labelPair>& baffles,
407                 const bool smoothMesh = true,
408                 const label nAllow = 0
409             );
411             //- Move mesh with externally provided mesh constraints
412             bool scaleMesh
413             (
414                 labelList& checkFaces,
415                 const List<labelPair>& baffles,
416                 const dictionary& paramDict,
417                 const dictionary& meshQualityDict,
418                 const bool smoothMesh = true,
419                 const label nAllow = 0
420             );
422             //- Update topology
423             void updateMesh();
425             //- Check mesh with mesh settings in dict. Collects incorrect faces
426             //  in set. Returns true if one or more faces in error.
427             //  Parallel ok.
428             static bool checkMesh
429             (
430                 const bool report,
431                 const polyMesh& mesh,
432                 const dictionary& dict,
433                 labelHashSet& wrongFaces
434             );
436             //- Check (subset of mesh) with mesh settings in dict.
437             //  Collects incorrect faces in set. Returns true if one
438             //  or more faces in error. Parallel ok.
439             static bool checkMesh
440             (
441                 const bool report,
442                 const polyMesh& mesh,
443                 const dictionary& dict,
444                 const labelList& checkFaces,
445                 labelHashSet& wrongFaces
446             );
448             //- Check (subset of mesh including baffles) with mesh settings
449             //  in dict. Collects incorrect faces in set. Returns true if one
450             //  or more faces in error. Parallel ok.
451             static bool checkMesh
452             (
453                 const bool report,
454                 const polyMesh& mesh,
455                 const dictionary& dict,
456                 const labelList& checkFaces,
457                 const List<labelPair>& baffles,
458                 labelHashSet& wrongFaces
459             );
461             //- Check part of mesh with mesh settings in dict.
462             //  Collects incorrect faces in set. Returns true if one or
463             //  more faces in error. Parallel ok.
464             static bool checkMesh
465             (
466                 const bool report,
467                 const dictionary& dict,
468                 const polyMeshGeometry&,
469                 const labelList& checkFaces,
470                 labelHashSet& wrongFaces
471             );
473             //- Check part of mesh including baffles with mesh settings in dict.
474             //  Collects incorrect faces in set. Returns true if one or
475             //  more faces in error. Parallel ok.
476             static bool checkMesh
477             (
478                 const bool report,
479                 const dictionary& dict,
480                 const polyMeshGeometry&,
481                 const labelList& checkFaces,
482                 const List<labelPair>& baffles,
483                 labelHashSet& wrongFaces
484             );
486             // Helper functions to manipulate displacement vector.
488                 //- Fully explicit smoothing of fields (not positions)
489                 //  of internal points with varying diffusivity.
490                 template <class Type>
491                 void smooth
492                 (
493                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
494                     const scalarField& edgeWeight,
495                     GeometricField<Type, pointPatchField, pointMesh>& newFld
496                 ) const;
500 template<>
501 void motionSmoother::applyCornerConstraints<scalar>
503     GeometricField<scalar, pointPatchField, pointMesh>& pf
504 ) const;
507 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
509 } // End namespace Foam
511 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
513 #ifdef NoRepository
514 #   include "motionSmootherTemplates.C"
515 #endif
517 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
519 #endif
521 // ************************************************************************* //