distributedTriSurfaceMesh.H 18.9 KB
Newer Older
mattijs's avatar
mattijs committed
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-2017 OpenFOAM Foundation
9
    Copyright (C) 2015-2020 OpenCFD Ltd.
mattijs's avatar
mattijs committed
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.
mattijs's avatar
mattijs committed
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/>.
mattijs's avatar
mattijs committed
26 27 28 29 30

Class
    Foam::distributedTriSurfaceMesh

Description
mattijs's avatar
mattijs committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44
    IOoject and searching on distributed triSurface. All processor hold
    (possibly overlapping) part of the overall surface. All queries are
    distributed to the processor that can answer it and the result sent back.

    Can work in three modes:
    - follow : makes sure each processor has all the triangles inside the
    externally provided bounding box (usually the mesh bounding box).
    Guarantees minimum amount of communication since mesh-local queries
    should be answerable without any comms.
    - independent : surface is decomposed according to the triangle centres
    so the decomposition might be radically different from the mesh
    decomposition. Guarantees best memory balance but at the expense of
    more communication.
    - frozen : no change
mattijs's avatar
mattijs committed
45

46 47 48 49 50 51 52 53 54
    Note: addressing used:
    distributedTriSurfaceMesh: none

    triSurfaceMesh:
    - surf.pointFaces()     : edge addressing (for volume tests only)
    - surf.edges()          : edgeTree
    - surf.faceFaces()      : only if minQuality > 0


mattijs's avatar
mattijs committed
55 56 57 58 59 60 61 62 63
SourceFiles
    distributedTriSurfaceMesh.C

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

#ifndef distributedTriSurfaceMesh_H
#define distributedTriSurfaceMesh_H

#include "triSurfaceMesh.H"
64
#include "localIOdictionary.H"
mattijs's avatar
mattijs committed
65 66 67
#include "IOdictionary.H"
#include "Pair.H"
#include "globalIndex.H"
68
#include "DynamicField.H"
mattijs's avatar
mattijs committed
69 70 71 72 73 74 75

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

namespace Foam
{

class mapDistribute;
mattijs's avatar
mattijs committed
76
class decompositionMethod;
mattijs's avatar
mattijs committed
77

mattijs's avatar
mattijs committed
78 79 80 81
// Typedefs
typedef Pair<point> segment;


mattijs's avatar
mattijs committed
82
/*---------------------------------------------------------------------------*\
83
                   Class distributedTriSurfaceMesh Declaration
mattijs's avatar
mattijs committed
84 85 86 87 88 89
\*---------------------------------------------------------------------------*/

class distributedTriSurfaceMesh
:
    public triSurfaceMesh
{
mattijs's avatar
mattijs committed
90
public:
mattijs's avatar
mattijs committed
91 92 93

    // Static data

mattijs's avatar
mattijs committed
94 95 96 97
        enum distributionType
        {
            FOLLOW = 0,
            INDEPENDENT = 1,
98 99
            DISTRIBUTED = 2,
            FROZEN = 3
mattijs's avatar
mattijs committed
100 101
        };

102
        static const Enum<distributionType> distributionTypeNames_;
mattijs's avatar
mattijs committed
103 104 105

private:

mattijs's avatar
mattijs committed
106 107
    // Private member data

mattijs's avatar
mattijs committed
108
        //- Merging distance
mattijs's avatar
mattijs committed
109 110
        scalar mergeDist_;

111 112
        autoPtr<IOdictionary> decomposeParDict_;

mattijs's avatar
mattijs committed
113 114
        //- Decomposition used when independently decomposing surface.
        autoPtr<decompositionMethod> decomposer_;
mattijs's avatar
mattijs committed
115 116

        //- Bounding box settings
117
        localIOdictionary dict_;
mattijs's avatar
mattijs committed
118

119
        //- Bounding boxes of all processors
120
        List<List<treeBoundBox>> procBb_;
mattijs's avatar
mattijs committed
121 122 123 124

        //- Global triangle numbering
        mutable autoPtr<globalIndex> globalTris_;

125
        //- The (wanted) distribution type.
mattijs's avatar
mattijs committed
126 127
        distributionType distType_;

128 129 130 131
        //- The (current) distribution type. Used to trigger re-distribution
        //  when starting from undecomposed surface.
        distributionType currentDistType_;

mattijs's avatar
mattijs committed
132 133 134 135 136

    // Private Member Functions

        // Read

137 138 139 140
            //- Search for io.local directory (=triSurface) either in case
            //  directory or in parent directory
            static word findLocalInstance(const IOobject& io);

mattijs's avatar
mattijs committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154
            //- Read my additional data
            bool read();


        // Line intersection

            static bool isLocal
            (
                const List<treeBoundBox>& myBbs,
                const point& start,
                const point& end
            );

            //- Split segment into subsegments overlapping the processor
mattijs's avatar
mattijs committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168
            //  bounding box.
            //void Foam::distributedTriSurfaceMesh::splitSegment
            //(
            //    const label segmentI,
            //    const point& start,
            //    const point& end,
            //    const treeBoundBox& bb,
            //
            //    DynamicList<segment>& allSegments,
            //    DynamicList<label>& allSegmentMap,
            //    DynamicList<label> sendMap
            //) const

            //- Distribute segments into overlapping processor
mattijs's avatar
mattijs committed
169
            //  bounding boxes. Sort per processor.
mattijs's avatar
mattijs committed
170
            void distributeSegment
mattijs's avatar
mattijs committed
171 172 173 174 175
            (
                const label,
                const point& start,
                const point& end,

mattijs's avatar
mattijs committed
176
                DynamicList<segment>&,
mattijs's avatar
mattijs committed
177
                DynamicList<label>&,
178
                List<DynamicList<label>>&
mattijs's avatar
mattijs committed
179 180 181 182
            ) const;

            //- Divide edges into local and remote segments. Construct map to
            //  distribute and collect data.
mattijs's avatar
mattijs committed
183
            autoPtr<mapDistribute> distributeSegments
mattijs's avatar
mattijs committed
184 185 186 187
            (
                const pointField& start,
                const pointField& end,

mattijs's avatar
mattijs committed
188
                List<segment>& allSegments,
mattijs's avatar
mattijs committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
                List<label>& allSegmentMap
            ) const;

            //- Split edges, distribute, test and collect.
            void findLine
            (
                const bool nearestIntersection,
                const pointField& start,
                const pointField& end,
                List<pointIndexHit>& info
            ) const;


        // Triangle index

sergio's avatar
ENH:  
sergio committed
204

205 206 207
            //- Helper: convert local triangle indices to global ones
            void convertTriIndices(List<pointIndexHit>& info) const;

mattijs's avatar
mattijs committed
208 209 210 211 212 213 214 215 216 217 218 219
            //- Obtains global indices from pointIndexHit and swaps them back
            //  to their original processor. Used to calculate local region
            //  and normal.
            autoPtr<mapDistribute> calcLocalQueries
            (
                const List<pointIndexHit>&,
                labelList& triangleIndex
            ) const;


        // Nearest

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
            //- Is location inside any of the bounding boxes
            bool contains
            (
                const List<treeBoundBox>& bbs,
                const point& sample
            ) const;

            //- Is location inside any of the processors bb or if not
            //  does it overlap
            Tuple2<label, scalar> findBestProcs
            (
                const point& centre,
                const scalar radiusSqr,
                boolList& procContains,
                boolList& procOverlaps,
                label& minProci
            ) const;

mattijs's avatar
mattijs committed
238 239 240 241 242 243 244
            label calcOverlappingProcs
            (
                const point& centre,
                const scalar radiusSqr,
                boolList& overlaps
            ) const;

245
            //- Calculate map to send centres+radius to processors
mattijs's avatar
mattijs committed
246 247
            autoPtr<mapDistribute> calcLocalQueries
            (
248
                const bool includeLocalProcessor,
mattijs's avatar
mattijs committed
249 250 251 252 253 254 255 256 257
                const pointField& centres,
                const scalarField& radiusSqr,

                pointField& allCentres,
                scalarField& allRadiusSqr,
                labelList& allSegmentMap
            ) const;


258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
        // Side

            //- Side of nearest point w.r.t. edge between face0 and face1
            volumeType edgeSide
            (
                const point& sample,
                const point& nearestPoint,
                const label face0,
                const label face1
            ) const;

            //- Find edge-connected face
            label findOtherFace
            (
                const labelListList& pointFaces,
                const label nearFacei,
                const label nearLabel
            ) const;

            //- Side of nearest point on faces w.r.t. samples. Handles nearest
            //  on edge/point
            void surfaceSide
            (
                const pointField& samples,
                const List<pointIndexHit>& nearestInfo,
                List<volumeType>& region
            ) const;


            // Caching of volume type (based on indexedOctree)

            //- Collect mid points of tree boxes
            void collectLeafMids
            (
                const label nodeI,
                DynamicField<point>& midPoints
            ) const;

            //- Find volume type of tree boxes
            volumeType calcVolumeType
            (
                const List<volumeType>& midPointTypes,
                label& index,
                PackedList<2>& nodeTypes,
                const label nodeI
            ) const;

            //- Look up any cached data. Return unknown if cannot be determined.
            volumeType cachedVolumeType
            (
                const label nodeI,
                const point& sample
            ) const;


mattijs's avatar
mattijs committed
313 314
        // Surface redistribution

315 316 317 318 319 320 321 322
            //- Calculate face-faces
            static void calcFaceFaces
            (
                const triSurface& s,
                const labelListList& pointFaces,
                labelListList& faceFaces
            );

Andrew Heather's avatar
Andrew Heather committed
323
            //- Finds new bounds based on an independent decomposition.
324
            List<List<treeBoundBox>> independentlyDistributedBbs
mattijs's avatar
mattijs committed
325 326 327 328
            (
                const triSurface&
            );

mattijs's avatar
mattijs committed
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
            //- Does any part of triangle overlap bb.
            static bool overlaps
            (
                const List<treeBoundBox>& bb,
                const point& p0,
                const point& p1,
                const point& p2
            );

            //- Find points used in subset
            static void subsetMeshMap
            (
                const triSurface& s,
                const boolList& include,
                const label nIncluded,
                labelList& newToOldPoints,
                labelList& oldToNewPoints,
                labelList& newToOldFaces
            );

            //- Construct subsetted surface
            static triSurface subsetMesh
            (
                const triSurface& s,
                const labelList& newToOldPoints,
                const labelList& oldToNewPoints,
                const labelList& newToOldFaces
            );

            //- Subset given marked faces
            static triSurface subsetMesh
            (
                const triSurface& s,
                const boolList& include,
                labelList& newToOldPoints,
                labelList& newToOldFaces
            );

            //- Subset given marked faces
            static triSurface subsetMesh
            (
                const triSurface& s,
                const labelList& newToOldFaces,
                labelList& newToOldPoints
            );

            //- Find triangle otherF in allFaces.
            static label findTriangle
            (
                const List<labelledTri>& allFaces,
                const labelListList& allPointFaces,
                const labelledTri& otherF
            );

            //- Merge triSurface (subTris, subPoints) into allTris, allPoints.
            static void merge
            (
                const scalar mergeDist,
                const List<labelledTri>& subTris,
                const pointField& subPoints,

                List<labelledTri>& allTris,
                pointField& allPoints,

                labelList& faceConstructMap,
                labelList& pointConstructMap
            );

            //- Distribute stored fields
            template<class Type>
            void distributeFields(const mapDistribute& map);


402 403
        //- No copy construct
        distributedTriSurfaceMesh(const distributedTriSurfaceMesh&) = delete;
mattijs's avatar
mattijs committed
404

405 406
        //- No copy assignment
        void operator=(const distributedTriSurfaceMesh&) = delete;
mattijs's avatar
mattijs committed
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424


public:

    //- Runtime type information
    TypeName("distributedTriSurfaceMesh");


    // Constructors

        //- Construct from triSurface
        distributedTriSurfaceMesh
        (
            const IOobject&,
            const triSurface&,
            const dictionary& dict
        );

mattijs's avatar
mattijs committed
425
        //- Construct read. Does findInstance to find io.local().
mattijs's avatar
mattijs committed
426 427
        distributedTriSurfaceMesh(const IOobject& io);

mattijs's avatar
mattijs committed
428 429
        //- Construct from dictionary (used by searchableSurface).
        //  Does read. Does findInstance to find io.local().
mattijs's avatar
mattijs committed
430 431 432 433 434 435 436
        distributedTriSurfaceMesh
        (
            const IOobject& io,
            const dictionary& dict
        );


437 438
    //- Destructor
    virtual ~distributedTriSurfaceMesh();
mattijs's avatar
mattijs committed
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

        //- Clear storage
        void clearOut();


    // Member Functions

        //- Triangle indexing (demand driven)
        const globalIndex& globalTris() const;


        // searchableSurface implementation

            //- Range of global indices that can be returned.
            virtual label globalSize() const
            {
455
                return globalTris().size();
mattijs's avatar
mattijs committed
456 457 458 459 460 461 462 463 464
            }

            virtual void findNearest
            (
                const pointField& sample,
                const scalarField& nearestDistSqr,
                List<pointIndexHit>&
            ) const;

465 466 467 468 469 470 471 472 473 474
            //- Find the nearest locations for the supplied points to a
            //  particular region in the searchable surface.
            virtual void findNearest
            (
                const pointField& samples,
                const scalarField& nearestDistSqr,
                const labelList& regionIndices,
                List<pointIndexHit>& info
            ) const;

mattijs's avatar
mattijs committed
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
            virtual void findLine
            (
                const pointField& start,
                const pointField& end,
                List<pointIndexHit>&
            ) const;

            virtual void findLineAny
            (
                const pointField& start,
                const pointField& end,
                List<pointIndexHit>&
            ) const;

            //- Get all intersections in order from start to end.
            virtual void findLineAll
            (
                const pointField& start,
                const pointField& end,
494
                List<List<pointIndexHit>>&
mattijs's avatar
mattijs committed
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
            ) const;

            //- From a set of points and indices get the region
            virtual void getRegion
            (
                const List<pointIndexHit>&,
                labelList& region
            ) const;

            //- From a set of points and indices get the normal
            virtual void getNormal
            (
                const List<pointIndexHit>&,
                vectorField& normal
            ) const;

            //- Determine type (inside/outside/mixed) for point. unknown if
            //  cannot be determined (e.g. non-manifold surface)
            virtual void getVolumeType
            (
                const pointField&,
                List<volumeType>&
            ) const;

            //- Set bounds of surface. Bounds currently set as list of
            //  bounding boxes. Will do redistribution of surface to locally
            //  have all triangles overlapping bounds.
            //  Larger bounds: more triangles (memory), more fully local tests
            //  (quick).
            //  keepNonLocal = true : keep triangles that do not overlap
            //  any processor bounds.
            //  Should really be split into a routine to determine decomposition
            //  and one that does actual distribution but determining
            //  decomposition with duplicate triangle merging requires
529
            //  same amount as work as actual distribution.
mattijs's avatar
mattijs committed
530 531 532 533 534 535 536 537 538 539 540
            virtual void distribute
            (
                const List<treeBoundBox>&,
                const bool keepNonLocal,
                autoPtr<mapDistribute>& faceMap,
                autoPtr<mapDistribute>& pointMap
            );


        // Other

541
            //- WIP. From a set of hits (points and
mattijs's avatar
mattijs committed
542
            //  indices) get the specified field. Misses do not get set.
543
            virtual void getField(const List<pointIndexHit>&, labelList&) const;
mattijs's avatar
mattijs committed
544

545 546 547 548 549 550 551 552
            //- Calculate the triangles that are overlapping bounds.
            static void overlappingSurface
            (
                const triSurface&,
                const List<treeBoundBox>&,
                boolList& includedFace
            );

mattijs's avatar
mattijs committed
553 554 555 556 557 558 559 560 561
            //- Subset the part of surface that is overlapping bounds.
            static triSurface overlappingSurface
            (
                const triSurface&,
                const List<treeBoundBox>&,
                labelList& subPointMap,
                labelList& subFaceMap
            );

sergio's avatar
ENH:  
sergio committed
562 563 564 565 566 567 568 569 570 571 572

            //- Obtains global indices from pointIndexHit and swaps them back
            //  to their original processor. Used to calculate local region
            //  and normal.
            virtual autoPtr<mapDistribute> localQueries
            (
                const List<pointIndexHit>&,
                labelList& triangleIndex
            ) const;


mattijs's avatar
mattijs committed
573 574 575 576 577 578 579
            //- Print some stats. Parallel aware version of
            //  triSurface::writeStats.
            void writeStats(Ostream& os) const;


        // regIOobject implementation

580
            //- Write using stream options
581 582 583 584
            //  Do not use the triSurfaceMesh::writeObject since it
            //  would filter out empty regions. These need to be preserved
            //  in case we want to make decisions based on the number of
            //  regions.
mattijs's avatar
mattijs committed
585 586
            virtual bool writeObject
            (
587
                IOstreamOption streamOpt,
588
                const bool valid
mattijs's avatar
mattijs committed
589 590
            ) const;

591 592 593 594 595 596 597 598 599 600 601 602
            //- Is object global
            virtual bool global() const
            {
                return false;
            }

            //- Return complete path + object name if the file exists
            //  either in the case/processor or case otherwise null
            virtual fileName filePath() const
            {
                return searchableSurface::localFilePath(type());
            }
mattijs's avatar
mattijs committed
603 604 605
};


606 607 608 609 610 611 612 613
//- Template function for obtaining global status
template<>
inline bool typeGlobal<distributedTriSurfaceMesh>()
{
    return false;
}


mattijs's avatar
mattijs committed
614 615 616 617 618 619 620
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

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

#ifdef NoRepository
621
    #include "distributedTriSurfaceMeshTemplates.C"
mattijs's avatar
mattijs committed
622 623 624 625 626 627 628
#endif

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

#endif

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