FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

motionSmoother.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Class
00025     Foam::motionSmoother
00026 
00027 Description
00028     Given a displacement moves the mesh by scaling the displacement back
00029     until there are no more mesh errors.
00030 
00031     Holds displacement field (read upon construction since need boundary
00032     conditions) and scaling factor and optional patch number on which to
00033     scale back displacement.
00034 
00035     E.g.
00036     @verbatim
00037         // Construct iterative mesh mover.
00038         motionSmoother meshMover(mesh, labelList(1, patchI));
00039 
00040         // Set desired displacement:
00041         meshMover.displacement() = ..
00042 
00043         for (label iter = 0; iter < maxIter; iter++)
00044         {
00045             if (meshMover.scaleMesh(true))
00046             {
00047                 Info<< "Successfully moved mesh" << endl;
00048                 return true;
00049             }
00050         }
00051     @endverbatim
00052 
00053 Note
00054     - Shared points (parallel): a processor can have points which are part of
00055     pp on another processor but have no pp itself (i.e. it has points
00056     and/or edges but no faces of pp). Hence we have to be careful when e.g.
00057     synchronising displacements that the value from the processor which has
00058     faces of pp get priority. This is currently handled in setDisplacement
00059     by resetting the internal displacement to zero before doing anything
00060     else. The combine operator used will give preference to non-zero
00061     values.
00062 
00063     - Various routines take baffles. These are sets of boundary faces that
00064     are treated as a single internal face. This is a hack used to apply
00065     movement to internal faces.
00066 
00067     - Mesh constraints are looked up from the supplied dictionary. (uses
00068     recursive lookup)
00069 
00070 SourceFiles
00071     motionSmoother.C
00072     motionSmootherTemplates.C
00073 
00074 \*---------------------------------------------------------------------------*/
00075 
00076 #ifndef motionSmoother_H
00077 #define motionSmoother_H
00078 
00079 #include <OpenFOAM/pointFields.H>
00080 #include <OpenFOAM/HashSet.H>
00081 #include <OpenFOAM/PackedBoolList.H>
00082 #include <OpenFOAM/indirectPrimitivePatch.H>
00083 #include <OpenFOAM/className.H>
00084 #include <meshTools/twoDPointCorrector.H>
00085 
00086 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00087 
00088 namespace Foam
00089 {
00090 
00091 class polyMeshGeometry;
00092 class faceSet;
00093 
00094 /*---------------------------------------------------------------------------*\
00095                            Class motionSmoother Declaration
00096 \*---------------------------------------------------------------------------*/
00097 
00098 class motionSmoother
00099 {
00100     // Private class
00101 
00102         //- To synchronise displacements. We want max displacement since
00103         //  this is what is specified on pp and internal mesh will have
00104         //  zero displacement.
00105         class maxMagEqOp
00106         {
00107 
00108         public:
00109 
00110             void operator()(vector& x, const vector& y) const
00111             {
00112                 for (direction i = 0; i < vector::nComponents; i++)
00113                 {
00114                     scalar magX = mag(x[i]);
00115                     scalar magY = mag(y[i]);
00116 
00117                     if (magX < magY)
00118                     {
00119                         x[i] = y[i];
00120                     }
00121                     else if (magX == magY)
00122                     {
00123                         if (y[i] > x[i])
00124                         {
00125                             x[i] = y[i];
00126                         }
00127                     }
00128                 }
00129             }
00130         };
00131 
00132 
00133     // Private data
00134 
00135         //- Reference to polyMesh. Non-const since we move mesh.
00136         polyMesh& mesh_;
00137 
00138         //- Reference to pointMesh
00139         pointMesh& pMesh_;
00140 
00141         //- Reference to face subset of all adaptPatchIDs
00142         indirectPrimitivePatch& pp_;
00143 
00144         //- Indices of fixedValue patches that we're allowed to modify the
00145         // displacement on.
00146         const labelList adaptPatchIDs_;
00147 
00148 
00149         // Smoothing and checking parameters
00150         dictionary paramDict_;
00151 
00152         // Internal data
00153 
00154         //- Displacement field
00155         pointVectorField displacement_;
00156 
00157         //- Scale factor for displacement
00158         pointScalarField scale_;
00159 
00160         //- Starting mesh position
00161         pointField oldPoints_;
00162 
00163         //- Is mesh point on boundary or not
00164         PackedBoolList isInternalPoint_;
00165 
00166         //- Is edge master (always except if on coupled boundary and on
00167         //  lower processor)
00168         PackedBoolList isMasterEdge_;
00169 
00170         //- 2-D motion corrector
00171         twoDPointCorrector twoDCorrector_;
00172 
00173         // Muli-patch constraints (from pointPatchInterpolation)
00174 
00175             labelList patchPatchPointConstraintPoints_;
00176             tensorField patchPatchPointConstraintTensors_;
00177 
00178 
00179     // Private Member Functions
00180 
00181         //- Average of connected points.
00182         template <class Type>
00183         tmp<GeometricField<Type, pointPatchField, pointMesh> > avg
00184         (
00185             const GeometricField<Type, pointPatchField, pointMesh>& fld,
00186             const scalarField& edgeWeight,
00187             const bool separation
00188         ) const;
00189 
00190         //- Check constraints
00191         template<class Type>
00192         static void checkConstraints
00193         (
00194             GeometricField<Type, pointPatchField, pointMesh>&
00195         );
00196 
00197         //- Multi-patch constraints
00198         template<class Type>
00199         void applyCornerConstraints
00200         (
00201             GeometricField<Type, pointPatchField, pointMesh>&
00202         ) const;
00203 
00204         //- Test synchronisation of pointField
00205         template<class Type, class CombineOp>
00206         void testSyncField
00207         (
00208             const Field<Type>&,
00209             const CombineOp& cop,
00210             const Type& zero,
00211             const bool separation,
00212             const scalar maxMag
00213         ) const;
00214 
00215         //- Assemble tensors for multi-patch constraints
00216         void makePatchPatchAddressing();
00217 
00218         static void checkFld(const pointScalarField&);
00219 
00220         //- Get points used by given faces
00221         labelHashSet getPoints(const labelHashSet&) const;
00222 
00223         //- explicit smoothing and min on all affected internal points
00224         void minSmooth
00225         (
00226             const PackedBoolList& isAffectedPoint,
00227             const pointScalarField& fld,
00228             pointScalarField& newFld
00229         ) const;
00230 
00231         //- same but only on selected points (usually patch points)
00232         void minSmooth
00233         (
00234             const PackedBoolList& isAffectedPoint,
00235             const labelList& meshPoints,
00236             const pointScalarField& fld,
00237             pointScalarField& newFld
00238         ) const;
00239 
00240         //- Scale certain (internal) points of a field
00241         void scaleField
00242         (
00243             const labelHashSet& pointLabels,
00244             const scalar scale,
00245             pointScalarField&
00246         ) const;
00247 
00248         //- As above but points have to be in meshPoints as well
00249         //  (usually to scale patch points)
00250         void scaleField
00251         (
00252             const labelList& meshPoints,
00253             const labelHashSet& pointLabels,
00254             const scalar scale,
00255             pointScalarField&
00256         ) const;
00257 
00258         //- Helper function. Is point internal?
00259         bool isInternalPoint(const label pointI) const;
00260 
00261         //- Given a set of faces that cause smoothing and a number of
00262         //  iterations determine the maximum set of points who are affected
00263         //  and the accordingly affected faces.
00264         void getAffectedFacesAndPoints
00265         (
00266             const label nPointIter,
00267             const faceSet& wrongFaces,
00268 
00269             labelList& affectedFaces,
00270             PackedBoolList& isAffectedPoint
00271         ) const;
00272 
00273         //- Disallow default bitwise copy construct
00274         motionSmoother(const motionSmoother&);
00275 
00276         //- Disallow default bitwise assignment
00277         void operator=(const motionSmoother&);
00278 
00279 
00280 public:
00281 
00282     ClassName("motionSmoother");
00283 
00284     // Constructors
00285 
00286         //- Construct from mesh, patches to work on and smoothing parameters.
00287         //  Reads displacement field (only boundary conditions used)
00288         motionSmoother
00289         (
00290             polyMesh&,
00291             pointMesh&,
00292             indirectPrimitivePatch& pp,         // 'outside' points
00293             const labelList& adaptPatchIDs,     // patches forming 'outside'
00294             const dictionary& paramDict
00295         );
00296 
00297         //- Construct from mesh, patches to work on and smoothing parameters and
00298         //  displacementfield (only boundary conditions used)
00299         motionSmoother
00300         (
00301             polyMesh&,
00302             indirectPrimitivePatch& pp,         // 'outside' points
00303             const labelList& adaptPatchIDs,     // patches forming 'outside'
00304             const pointVectorField&,
00305             const dictionary& paramDict
00306         );
00307 
00308 
00309     // Destructor
00310 
00311         ~motionSmoother();
00312 
00313 
00314     // Member Functions
00315 
00316         // Access
00317 
00318             //- Reference to mesh
00319             const polyMesh& mesh() const;
00320 
00321             //- Reference to pointMesh
00322             const pointMesh& pMesh() const;
00323 
00324             //- Reference to patch
00325             const indirectPrimitivePatch& patch() const;
00326 
00327             //- Patch labels that are being adapted
00328             const labelList& adaptPatchIDs() const;
00329 
00330             const dictionary& paramDict() const;
00331 
00332             //- Reference to displacement field
00333             pointVectorField& displacement();
00334 
00335             //- Reference to displacement field
00336             const pointVectorField& displacement() const;
00337 
00338             //- Reference to scale field
00339             const pointScalarField& scale() const;
00340 
00341             //- Starting mesh position
00342             const pointField& oldPoints() const;
00343 
00344             //- Return reference to 2D point motion correction
00345             twoDPointCorrector& twoDCorrector()
00346             {
00347                 return twoDCorrector_;
00348             }
00349 
00350 
00351 
00352         // Edit
00353 
00354             //- Take over existing mesh position.
00355             void correct();
00356 
00357             //- Set displacement field from displacement on patch points.
00358             //  Modify provided displacement to be consistent with actual
00359             //  boundary conditions on displacement. Note: resets the
00360             //  displacement to be 0 on coupled patches beforehand
00361             //  to make sure shared points
00362             //  partially on pp (on some processors) and partially not
00363             //  (on other processors) get the value from pp.
00364             void setDisplacement(pointField& patchDisp);
00365 
00366             //- Special correctBoundaryConditions which evaluates fixedValue
00367             //  patches first so they get overwritten with any constraint
00368             //  bc's.
00369             void correctBoundaryConditions(pointVectorField&) const;
00370 
00371             //- Move mesh. Does 2D correction (modifies passed pointField) and
00372             //  polyMesh::movePoints. Returns swept volumes.
00373             tmp<scalarField> movePoints(pointField&);
00374 
00375             //- Set the errorReduction (by how much to scale the displacement
00376             //  at error locations) parameter. Returns the old value.
00377             //  Set to 0 (so revert to old mesh) grows out one cell layer
00378             //  from error faces.
00379             scalar setErrorReduction(const scalar);
00380 
00381             //- Move mesh with given scale. Return true if mesh ok or has
00382             //  less than nAllow errors, false
00383             //  otherwise and locally update scale. Smoothmesh=false means only
00384             //  patch points get moved.
00385             //  Parallel ok (as long as displacement field is consistent
00386             //  across patches)
00387             bool scaleMesh
00388             (
00389                 labelList& checkFaces,
00390                 const bool smoothMesh = true,
00391                 const label nAllow = 0
00392             );
00393 
00394             //- Move mesh (with baffles) with given scale.
00395             bool scaleMesh
00396             (
00397                 labelList& checkFaces,
00398                 const List<labelPair>& baffles,
00399                 const bool smoothMesh = true,
00400                 const label nAllow = 0
00401             );
00402 
00403             //- Move mesh with externally provided mesh constraints
00404             bool scaleMesh
00405             (
00406                 labelList& checkFaces,
00407                 const List<labelPair>& baffles,
00408                 const dictionary& paramDict,
00409                 const dictionary& meshQualityDict,
00410                 const bool smoothMesh = true,
00411                 const label nAllow = 0
00412             );
00413 
00414             //- Update topology
00415             void updateMesh();
00416 
00417             //- Check mesh with mesh settings in dict. Collects incorrect faces
00418             //  in set. Returns true if one or more faces in error.
00419             //  Parallel ok.
00420             static bool checkMesh
00421             (
00422                 const bool report,
00423                 const polyMesh& mesh,
00424                 const dictionary& dict,
00425                 labelHashSet& wrongFaces
00426             );
00427 
00428             //- Check (subset of mesh) with mesh settings in dict.
00429             //  Collects incorrect faces in set. Returns true if one
00430             //  or more faces in error. Parallel ok.
00431             static bool checkMesh
00432             (
00433                 const bool report,
00434                 const polyMesh& mesh,
00435                 const dictionary& dict,
00436                 const labelList& checkFaces,
00437                 labelHashSet& wrongFaces
00438             );
00439 
00440             //- Check (subset of mesh including baffles) with mesh settings
00441             //  in dict. Collects incorrect faces in set. Returns true if one
00442             //  or more faces in error. Parallel ok.
00443             static bool checkMesh
00444             (
00445                 const bool report,
00446                 const polyMesh& mesh,
00447                 const dictionary& dict,
00448                 const labelList& checkFaces,
00449                 const List<labelPair>& baffles,
00450                 labelHashSet& wrongFaces
00451             );
00452 
00453             //- Check part of mesh with mesh settings in dict.
00454             //  Collects incorrect faces in set. Returns true if one or
00455             //  more faces in error. Parallel ok.
00456             static bool checkMesh
00457             (
00458                 const bool report,
00459                 const dictionary& dict,
00460                 const polyMeshGeometry&,
00461                 const labelList& checkFaces,
00462                 labelHashSet& wrongFaces
00463             );
00464 
00465             //- Check part of mesh including baffles with mesh settings in dict.
00466             //  Collects incorrect faces in set. Returns true if one or
00467             //  more faces in error. Parallel ok.
00468             static bool checkMesh
00469             (
00470                 const bool report,
00471                 const dictionary& dict,
00472                 const polyMeshGeometry&,
00473                 const labelList& checkFaces,
00474                 const List<labelPair>& baffles,
00475                 labelHashSet& wrongFaces
00476             );
00477 
00478             // Helper functions to manipulate displacement vector.
00479 
00480                 //- Fully explicit smoothing of internal points with varying
00481                 //  diffusivity.
00482                 template <class Type>
00483                 void smooth
00484                 (
00485                     const GeometricField<Type, pointPatchField, pointMesh>& fld,
00486                     const scalarField& edgeWeight,
00487                     const bool separation,
00488                     GeometricField<Type, pointPatchField, pointMesh>& newFld
00489                 ) const;
00490 };
00491 
00492 
00493 template<>
00494 void motionSmoother::applyCornerConstraints<scalar>
00495 (
00496     GeometricField<scalar, pointPatchField, pointMesh>& pf
00497 ) const;
00498 
00499 
00500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00501 
00502 } // End namespace Foam
00503 
00504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00505 
00506 #ifdef NoRepository
00507 #   include "motionSmootherTemplates.C"
00508 #endif
00509 
00510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00511 
00512 #endif
00513 
00514 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines