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

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