regionSplit.H 8.66 KB
Newer Older
1 2 3 4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
OpenFOAM bot's avatar
OpenFOAM bot committed
5
    \\  /    A nd           | www.openfoam.com
OpenFOAM bot's avatar
OpenFOAM bot committed
6 7
     \\/     M anipulation  |
-------------------------------------------------------------------------------
OpenFOAM bot's avatar
OpenFOAM bot committed
8
    Copyright (C) 2011-2013 OpenFOAM Foundation
9
    Copyright (C) 2018-2020 OpenCFD Ltd.
10 11 12 13
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

14 15 16 17
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
18 19 20 21 22 23 24

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
25
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
26 27 28 29 30 31

Class
    Foam::regionSplit

Description
    This class separates the mesh into distinct unconnected regions,
32 33 34 35 36
    each of which is then given a label according to globalNumbering().


    Say 6 cells, 3 processors, with single baffle on proc1.

37
    \verbatim
38 39 40 41 42 43 44
              baffle
                |
    +---+---+---+---+---+---+
    |   |   |   |   |   |   |
    +---+---+---+---+---+---+
      proc0 | proc1 | proc2

45
    \endverbatim
46 47


48 49
    \verbatim

50 51 52 53 54 55 56
    1: determine local regions (uncoupled)

    +---+---+---+---+---+---+
    | 0 | 0 | 0 | 1 | 0 | 0 |
    +---+---+---+---+---+---+
      proc0 | proc1 | proc2

57
    \endverbatim
58 59 60 61


    2: make global

62 63
    \verbatim

64 65 66 67 68
    +---+---+---+---+---+---+
    | 0 | 0 | 1 | 2 | 3 | 3 |
    +---+---+---+---+---+---+
      proc0 | proc1 | proc2

69
    \endverbatim
70 71 72 73


    3: merge connected across procs

74 75
    \verbatim

76 77 78 79 80
    +---+---+---+---+---+---+
    | 0 | 0 | 0 | 2 | 2 | 2 |
    +---+---+---+---+---+---+
      proc0 | proc1 | proc2

81
    \endverbatim
82 83


84
    4. determine locally owner regions.
85

86 87 88 89 90 91 92 93 94 95
    Determine compact numbering for the local regions and send these to
    all processors that need them:

    - proc0 uses regions:
      - 0 which is local to it.
    - proc1 uses regions
      - 0 which originates from proc0
      - 2 which is local to it
    - proc2 uses regions
      - 2 which originates from proc1
96 97 98 99

    So proc1 needs to get the compact number for region 0 from proc0 and proc2
    needs to get the compact number for region 2 from proc1:

100 101
    \verbatim

102 103 104 105 106
    +---+---+---+---+---+---+
    | 0 | 0 | 0 | 1 | 1 | 1 |
    +---+---+---+---+---+---+
      proc0 | proc1 | proc2

107 108
    \endverbatim

109 110
    Can optionally keep all regions local to the processor.

111 112 113
Note
    does not walk across cyclicAMI/cyclicACMI - since these are not
    \c coupled() at the patch level.
114

115 116 117 118 119 120 121 122
SourceFiles
    regionSplit.C

\*---------------------------------------------------------------------------*/

#ifndef regionSplit_H
#define regionSplit_H

123 124
#include "globalIndex.H"
#include "labelPair.H"
125
#include "bitSet.H"
126
#include "boolList.H"
mattijs's avatar
mattijs committed
127
#include "MeshObject.H"
128 129 130 131 132 133

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

134
// Forward Declarations
135 136
class polyMesh;

137
/*---------------------------------------------------------------------------*\
138
                         Class regionSplit Declaration
139 140 141 142
\*---------------------------------------------------------------------------*/

class regionSplit
:
143
    public MeshObject<polyMesh, TopologicalMeshObject, regionSplit>,
144 145
    public labelList
{
146
    // Private Data
147

148 149
        //- Indexing into the regions
        globalIndex globalNumbering_;
150 151 152 153 154 155

        //- Temporary list of cells that have changed
        mutable DynamicList<label> changedCells_;

        //- Temporary list of faces that have changed
        mutable DynamicList<label> changedFaces_;
156 157


158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    // Private Class


        //- Simple wrapper for handling test() on bitSet or boolList
        //- without a templating layer or lambda expresssion.
        class bitSetOrBoolList
        {
            const bitSet& a_;
            const boolList& b_;

        public:

            explicit bitSetOrBoolList(const bitSet& select)
            :
                a_(select),
                b_(boolList::null())
            {}

            explicit bitSetOrBoolList(const boolList& select)
            :
                a_(bitSet::null()),
                b_(select)
            {}

            //- Test function
            bool test(const label i) const
            {
                return a_.test(i) || b_.test(i);
            }
        };


190 191
    // Private Member Functions

192 193 194
        //- Check that boundary faces are synchronised, or Fatal
        void checkBoundaryFaceSync(const boolList& blockedFace) const;

195 196 197 198 199 200 201 202 203 204 205 206 207
        //- Update faceRegion data between (non-processor) coupled faces.
        void updateFacePair
        (
            const label face0,
            const label face1,
            labelList& faceRegion,
            DynamicList<label>& facesChanged
        ) const;

        //- Given a seed cell label, fill cellRegion/faceRegion with markValue
        //- for contiguous region around it
        void fillSeedMask
        (
208
            const UList<labelPair>& explicitConnections,
209 210 211 212 213 214 215 216 217 218
            const label seedCellID,
            const label markValue,
            labelList& cellRegion,
            labelList& faceRegion
        ) const;


        //- Calculate the local region split.
        //  \return number of processor-local regions,
        //      without consolidation between procesors
219
        label localRegionSplit
220
        (
221 222 223
            const UList<labelPair>& explicitConnections,
            labelList& cellRegion,
            labelList& faceRegion
224 225
        ) const;

226 227 228 229 230
        //- Manually consolidate regions globally by swapping information
        //  between processor domains and reducing the regions accordingly.
        //
        //  \return globalIndex into the local regions after reduction.
        globalIndex reduceRegionsImpl
231
        (
232 233
            const label numLocalRegions,
            const bitSetOrBoolList& blockedFace,
234 235 236
            labelList& cellRegion
        ) const;

mattijs's avatar
mattijs committed
237

238 239 240 241 242
public:

    //- Runtime type information
    ClassName("regionSplit");

mattijs's avatar
mattijs committed
243

244 245 246
    // Constructors

        //- Construct from mesh
247 248
        regionSplit
        (
249
            const polyMesh& mesh,
250 251
            const bool doGlobalRegions = Pstream::parRun()
        );
252

253 254 255 256
        //- Construct from mesh and whether face is blocked, optionally
        //- with additional explicit connections between
        //- normal boundary faces.
        //
257
        //  \note blockedFace must be consistent across coupled faces!
258 259
        regionSplit
        (
260
            const polyMesh& mesh,
261 262
            const bitSet& blockedFace,
            const List<labelPair>& explicitConnections = List<labelPair>(),
263 264
            const bool doGlobalRegions = Pstream::parRun()
        );
265

266 267 268 269
        //- Construct from mesh and whether face is blocked, optionally
        //- with additional explicit connections between
        //- normal boundary faces.
        //
270
        //  \note blockedFace must be consistent across coupled faces!
mattijs's avatar
mattijs committed
271 272
        regionSplit
        (
273
            const polyMesh& mesh,
mattijs's avatar
mattijs committed
274
            const boolList& blockedFace,
275
            const List<labelPair>& explicitConnections = List<labelPair>(),
276
            const bool doGlobalRegions = Pstream::parRun()
mattijs's avatar
mattijs committed
277 278
        );

mattijs's avatar
mattijs committed
279

280 281
    // Member Functions

282
        //- Return global region numbering
283
        const globalIndex& globalNumbering() const noexcept
284
        {
285
            return globalNumbering_;
286 287
        }

288 289 290 291 292 293
        //- Return local number of regions
        label nLocalRegions() const
        {
            return globalNumbering().localSize(Pstream::myProcNo());
        }

294
        //- Return total number of regions
295 296
        label nRegions() const
        {
297
            return globalNumbering().size();
298
        }
299

300
        //- Manually consolidate regions globally by swapping information
301 302
        //  between processor domains and reducing the regions accordingly.
        //
303 304
        //  \return globalIndex into the local regions after reduction.
        globalIndex reduceRegions
305 306
        (
            const label numLocalRegions,
307
            const bitSet& blockedFace,
308 309
            labelList& cellRegion
        ) const;
310 311 312 313 314 315 316 317 318 319 320 321
};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //