Merge branch 'master' of ssh://opencfd@repo.or.cz/srv/git/OpenFOAM-1.5.x
[OpenFOAM-1.5.x.git] / src / dynamicMesh / motionSmoother / motionSmoother.H
blobc9e20f6a55afdd329cdd657d5a0dc88e4e9dccc9
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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 SourceFiles
69     motionSmoother.C
70     motionSmootherTemplates.C
72 \*---------------------------------------------------------------------------*/
74 #ifndef motionSmoother_H
75 #define motionSmoother_H
77 #include "pointFields.H"
78 #include "labelHashSet.H"
79 #include "PackedList.H"
80 #include "indirectPrimitivePatch.H"
81 #include "className.H"
82 #include "twoDPointCorrector.H"
84 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
86 namespace Foam
89 class polyMeshGeometry;
90 class faceSet;
92 /*---------------------------------------------------------------------------*\
93                            Class motionSmoother Declaration
94 \*---------------------------------------------------------------------------*/
96 class motionSmoother
98     // Private class
100         //- To synchronise displacements. We want max displacement since
101         //  this is what is specified on pp and internal mesh will have
102         //  zero displacement.
103         class maxMagEqOp
104         {
106         public:
108             void operator()(vector& x, const vector& y) const
109             {
110                 for (direction i = 0; i < vector::nComponents; i++)
111                 {
112                     scalar magX = mag(x[i]);
113                     scalar magY = mag(y[i]);
115                     if (magX < magY)
116                     {
117                         x[i] = y[i];
118                     }
119                     else if (magX == magY)
120                     {
121                         if (y[i] > x[i])
122                         {
123                             x[i] = y[i];
124                         }
125                     }
126                 }
127             }
128         };
131     // Private data
133         //- Reference to polyMesh. Non-const since we move mesh.
134         polyMesh& mesh_;
136         //- Reference to pointMesh
137         pointMesh& pMesh_;
139         //- Reference to face subset of all adaptPatchIDs
140         indirectPrimitivePatch& pp_;
142         //- Indices of fixedValue patches that we're allowed to modify the
143         // displacement on.
144         const labelList adaptPatchIDs_;
147         // Smoothing and checking parameters
148         dictionary paramDict_;
150         // Internal data
152         //- Displacement field
153         pointVectorField displacement_;
155         //- Scale factor for displacement
156         pointScalarField scale_;
158         //- Starting mesh position
159         pointField oldPoints_;
161         //- Is mesh point on boundary or not
162         PackedList<1> isInternalPoint_;
164         //- Is edge master (always except if on coupled boundary and on
165         //  lower processor)
166         PackedList<1> isMasterEdge_;
168         //- 2-D motion corrector
169         twoDPointCorrector twoDCorrector_;
171         // Muli-patch constraints (from pointPatchInterpolation)
173             labelList patchPatchPointConstraintPoints_;
174             tensorField patchPatchPointConstraintTensors_;
177     // Private Member Functions
179         //- Average of connected points.
180         template <class Type>
181         tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
182         (
183             const GeometricField<Type, pointPatchField, pointMesh>& fld,
184             const scalarField& edgeWeight,
185             const bool separation
186         ) const;
188         //- Check constraints
189         template<class Type>
190         static void checkConstraints
191         (
192             GeometricField<Type, pointPatchField, pointMesh>&
193         );
195         //- Multi-patch constraints
196         template<class Type>
197         void applyCornerConstraints
198         (
199             GeometricField<Type, pointPatchField, pointMesh>&
200         ) const;
202         //- Test synchronisation of pointField
203         template<class Type, class CombineOp>
204         void testSyncField
205         (
206             const Field<Type>&,
207             const CombineOp& cop,
208             const Type& zero,
209             const bool separation
210         ) const;
212         //- Assemble tensors for multi-patch constraints
213         void makePatchPatchAddressing();
215         static void checkFld(const pointScalarField&);
217         //- Get points used by given faces
218         labelHashSet getPoints(const labelHashSet&) const;
220         //- explicit smoothing and min on all affected internal points
221         void minSmooth
222         (
223             const PackedList<1>& isAffectedPoint,
224             const pointScalarField& fld,
225             pointScalarField& newFld
226         ) const;
228         //- same but only on selected points (usually patch points)
229         void minSmooth
230         (
231             const PackedList<1>& isAffectedPoint,
232             const labelList& meshPoints,
233             const pointScalarField& fld,
234             pointScalarField& newFld
235         ) const;
237         //- Scale certain (internal) points of a field
238         void scaleField
239         (
240             const labelHashSet& pointLabels,
241             const scalar scale,
242             pointScalarField&
243         ) const;
245         //- As above but points have to be in meshPoints as well
246         //  (usually to scale patch points)
247         void scaleField
248         (
249             const labelList& meshPoints,
250             const labelHashSet& pointLabels,
251             const scalar scale,
252             pointScalarField&
253         ) const;
255         //- Helper function. Is point internal?
256         bool isInternalPoint(const label pointI) const;
258         //- Given a set of faces that cause smoothing and a number of
259         //  iterations determine the maximum set of points who are affected
260         //  and the accordingly affected faces.
261         void getAffectedFacesAndPoints
262         (
263             const label nPointIter,
264             const faceSet& wrongFaces,
266             labelList& affectedFaces,
267             PackedList<1>& isAffectedPoint
268         ) const;
270         //- Disallow default bitwise copy construct
271         motionSmoother(const motionSmoother&);
273         //- Disallow default bitwise assignment
274         void operator=(const motionSmoother&);
277 public:
279     ClassName("motionSmoother");
281     // Constructors
283         //- Construct from mesh, patches to work on and smoothing parameters.
284         //  Reads displacement field (only boundary conditions used)
285         motionSmoother
286         (
287             polyMesh&,
288             pointMesh&,
289             indirectPrimitivePatch& pp,         // 'outside' points
290             const labelList& adaptPatchIDs,     // patches forming 'outside'
291             const dictionary& paramDict
292         );
294         //- Construct from mesh, patches to work on and smoothing parameters and
295         //  displacementfield (only boundary conditions used)
296         motionSmoother
297         (
298             polyMesh&,
299             indirectPrimitivePatch& pp,         // 'outside' points
300             const labelList& adaptPatchIDs,     // patches forming 'outside'
301             const pointVectorField&,
302             const dictionary& paramDict
303         );
306     // Destructor
308         ~motionSmoother();
311     // Member Functions
313         // Access
315             //- Reference to mesh
316             const polyMesh& mesh() const;
318             //- Reference to pointMesh
319             const pointMesh& pMesh() const;
321             //- Reference to patch
322             const indirectPrimitivePatch& patch() const;
324             //- Patch labels that are being adapted
325             const labelList& adaptPatchIDs() const;
327             //- Reference to displacement field
328             pointVectorField& displacement();
330             //- Reference to displacement field
331             const pointVectorField& displacement() const;
333             //- Reference to scale field
334             const pointScalarField& scale() const;
336             //- Starting mesh position
337             const pointField& oldPoints() const;
339             //- Return reference to 2D point motion correction
340             twoDPointCorrector& twoDCorrector()
341             {
342                 return twoDCorrector_;
343             }
347         // Edit
349             //- Take over existing mesh position.
350             void correct();
352             //- Set displacement field from displacement on patch points.
353             //  Modify provided displacement to be consistent with actual
354             //  boundary conditions on displacement. Note: resets the
355             //  displacement to be 0 on coupled patches beforehand
356             //  to make sure shared points
357             //  partially on pp (on some processors) and partially not
358             //  (on other processors) get the value from pp.
359             void setDisplacement(pointField& patchDisp);
361             //- Special correctBoundaryConditions which evaluates fixedValue
362             //  patches first so they get overwritten with any constraint
363             //  bc's.
364             void correctBoundaryConditions(pointVectorField&) const;
366             //- Move mesh. Does 2D correction (modifies passed pointField) and
367             //  polyMesh::movePoints. Returns swept volumes.
368             tmp<scalarField> movePoints(pointField&);
370             //- Set the errorReduction (by how much to scale the displacement
371             //  at error locations) parameter. Returns the old value.
372             //  Set to 0 (so revert to old mesh) grows out one cell layer
373             //  from error faces.
374             scalar setErrorReduction(const scalar);
376             //- Move mesh with given scale. Return true if mesh ok or has
377             //  less than nAllow errors, false
378             //  otherwise and locally update scale. Smoothmesh=false means only
379             //  patch points get moved.
380             //  Parallel ok (as long as displacement field is consistent
381             //  across patches)
382             bool scaleMesh
383             (
384                 labelList& checkFaces,
385                 const bool smoothMesh = true,
386                 const label nAllow = 0
387             );
389             //- Move mesh (with baffles) with given scale.
390             bool scaleMesh
391             (
392                 labelList& checkFaces,
393                 const List<labelPair>& baffles,
394                 const bool smoothMesh = true,
395                 const label nAllow = 0
396             );
398             //- Update topology
399             void updateMesh();
401             //- Check mesh with mesh settings in dict. Collects incorrect faces
402             //  in set. Returns true if one or more faces in error.
403             //  Parallel ok.
404             static bool checkMesh
405             (
406                 const bool report,
407                 const polyMesh& mesh,
408                 const dictionary& dict,
409                 labelHashSet& wrongFaces
410             );
412             //- Check (subset of mesh) with mesh settings in dict.
413             //  Collects incorrect faces in set. Returns true if one
414             //  or more faces in error. Parallel ok.
415             static bool checkMesh
416             (
417                 const bool report,
418                 const polyMesh& mesh,
419                 const dictionary& dict,
420                 const labelList& checkFaces,
421                 labelHashSet& wrongFaces
422             );
424             //- Check (subset of mesh including baffles) with mesh settings
425             //  in dict. Collects incorrect faces in set. Returns true if one
426             //  or more faces in error. Parallel ok.
427             static bool checkMesh
428             (
429                 const bool report,
430                 const polyMesh& mesh,
431                 const dictionary& dict,
432                 const labelList& checkFaces,
433                 const List<labelPair>& baffles,
434                 labelHashSet& wrongFaces
435             );
437             //- Check part of mesh with mesh settings in dict.
438             //  Collects incorrect faces in set. Returns true if one or
439             //  more faces in error. Parallel ok.
440             static bool checkMesh
441             (
442                 const bool report,
443                 const dictionary& dict,
444                 const polyMeshGeometry&,
445                 const labelList& checkFaces,
446                 labelHashSet& wrongFaces
447             );
449             //- Check part of mesh including baffles with mesh settings in dict.
450             //  Collects incorrect faces in set. Returns true if one or
451             //  more faces in error. Parallel ok.
452             static bool checkMesh
453             (
454                 const bool report,
455                 const dictionary& dict,
456                 const polyMeshGeometry&,
457                 const labelList& checkFaces,
458                 const List<labelPair>& baffles,
459                 labelHashSet& wrongFaces
460             );
462             // Helper functions to manipulate displacement vector.
464                 //- Fully explicit smoothing of internal points with varying
465                 //  diffusivity.
466                 template <class Type>
467                 void smooth
468                 (
469                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
470                     const scalarField& edgeWeight,
471                     const bool separation,
472                     GeometricField<Type, pointPatchField, pointMesh>& newFld
473                 ) const;
477 template<>
478 void motionSmoother::applyCornerConstraints<scalar>
480     GeometricField<scalar, pointPatchField, pointMesh>& pf
481 ) const;
484 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
486 } // End namespace Foam
488 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
490 #ifdef NoRepository
491 #   include "motionSmootherTemplates.C"
492 #endif
494 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
496 #endif
498 // ************************************************************************* //