initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / dynamicMesh / motionSmoother / motionSmoother.H
blob3d853e476d3df0f757339ef8de1e3fee44c1ca66
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Class
26     Foam::motionSmoother
28 Description
29     Given a displacement moves the mesh by scaling the displacement back
30     until there are no more mesh errors.
32     Holds displacement field (read upon construction since need boundary
33     conditions) and scaling factor and optional patch number on which to
34     scale back displacement.
36     E.g.
37     @verbatim
38         // Construct iterative mesh mover.
39         motionSmoother meshMover(mesh, labelList(1, patchI));
41         // Set desired displacement:
42         meshMover.displacement() = ..
44         for (label iter = 0; iter < maxIter; iter++)
45         {
46             if (meshMover.scaleMesh(true))
47             {
48                 Info<< "Successfully moved mesh" << endl;
49                 return true;
50             }
51         }
52     @endverbatim
54 Note
55     - Shared points (parallel): a processor can have points which are part of
56     pp on another processor but have no pp itself (i.e. it has points
57     and/or edges but no faces of pp). Hence we have to be careful when e.g.
58     synchronising displacements that the value from the processor which has
59     faces of pp get priority. This is currently handled in setDisplacement
60     by resetting the internal displacement to zero before doing anything
61     else. The combine operator used will give preference to non-zero
62     values.
64     - Various routines take baffles. These are sets of boundary faces that
65     are treated as a single internal face. This is a hack used to apply
66     movement to internal faces.
68     - Mesh constraints are looked up from the supplied dictionary. (uses
69     recursive lookup)
71 SourceFiles
72     motionSmoother.C
73     motionSmootherTemplates.C
75 \*---------------------------------------------------------------------------*/
77 #ifndef motionSmoother_H
78 #define motionSmoother_H
80 #include "pointFields.H"
81 #include "HashSet.H"
82 #include "PackedBoolList.H"
83 #include "indirectPrimitivePatch.H"
84 #include "className.H"
85 #include "twoDPointCorrector.H"
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
89 namespace Foam
92 class polyMeshGeometry;
93 class faceSet;
95 /*---------------------------------------------------------------------------*\
96                            Class motionSmoother Declaration
97 \*---------------------------------------------------------------------------*/
99 class motionSmoother
101     // Private class
103         //- To synchronise displacements. We want max displacement since
104         //  this is what is specified on pp and internal mesh will have
105         //  zero displacement.
106         class maxMagEqOp
107         {
109         public:
111             void operator()(vector& x, const vector& y) const
112             {
113                 for (direction i = 0; i < vector::nComponents; i++)
114                 {
115                     scalar magX = mag(x[i]);
116                     scalar magY = mag(y[i]);
118                     if (magX < magY)
119                     {
120                         x[i] = y[i];
121                     }
122                     else if (magX == magY)
123                     {
124                         if (y[i] > x[i])
125                         {
126                             x[i] = y[i];
127                         }
128                     }
129                 }
130             }
131         };
134     // Private data
136         //- Reference to polyMesh. Non-const since we move mesh.
137         polyMesh& mesh_;
139         //- Reference to pointMesh
140         pointMesh& pMesh_;
142         //- Reference to face subset of all adaptPatchIDs
143         indirectPrimitivePatch& pp_;
145         //- Indices of fixedValue patches that we're allowed to modify the
146         // displacement on.
147         const labelList adaptPatchIDs_;
150         // Smoothing and checking parameters
151         dictionary paramDict_;
153         // Internal data
155         //- Displacement field
156         pointVectorField displacement_;
158         //- Scale factor for displacement
159         pointScalarField scale_;
161         //- Starting mesh position
162         pointField oldPoints_;
164         //- Is mesh point on boundary or not
165         PackedBoolList isInternalPoint_;
167         //- Is edge master (always except if on coupled boundary and on
168         //  lower processor)
169         PackedBoolList isMasterEdge_;
171         //- 2-D motion corrector
172         twoDPointCorrector twoDCorrector_;
174         // Muli-patch constraints (from pointPatchInterpolation)
176             labelList patchPatchPointConstraintPoints_;
177             tensorField patchPatchPointConstraintTensors_;
180     // Private Member Functions
182         //- Average of connected points.
183         template <class Type>
184         tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
185         (
186             const GeometricField<Type, pointPatchField, pointMesh>& fld,
187             const scalarField& edgeWeight,
188             const bool separation
189         ) const;
191         //- Check constraints
192         template<class Type>
193         static void checkConstraints
194         (
195             GeometricField<Type, pointPatchField, pointMesh>&
196         );
198         //- Multi-patch constraints
199         template<class Type>
200         void applyCornerConstraints
201         (
202             GeometricField<Type, pointPatchField, pointMesh>&
203         ) const;
205         //- Test synchronisation of pointField
206         template<class Type, class CombineOp>
207         void testSyncField
208         (
209             const Field<Type>&,
210             const CombineOp& cop,
211             const Type& zero,
212             const bool separation
213         ) const;
215         //- Assemble tensors for multi-patch constraints
216         void makePatchPatchAddressing();
218         static void checkFld(const pointScalarField&);
220         //- Get points used by given faces
221         labelHashSet getPoints(const labelHashSet&) const;
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;
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;
240         //- Scale certain (internal) points of a field
241         void scaleField
242         (
243             const labelHashSet& pointLabels,
244             const scalar scale,
245             pointScalarField&
246         ) const;
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,
255             pointScalarField&
256         ) const;
258         //- Helper function. Is point internal?
259         bool isInternalPoint(const label pointI) const;
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,
269             labelList& affectedFaces,
270             PackedBoolList& isAffectedPoint
271         ) const;
273         //- Disallow default bitwise copy construct
274         motionSmoother(const motionSmoother&);
276         //- Disallow default bitwise assignment
277         void operator=(const motionSmoother&);
280 public:
282     ClassName("motionSmoother");
284     // Constructors
286         //- Construct from mesh, patches to work on and smoothing parameters.
287         //  Reads displacement field (only boundary conditions used)
288         motionSmoother
289         (
290             polyMesh&,
291             pointMesh&,
292             indirectPrimitivePatch& pp,         // 'outside' points
293             const labelList& adaptPatchIDs,     // patches forming 'outside'
294             const dictionary& paramDict
295         );
297         //- Construct from mesh, patches to work on and smoothing parameters and
298         //  displacementfield (only boundary conditions used)
299         motionSmoother
300         (
301             polyMesh&,
302             indirectPrimitivePatch& pp,         // 'outside' points
303             const labelList& adaptPatchIDs,     // patches forming 'outside'
304             const pointVectorField&,
305             const dictionary& paramDict
306         );
309     // Destructor
311         ~motionSmoother();
314     // Member Functions
316         // Access
318             //- Reference to mesh
319             const polyMesh& mesh() const;
321             //- Reference to pointMesh
322             const pointMesh& pMesh() const;
324             //- Reference to patch
325             const indirectPrimitivePatch& patch() const;
327             //- Patch labels that are being adapted
328             const labelList& adaptPatchIDs() const;
330             const dictionary& paramDict() const;
332             //- Reference to displacement field
333             pointVectorField& displacement();
335             //- Reference to displacement field
336             const pointVectorField& displacement() const;
338             //- Reference to scale field
339             const pointScalarField& scale() const;
341             //- Starting mesh position
342             const pointField& oldPoints() const;
344             //- Return reference to 2D point motion correction
345             twoDPointCorrector& twoDCorrector()
346             {
347                 return twoDCorrector_;
348             }
352         // Edit
354             //- Take over existing mesh position.
355             void correct();
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);
366             //- Special correctBoundaryConditions which evaluates fixedValue
367             //  patches first so they get overwritten with any constraint
368             //  bc's.
369             void correctBoundaryConditions(pointVectorField&) const;
371             //- Move mesh. Does 2D correction (modifies passed pointField) and
372             //  polyMesh::movePoints. Returns swept volumes.
373             tmp<scalarField> movePoints(pointField&);
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);
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             );
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             );
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             );
414             //- Update topology
415             void updateMesh();
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             );
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             );
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             );
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             );
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             );
478             // Helper functions to manipulate displacement vector.
480                 //- Fully explicit smoothing of internal points with varying
481                 //  diffusivity.
482                 template <class Type>
483                 void smooth
484                 (
485                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
486                     const scalarField& edgeWeight,
487                     const bool separation,
488                     GeometricField<Type, pointPatchField, pointMesh>& newFld
489                 ) const;
493 template<>
494 void motionSmoother::applyCornerConstraints<scalar>
496     GeometricField<scalar, pointPatchField, pointMesh>& pf
497 ) const;
500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
502 } // End namespace Foam
504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
506 #ifdef NoRepository
507 #   include "motionSmootherTemplates.C"
508 #endif
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
512 #endif
514 // ************************************************************************* //