diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C index 198be01bcf..a6547fa114 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -168,12 +168,7 @@ void Foam::shellSurfaces::orient() { const searchableSurface& s = allGeometry_[shells_[shellI]]; - if - ( - modes_[shellI] != DISTANCE - && isA(s) - && !isA(s) - ) + if (modes_[shellI] != DISTANCE && isA(s)) { hasSurface = true; @@ -196,35 +191,39 @@ void Foam::shellSurfaces::orient() { const searchableSurface& s = allGeometry_[shells_[shellI]]; - if - ( - modes_[shellI] != DISTANCE - && isA(s) - && !isA(s) - ) + if (modes_[shellI] != DISTANCE && isA(s)) { - triSurfaceMesh& shell = const_cast + List info; + vectorField normal; + labelList region; + s.findNearest ( - refCast(s) + pointField(1, outsidePt), + scalarField(1, GREAT), + info, + normal, + region ); - // Flip surface so outsidePt is outside. - bool anyFlipped = orientedSurface::orient - ( - shell, - outsidePt, - true - ); + //Pout<< "outsidePt:" << outsidePt << endl; + //Pout<< "info :" << info[0] << endl; + //Pout<< "normal :" << normal[0] << endl; + //Pout<< "region :" << region[0] << endl; + + bool anyFlipped = false; + if ((normal[0] & (info[0].point()-outsidePt)) > 0) + { + triSurfaceMesh& shell = const_cast + ( + refCast(s) + ); + shell.flip(); + anyFlipped = true; + } + if (anyFlipped && !dryRun_) { - // orientedSurface will have done a clearOut of the surface. - // we could do a clearout of the triSurfaceMeshes::trees() - // but these aren't affected by orientation - // (except for cached - // sideness which should not be set at this point. - // !!Should check!) - Info<< "shellSurfaces : Flipped orientation of surface " << s.name() << " so point " << outsidePt << " is outside." << endl; diff --git a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C index 8976887905..4d13ca4deb 100644 --- a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C +++ b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2015-2020,2022 OpenCFD Ltd. + Copyright (C) 2015-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -101,6 +101,7 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const if (debug) { Pout<< "triSurfaceMesh::isSurfaceClosed:" + << " surface:" << searchableSurface::name() << " determining closedness for surface with " << triSurface::size() << " triangles" << endl; } @@ -223,6 +224,7 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const if (debug) { Pout<< "triSurfaceMesh::isSurfaceClosed :" + << " surface:" << searchableSurface::name() << " surface is non-manifold" << endl; } return false; @@ -240,6 +242,7 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const if (debug) { Pout<< "triSurfaceMesh::isSurfaceClosed :" + << " surface:" << searchableSurface::name() << " surface is open" << endl; } return false; @@ -274,6 +277,7 @@ bool Foam::triSurfaceMesh::isSurfaceClosed() const if (debug) { Pout<< "triSurfaceMesh::isSurfaceClosed :" + << " surface:" << searchableSurface::name() << " surface is closed" << endl; } return true; @@ -738,6 +742,7 @@ void Foam::triSurfaceMesh::movePoints(const pointField& newPoints) if (debug) { Pout<< "triSurfaceMesh::movePoints :" + << " surface:" << searchableSurface::name() << " moving at time " << objectRegistry::time().timeName() << endl; } @@ -773,6 +778,7 @@ Foam::triSurfaceMesh::edgeTree() const if (debug) { Pout<< "triSurfaceMesh::edgeTree :" + << " surface:" << searchableSurface::name() << " constructing tree for " << nEdges() - nInternalEdges() << " boundary edges" << endl; } @@ -882,6 +888,7 @@ Foam::volumeType Foam::triSurfaceMesh::outsideVolumeType() const if (debug) { Pout<< "triSurfaceMesh::outsideVolumeType :" + << " surface:" << searchableSurface::name() << " triggering outsidePoint:" << outsidePt << " orientation" << endl; } @@ -906,6 +913,49 @@ Foam::volumeType Foam::triSurfaceMesh::outsideVolumeType() const } +void Foam::triSurfaceMesh::flip() +{ + if (debug) + { + Pout<< "triSurfaceMesh::flip :" + << " surface:" << searchableSurface::name() + << " with current orientation " + << volumeType::names[outsideVolType_] + << endl; + } + + // Don't bother getting nearest etc. Just flip the triangles. + + // triSurface + { + triSurface& s = *this; + s.clearOut(); + for (auto& tri : s) + { + tri.flip(); + } + } + + // triSurfaceRegionSearch (if cached volume type) + triSurfaceRegionSearch::flip(); + + // edge tree not relevant + + if (hasVolumeType()) + { + // outsideVolType_ + if (outsideVolType_ == volumeType::INSIDE) + { + outsideVolType_ = volumeType::OUTSIDE; + } + else if (outsideVolType_ == volumeType::OUTSIDE) + { + outsideVolType_ = volumeType::INSIDE; + } + } +} + + void Foam::triSurfaceMesh::findNearest ( const pointField& samples, @@ -916,6 +966,7 @@ void Foam::triSurfaceMesh::findNearest if (debug) { Pout<< "triSurfaceMesh::findNearest :" + << " surface:" << searchableSurface::name() << " trying to find nearest for " << samples.size() << " samples with max sphere " << (samples.size() ? Foam::sqrt(max(nearestDistSqr)) : Zero) @@ -942,6 +993,7 @@ void Foam::triSurfaceMesh::findNearest if (debug) { Pout<< "triSurfaceMesh::findNearest :" + << " surface:" << searchableSurface::name() << " trying to find nearest and region for " << samples.size() << " samples with max sphere " << (samples.size() ? Foam::sqrt(max(nearestDistSqr)) : Zero) @@ -973,6 +1025,7 @@ void Foam::triSurfaceMesh::findLine if (debug) { Pout<< "triSurfaceMesh::findLine :" + << " surface:" << searchableSurface::name() << " intersecting with " << start.size() << " rays" << endl; } @@ -996,6 +1049,7 @@ void Foam::triSurfaceMesh::findLineAny if (debug) { Pout<< "triSurfaceMesh::findLineAny :" + << " surface:" << searchableSurface::name() << " intersecting with " << start.size() << " rays" << endl; } @@ -1019,6 +1073,7 @@ void Foam::triSurfaceMesh::findLineAll if (debug) { Pout<< "triSurfaceMesh::findLineAll :" + << " surface:" << searchableSurface::name() << " intersecting with " << start.size() << " rays" << endl; } @@ -1041,6 +1096,7 @@ void Foam::triSurfaceMesh::getRegion if (debug) { Pout<< "triSurfaceMesh::getRegion :" + << " surface:" << searchableSurface::name() << " getting region for " << info.size() << " triangles" << endl; } @@ -1074,6 +1130,7 @@ void Foam::triSurfaceMesh::getNormal if (debug) { Pout<< "triSurfaceMesh::getNormal :" + << " surface:" << searchableSurface::name() << " getting normal for " << info.size() << " triangles" << endl; } @@ -1182,6 +1239,7 @@ void Foam::triSurfaceMesh::setField(const labelList& values) if (debug) { Pout<< "triSurfaceMesh::setField :" + << " surface:" << searchableSurface::name() << " finished setting field for " << values.size() << " triangles" << endl; } @@ -1213,6 +1271,7 @@ void Foam::triSurfaceMesh::getField if (debug) { Pout<< "triSurfaceMesh::setField :" + << " surface:" << searchableSurface::name() << " finished getting field for " << info.size() << " triangles" << endl; } @@ -1231,6 +1290,7 @@ void Foam::triSurfaceMesh::getVolumeType if (debug) { Pout<< "triSurfaceMesh::getVolumeType :" + << " surface:" << searchableSurface::name() << " finding orientation for " << points.size() << " samples" << endl; } diff --git a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H index e5a18bdeb4..c833e24d2b 100644 --- a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H +++ b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H @@ -216,6 +216,9 @@ public: return triSurface::size(); } + //- Flip triangles, outsideVolumeType and all cached inside/outside. + virtual void flip(); + //- Get representative set of element coordinates // Usually the element centres (should be of length size()). virtual tmp coordinates() const; diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C index cb8a67db5c..eae21fb06e 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.C @@ -251,4 +251,26 @@ void Foam::triSurfaceRegionSearch::findNearest } +void Foam::triSurfaceRegionSearch::flip() +{ + triSurfaceSearch::flip(); + + for (auto& tree : treeByRegion_) + { + PackedList<2>& nodeTypes = tree.nodeTypes(); + forAll(nodeTypes, i) + { + if (nodeTypes[i] == volumeType::INSIDE) + { + nodeTypes[i] = volumeType::OUTSIDE; + } + else if (nodeTypes[i] == volumeType::OUTSIDE) + { + nodeTypes[i] = volumeType::INSIDE; + } + } + } +} + + // ************************************************************************* // diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H index 724617d132..54143930eb 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceRegionSearch.H @@ -128,6 +128,11 @@ public: const labelList& regionIndices, List& info ) const; + + // Edit + + //- Flip orientation + void flip(); }; diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C index 33fa142a61..b80944a491 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C @@ -255,6 +255,26 @@ Foam::triSurfaceSearch::tree() const } +void Foam::triSurfaceSearch::flip() +{ + if (treePtr_) + { + PackedList<2>& nodeTypes = treePtr_->nodeTypes(); + forAll(nodeTypes, i) + { + if (nodeTypes[i] == volumeType::INSIDE) + { + nodeTypes[i] = volumeType::OUTSIDE; + } + else if (nodeTypes[i] == volumeType::OUTSIDE) + { + nodeTypes[i] = volumeType::INSIDE; + } + } + } +} + + // Determine inside/outside for samples Foam::boolList Foam::triSurfaceSearch::calcInside ( diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H index a4ce7c8c98..2deb9abf9e 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H @@ -126,6 +126,9 @@ public: //- Demand driven construction of the octree const indexedOctree& tree() const; + //- Flip orientation (if cached on octree) + void flip(); + //- Return reference to the surface. const triSurface& surface() const { diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C index 8c32aface9..bdb63f152e 100644 --- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C +++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C @@ -110,6 +110,7 @@ namespace Foam }; + ////- Same as above but with some more debugging //typedef Tuple2, volumeType> NearType; // ////- Combine operator for volume types @@ -337,73 +338,145 @@ Foam::word Foam::distributedTriSurfaceMesh::findLocalInstance } -// Read my additional data from the dictionary -bool Foam::distributedTriSurfaceMesh::read() +bool Foam::distributedTriSurfaceMesh::readSettings(const bool undecomposed) { // Get bb of all domains. procBb_.resize_nocopy(Pstream::nProcs()); - if (dict_.empty()) + if (!dict_.readIfPresent("bounds", procBb_[Pstream::myProcNo()])) { - // Did not find the distributed version; assume master has loaded the - // triSurfaceMesh version. Make up some settings. - + // Not found. Use local triangles' bounding box const boundBox& localBb = triSurfaceMesh::bounds(); procBb_[Pstream::myProcNo()] = treeBoundBoxList(1, treeBoundBox(localBb)); dict_.add("bounds", procBb_[Pstream::myProcNo()]); + } - // Wanted distribution type + + decomposeUsingBbs_ = dict_.getOrDefault("decomposeUsingBbs", true); + + // Wanted distribution type + if + ( + !distributionTypeNames_.readIfPresent + ( + "distributionType", + dict_, + distType_ + ) + ) + { + // Not found. Make up most sensible data distType_ = DISTRIBUTED; //INDEPENDENT; dict_.add("distributionType", distributionTypeNames_[distType_]); + } - // Merge distance + // Merge distance + if (!dict_.readIfPresent("mergeDistance", mergeDist_)) + { mergeDist_ = SMALL; dict_.add("mergeDistance", mergeDist_); - - // Force underlying triSurfaceMesh to calculate volume type - // (is topological walk; does not construct tree) - surfaceClosed_ = triSurfaceMesh::hasVolumeType(); - Pstream::broadcast(surfaceClosed_); - dict_.add("closed", surfaceClosed_); - - // Delay calculating outside vol type since constructs tree. Is ok - // after distributing since then local surfaces much smaller - //outsideVolType_ = volumeType::UNKNOWN; - //if (surfaceClosed_) - //{ - // point outsidePt(localBb.max()+localBb.centre()); - // List outsideVolTypes; - // triSurfaceMesh::getVolumeType - // ( - // pointField(1, outsidePt), - // outsideVolTypes - // ); - // outsideVolType_ = outsideVolTypes[0]; - //} - //dict_.add("outsideVolumeType", volumeType::names[outsideVolType_]); } - else + + // Is closed? + if (!dict_.readIfPresent