ENH: allow certain difference when checking motionSmoother status
[OpenFOAM-1.6.x.git] / src / dynamicMesh / motionSmoother / motionSmoother.H
blob0814de3f7efdd52e2583c52a08b0959faeb4f01b
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 scalar maxMag
214         ) const;
216         //- Assemble tensors for multi-patch constraints
217         void makePatchPatchAddressing();
219         static void checkFld(const pointScalarField&);
221         //- Get points used by given faces
222         labelHashSet getPoints(const labelHashSet&) const;
224         //- explicit smoothing and min on all affected internal points
225         void minSmooth
226         (
227             const PackedBoolList& isAffectedPoint,
228             const pointScalarField& fld,
229             pointScalarField& newFld
230         ) const;
232         //- same but only on selected points (usually patch points)
233         void minSmooth
234         (
235             const PackedBoolList& isAffectedPoint,
236             const labelList& meshPoints,
237             const pointScalarField& fld,
238             pointScalarField& newFld
239         ) const;
241         //- Scale certain (internal) points of a field
242         void scaleField
243         (
244             const labelHashSet& pointLabels,
245             const scalar scale,
246             pointScalarField&
247         ) const;
249         //- As above but points have to be in meshPoints as well
250         //  (usually to scale patch points)
251         void scaleField
252         (
253             const labelList& meshPoints,
254             const labelHashSet& pointLabels,
255             const scalar scale,
256             pointScalarField&
257         ) const;
259         //- Helper function. Is point internal?
260         bool isInternalPoint(const label pointI) const;
262         //- Given a set of faces that cause smoothing and a number of
263         //  iterations determine the maximum set of points who are affected
264         //  and the accordingly affected faces.
265         void getAffectedFacesAndPoints
266         (
267             const label nPointIter,
268             const faceSet& wrongFaces,
270             labelList& affectedFaces,
271             PackedBoolList& isAffectedPoint
272         ) const;
274         //- Disallow default bitwise copy construct
275         motionSmoother(const motionSmoother&);
277         //- Disallow default bitwise assignment
278         void operator=(const motionSmoother&);
281 public:
283     ClassName("motionSmoother");
285     // Constructors
287         //- Construct from mesh, patches to work on and smoothing parameters.
288         //  Reads displacement field (only boundary conditions used)
289         motionSmoother
290         (
291             polyMesh&,
292             pointMesh&,
293             indirectPrimitivePatch& pp,         // 'outside' points
294             const labelList& adaptPatchIDs,     // patches forming 'outside'
295             const dictionary& paramDict
296         );
298         //- Construct from mesh, patches to work on and smoothing parameters and
299         //  displacementfield (only boundary conditions used)
300         motionSmoother
301         (
302             polyMesh&,
303             indirectPrimitivePatch& pp,         // 'outside' points
304             const labelList& adaptPatchIDs,     // patches forming 'outside'
305             const pointVectorField&,
306             const dictionary& paramDict
307         );
310     // Destructor
312         ~motionSmoother();
315     // Member Functions
317         // Access
319             //- Reference to mesh
320             const polyMesh& mesh() const;
322             //- Reference to pointMesh
323             const pointMesh& pMesh() const;
325             //- Reference to patch
326             const indirectPrimitivePatch& patch() const;
328             //- Patch labels that are being adapted
329             const labelList& adaptPatchIDs() const;
331             const dictionary& paramDict() const;
333             //- Reference to displacement field
334             pointVectorField& displacement();
336             //- Reference to displacement field
337             const pointVectorField& displacement() const;
339             //- Reference to scale field
340             const pointScalarField& scale() const;
342             //- Starting mesh position
343             const pointField& oldPoints() const;
345             //- Return reference to 2D point motion correction
346             twoDPointCorrector& twoDCorrector()
347             {
348                 return twoDCorrector_;
349             }
353         // Edit
355             //- Take over existing mesh position.
356             void correct();
358             //- Set displacement field from displacement on patch points.
359             //  Modify provided displacement to be consistent with actual
360             //  boundary conditions on displacement. Note: resets the
361             //  displacement to be 0 on coupled patches beforehand
362             //  to make sure shared points
363             //  partially on pp (on some processors) and partially not
364             //  (on other processors) get the value from pp.
365             void setDisplacement(pointField& patchDisp);
367             //- Special correctBoundaryConditions which evaluates fixedValue
368             //  patches first so they get overwritten with any constraint
369             //  bc's.
370             void correctBoundaryConditions(pointVectorField&) const;
372             //- Move mesh. Does 2D correction (modifies passed pointField) and
373             //  polyMesh::movePoints. Returns swept volumes.
374             tmp<scalarField> movePoints(pointField&);
376             //- Set the errorReduction (by how much to scale the displacement
377             //  at error locations) parameter. Returns the old value.
378             //  Set to 0 (so revert to old mesh) grows out one cell layer
379             //  from error faces.
380             scalar setErrorReduction(const scalar);
382             //- Move mesh with given scale. Return true if mesh ok or has
383             //  less than nAllow errors, false
384             //  otherwise and locally update scale. Smoothmesh=false means only
385             //  patch points get moved.
386             //  Parallel ok (as long as displacement field is consistent
387             //  across patches)
388             bool scaleMesh
389             (
390                 labelList& checkFaces,
391                 const bool smoothMesh = true,
392                 const label nAllow = 0
393             );
395             //- Move mesh (with baffles) with given scale.
396             bool scaleMesh
397             (
398                 labelList& checkFaces,
399                 const List<labelPair>& baffles,
400                 const bool smoothMesh = true,
401                 const label nAllow = 0
402             );
404             //- Move mesh with externally provided mesh constraints
405             bool scaleMesh
406             (
407                 labelList& checkFaces,
408                 const List<labelPair>& baffles,
409                 const dictionary& paramDict,
410                 const dictionary& meshQualityDict,
411                 const bool smoothMesh = true,
412                 const label nAllow = 0
413             );
415             //- Update topology
416             void updateMesh();
418             //- Check mesh with mesh settings in dict. Collects incorrect faces
419             //  in set. Returns true if one or more faces in error.
420             //  Parallel ok.
421             static bool checkMesh
422             (
423                 const bool report,
424                 const polyMesh& mesh,
425                 const dictionary& dict,
426                 labelHashSet& wrongFaces
427             );
429             //- Check (subset of mesh) with mesh settings in dict.
430             //  Collects incorrect faces in set. Returns true if one
431             //  or more faces in error. Parallel ok.
432             static bool checkMesh
433             (
434                 const bool report,
435                 const polyMesh& mesh,
436                 const dictionary& dict,
437                 const labelList& checkFaces,
438                 labelHashSet& wrongFaces
439             );
441             //- Check (subset of mesh including baffles) with mesh settings
442             //  in dict. Collects incorrect faces in set. Returns true if one
443             //  or more faces in error. Parallel ok.
444             static bool checkMesh
445             (
446                 const bool report,
447                 const polyMesh& mesh,
448                 const dictionary& dict,
449                 const labelList& checkFaces,
450                 const List<labelPair>& baffles,
451                 labelHashSet& wrongFaces
452             );
454             //- Check part of mesh with mesh settings in dict.
455             //  Collects incorrect faces in set. Returns true if one or
456             //  more faces in error. Parallel ok.
457             static bool checkMesh
458             (
459                 const bool report,
460                 const dictionary& dict,
461                 const polyMeshGeometry&,
462                 const labelList& checkFaces,
463                 labelHashSet& wrongFaces
464             );
466             //- Check part of mesh including baffles with mesh settings in dict.
467             //  Collects incorrect faces in set. Returns true if one or
468             //  more faces in error. Parallel ok.
469             static bool checkMesh
470             (
471                 const bool report,
472                 const dictionary& dict,
473                 const polyMeshGeometry&,
474                 const labelList& checkFaces,
475                 const List<labelPair>& baffles,
476                 labelHashSet& wrongFaces
477             );
479             // Helper functions to manipulate displacement vector.
481                 //- Fully explicit smoothing of internal points with varying
482                 //  diffusivity.
483                 template <class Type>
484                 void smooth
485                 (
486                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
487                     const scalarField& edgeWeight,
488                     const bool separation,
489                     GeometricField<Type, pointPatchField, pointMesh>& newFld
490                 ) const;
494 template<>
495 void motionSmoother::applyCornerConstraints<scalar>
497     GeometricField<scalar, pointPatchField, pointMesh>& pf
498 ) const;
501 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
503 } // End namespace Foam
505 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
507 #ifdef NoRepository
508 #   include "motionSmootherTemplates.C"
509 #endif
511 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
513 #endif
515 // ************************************************************************* //