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

faceCoupleInfo.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::faceCoupleInfo
00026 
00027 Description
00028     Container for information needed to couple to meshes. When constructed
00029     from two meshes and a geometric tolerance finds the corresponding
00030     boundary faces.
00031 
00032     The information it keeps is the set of faces&points (cutFaces,
00033     cutPoints) that should replace a set of faces on the master
00034     (masterPatch) and a set of faces on the slave (slavePatch)
00035 
00036 
00037     Uses same tolerance to match faces and points on matched faces since
00038     they both originate from the same points and the tolerance usually
00039     comes from writing these points with limited precision (6 by default)
00040 
00041     -# Perfect match:
00042        - one-to-one match for faces and points.
00043        - the cut is always the 'most connected' of the master and slave so
00044          multiple master or slave points might point to the same cut point.
00045 
00046     @verbatim
00047     e.g. master:
00048     
00049         +--+
00050         |  |
00051         |  |
00052         +--+
00053             +--+
00054             |  |
00055             |  |
00056             +--+
00057     slave:
00058             +--+
00059             |  |
00060             |  |
00061             +--+
00062         +--+
00063         |  |
00064         |  |
00065         +--+
00066     @endverbatim
00067     adding both together creates a singly connected 2x2 cavity so suddenly
00068     the duplicate master points and the duplicate slave points all become
00069     a single cut point.
00070 
00071 
00072     -# Subdivision match:
00073        - Can be constructed from slave being subdivision of master with the
00074          polyPatch constructor.
00075        - Does not include above shared-point detection!
00076 
00077     Notes on multiple slave faces per master:
00078 
00079     As long as
00080     - all master edges are present in slave
00081     - slave can have extra edges/points/faces BUT all subfaces have to have
00082       at least one point on a maste face.
00083 
00084     @verbatim
00085     So master:
00086     +-------+
00087     |       |
00088     |       |
00089     |       |
00090     |       |
00091     |       |
00092     |       |
00093     |       |
00094     +-------+
00095 
00096     slave:
00097     +---+---+
00098     |\  |  /|
00099     | \ | / |
00100     |  \|/  |
00101     +---+---+
00102     |  /|\  |
00103     | / | \ |
00104     |/  |  \|
00105     +---+---+
00106     is ok.
00107     @endverbatim
00108 
00109     For this kind of matching the order is:
00110     - match cutpoint to masterpoint
00111     - find those cutEdges that align with a master edge. This gives two sets
00112       of cut edges: those that have a master equivalent ('border edges') and
00113       those that don't ('internal edges'). The border edges now divide the
00114       cutFaces into regions with the same masterFace correspondence.
00115     - find cutFaces that are fully determined by the border edges they use.
00116     - all cutFaces that are connected through an internal edge have the same
00117       master face.
00118 
00119 
00120     Note: matching refined faces onto master is a bit dodgy and will probably
00121     only work for unwarped faces. Also it will fail if e.g. face is split
00122     into 3x3 since then middle face has no point/edge in common with master.
00123     (problem is in face matching (findSlavesCoveringMaster), probably
00124      point/edge matching might just work)
00125 
00126 
00127 SourceFiles
00128     faceCoupleInfo.C
00129 
00130 
00131 \*---------------------------------------------------------------------------*/
00132 
00133 #ifndef faceCoupleInfo_H
00134 #define faceCoupleInfo_H
00135 
00136 #include <OpenFOAM/pointField.H>
00137 #include <OpenFOAM/indirectPrimitivePatch.H>
00138 #include <OpenFOAM/primitiveFacePatch.H>
00139 
00140 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00141 
00142 namespace Foam
00143 {
00144 
00145 typedef HashTable<labelList, edge, Hash<edge> > edgeLookup;
00146 
00147 
00148 // Forward declaration of classes
00149 class face;
00150 class primitiveMesh;
00151 class polyPatch;
00152 class polyMesh;
00153 
00154 /*---------------------------------------------------------------------------*\
00155                            Class faceCoupleInfo Declaration
00156 \*---------------------------------------------------------------------------*/
00157 
00158 class faceCoupleInfo
00159 {
00160     // Private data
00161 
00162         //- Angle matching tolerance.
00163         static const scalar angleTol_;
00164 
00165         //- Master patch
00166         autoPtr<indirectPrimitivePatch> masterPatchPtr_;
00167 
00168         //- Slave patch
00169         autoPtr<indirectPrimitivePatch> slavePatchPtr_;
00170 
00171 
00172         //- Description of cut.
00173         //  - Cut is the matching area between the slave
00174         //  and the master.
00175         //  - cut is the finest of master and slave. It can never be
00176         //  coarser than either one of them. (so face addressing we keep is
00177         //  cut-to-master and cut-to-slave)
00178         //  - multiple master or slave points can end up becoming one cut point
00179         //  (so point addressing we keep is master-to-cut and slave-to-cut)
00180 
00181         //  Cut consists of faces and points (note: could be expressed as some
00182         //  kind of PrimitivePatch which holds points instead of reference to
00183         //  them)
00184         //  Orientation of cutFaces should be same as masterFaces!
00185         pointField cutPoints_;
00186         autoPtr<primitiveFacePatch> cutFacesPtr_;
00187 
00188         //- Additional point coupling information. Is between points on
00189         //  boundary of both meshes.
00190 
00191         // Addressing to/from cut
00192 
00193             //- master
00194             labelList cutToMasterFaces_;
00195             labelList masterToCutPoints_;
00196 
00197             //- slave
00198             labelList cutToSlaveFaces_;
00199             labelList slaveToCutPoints_;
00200 
00201             //- For edges originating from splitting of edges:
00202             //  given the two endpoints of the unsplit edge give the list
00203             //  of inbetween vertices
00204             edgeLookup cutEdgeToPoints_;
00205 
00206 
00207     // Private Member Functions
00208 
00209         // Debugging
00210 
00211             //- Calculate face centres from (subset of) faces.
00212             template<template<class> class FaceList>
00213             static pointField calcFaceCentres
00214             (
00215                 const FaceList<face>&,
00216                 const pointField&,
00217                 const label start,
00218                 const label size
00219             );
00220 
00221             //- Write edges
00222             static void writeOBJ
00223             (
00224                 const fileName& fName,
00225                 const edgeList& edges,
00226                 const pointField& points,
00227                 const bool compact = true
00228             );
00229 
00230             //- Write edges
00231             static void writeOBJ
00232             (
00233                 const fileName& fName,
00234                 const pointField& points0,
00235                 const pointField& points1
00236             );
00237 
00238             //- Write connections between corresponding points and faces
00239             //  as .obj files.
00240             void writePointsFaces() const;
00241 
00242             //- Write connections between corresponding edges as .obj files.
00243             void writeEdges(const labelList&, const labelList&) const;
00244 
00245 
00246         // Edge handling/matching
00247 
00248             //- Find corresponding edges on patch when having only a map for
00249             //  the points.
00250             labelList findMappedEdges
00251             (
00252                 const edgeList& edges,
00253                 const labelList& pointMap,
00254                 const indirectPrimitivePatch&
00255             );
00256 
00257             //- Check if edge on slavePatch corresponds to an edge between faces
00258             //  in two different polyPatches on the mesh.
00259             bool regionEdge(const polyMesh&, const label slaveEdgeI) const;
00260 
00261             //- Finds edge connected to point most aligned with master edge.
00262             label mostAlignedCutEdge
00263             (
00264                 const bool report,
00265                 const polyMesh& slaveMesh,
00266                 const bool patchDivision,
00267                 const labelList& cutToMasterEdges,
00268                 const labelList& cutToSlaveEdges,
00269                 const label pointI,
00270                 const label edgeStart,
00271                 const label edgeEnd
00272             ) const;
00273 
00274             //- From (many-to-one) map of cut edges to master edges determine
00275             //  points inbetween. I.e. just string up the edges. Stores this
00276             //  all on cutEdgeToPoints_
00277             void setCutEdgeToPoints(const labelList& cutToMasterEdges);
00278 
00279         // Face matching
00280 
00281             //- Matches two faces.Determines rotation for f1 to match up
00282             // with f0, i.e. the index in f0 of
00283             // the first point of f1.
00284             static label matchFaces
00285             (
00286                 const scalar absTol,
00287                 const pointField& points0,
00288                 const face& f0,
00289                 const pointField& points1,
00290                 const face& f1,
00291                 const bool sameOrientation
00292             );
00293 
00294             //- Matches points on patch to points on cut.
00295             static bool matchPointsThroughFaces
00296             (
00297                 const scalar absTol,
00298                 const pointField& cutPoints,
00299                 const faceList& cutFaces,
00300                 const pointField& patchPoints,
00301                 const faceList& patchFaces,
00302                 const bool sameOrientation,
00303 
00304                 labelList& patchToCutPoints,    // patch to (uncompacted) cut points
00305                 labelList& cutToCompact,        // compaction list
00306                 labelList& compactToCut         // compaction list
00307             );
00308 
00309             //- Returns max distance to masterF of any point on cutF.
00310             static scalar maxDistance
00311             (
00312                 const face& cutF,
00313                 const pointField& cutPoints,
00314                 const face& masterF,
00315                 const pointField& masterPoints
00316             );
00317 
00318             //- Finds matching (boundary)face centres.
00319             //  Since faces identical uses geometric match on face centres.
00320             static void findPerfectMatchingFaces
00321             (
00322                 const primitiveMesh& mesh0,
00323                 const primitiveMesh& mesh1,
00324                 const scalar absTol,
00325 
00326                 labelList& mesh0Faces,
00327                 labelList& mesh1Faces
00328             );
00329 
00330             //- Find matching (boundary)faces. Matching if slave is on top of
00331             //  master face (slaves is subdivision of master)
00332             static void findSlavesCoveringMaster
00333             (
00334                 const primitiveMesh& mesh0,
00335                 const primitiveMesh& mesh1,
00336                 const scalar absTol,
00337 
00338                 labelList& mesh0Faces,
00339                 labelList& mesh1Faces
00340             );
00341 
00342             //- Grow cutToMasterFace across 'internal' edges.
00343             label growCutFaces(const labelList&, Map<labelList>&);
00344 
00345             void checkMatch(const labelList& cutToMasterEdges) const;
00346 
00347             //- Gets a list of cutFaces (that use a master edge) and the
00348             // candidate master faces.
00349             // Checks among these master faces if there is only one remaining
00350             // unmatched one.
00351             label matchEdgeFaces(const labelList&, Map<labelList>& candidates);
00352 
00353             //- Gets a list of cutFaces (that use a master edge) and the
00354             //  candidate master faces.
00355             //  Finds most aligned master face.
00356             label geometricMatchEdgeFaces(Map<labelList>& candidates);
00357 
00358         //- Used by perfectPointMatch. Determine match from cut points to
00359         //  slave points (for perfect matching faces)
00360         void perfectSlavePointMatch(const scalar absTol);
00361 
00362         //- Find point and edge correspondence for perfect matching faces
00363         void perfectPointMatch(const scalar absTol, const bool);
00364 
00365         //- Find point and edge correspondence for slaves being subdivision of
00366         //  master.
00367         void subDivisionMatch
00368         (
00369             const polyMesh& slaveMesh,
00370             const bool patchDivision,
00371             const scalar absTol
00372         );
00373 
00374 public:
00375 
00376     //- Runtime type information
00377     ClassName("faceCoupleInfo");
00378 
00379 
00380     // Constructors
00381 
00382         //- Construct from two meshes and absolute tolerance.
00383         //  Finds out matches geometrically. No checking for nonsense match.
00384         //  Tolerance is absolute one so use with care.
00385         //  perfectMatch : each point/edge/face has corresponding point on other
00386         //                 side
00387         //                 if this is false then assumes slave is subdivision.
00388         //                 Matching then will work only for non-warped faces
00389         //                 since does nearest-to-face comparison with absTol.
00390         faceCoupleInfo
00391         (
00392             const polyMesh& mesh0,
00393             const polyMesh& mesh1,
00394             const scalar absTol,
00395             const bool perfectMatch
00396         );
00397 
00398         //- Construct from meshes and subset of mesh faces
00399         //  (i.e. indirectPrimitivePatch addressing)
00400         //  All faces in patch are considered matched (but don't have to be 
00401         //  ordered)
00402         //  perfectMatch : each point/edge/face has corresponding point on other
00403         //                 side
00404         //  orderedFaces : faces in patch are ordered (so masterAddressing[i]
00405         //  matches slaveAddressing[i])
00406         //  patchDivision: faces in slave mesh that originate from the
00407         //  same master face have the same patch. Used by some triangulation
00408         //  methods.
00409         faceCoupleInfo
00410         (
00411             const polyMesh& masterMesh,
00412             const labelList& masterAddressing,
00413             const polyMesh& slaveMesh,
00414             const labelList& slaveAddressing,
00415             const scalar absTol,
00416             const bool perfectMatch,
00417             const bool orderedFaces,
00418             const bool patchDivision
00419         );
00420 
00421 
00422     // Destructor
00423 
00424         ~faceCoupleInfo();
00425 
00426 
00427 
00428     // Member Functions
00429 
00430         //- Utility functions
00431 
00432             //- Get patch face labels
00433             static labelList faceLabels(const polyPatch&);
00434 
00435             //- Create Map from List
00436             static Map<label> makeMap(const labelList&);
00437             static Map<labelList> makeMap(const labelListList&);
00438 
00439 
00440         // Access
00441 
00442             //- Addressing engine for coupled faces on mesh0
00443             const indirectPrimitivePatch& masterPatch() const
00444             {
00445                 return masterPatchPtr_();
00446             }
00447 
00448             //- Addressing engine for coupled faces on mesh1
00449             const indirectPrimitivePatch& slavePatch() const
00450             {
00451                 return slavePatchPtr_();
00452             }
00453 
00454             //- Addressing engine for combined set of faces.
00455             const primitiveFacePatch& cutFaces() const
00456             {
00457                 return cutFacesPtr_();
00458             }
00459 
00460             //- Points for combined set of faces.
00461             const pointField& cutPoints() const
00462             {
00463                 return cutPoints_;
00464             }
00465 
00466 
00467         // Addressing from meshes to cut and vice versa.
00468 
00469             //- Master face for every face on cut. Will always be at least
00470             //  one but there might be multiple cut faces pointing to the same
00471             //  master
00472             const labelList& cutToMasterFaces() const
00473             {
00474                 return cutToMasterFaces_;
00475             }
00476             const labelList& masterToCutPoints() const
00477             {
00478                 return masterToCutPoints_;
00479             }
00480 
00481             const labelList& cutToSlaveFaces() const
00482             {
00483                 return cutToSlaveFaces_;
00484             }
00485             const labelList& slaveToCutPoints() const
00486             {
00487                 return slaveToCutPoints_;
00488             }
00489 
00490             //- From two cut points (original edge) to list of inserted
00491             //  points
00492             const edgeLookup& cutEdgeToPoints() const
00493             {
00494                 return cutEdgeToPoints_;
00495             }
00496 
00497  };
00498 
00499 
00500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00501 
00502 } // End namespace Foam
00503 
00504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00505 
00506 #ifdef NoRepository
00507 #   include <dynamicMesh/faceCoupleInfoTemplates.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