/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2019-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. 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. 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 along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "polyMeshAdder.H" #include "mapAddedPolyMesh.H" #include "IOobject.H" #include "faceCoupleInfo.H" #include "processorPolyPatch.H" #include "SortableList.H" #include "Time.H" #include "globalMeshData.H" #include "mergePoints.H" #include "polyModifyFace.H" #include "polyRemovePoint.H" #include "polyTopoChange.H" #include "globalIndex.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Get index of patch in new set of patchnames/types Foam::label Foam::polyMeshAdder::patchIndex ( const polyPatch& p, DynamicList& allPatchNames, DynamicList& allPatchTypes ) { // Find the patch name on the list. If the patch is already there // and patch types match, return index const word& pType = p.type(); const word& pName = p.name(); label patchi = allPatchNames.find(pName); if (patchi < 0) { // Not found - add to the lists patchi = allPatchNames.size(); allPatchNames.push_back(pName); allPatchTypes.push_back(pType); } else if (allPatchTypes[patchi] != pType) { // Found the name, but type is different patchi = allPatchNames.size(); // Duplicate name is not allowed. Create a composite name from the // patch name and case name const word& caseName = p.boundaryMesh().mesh().time().caseName(); allPatchNames.push_back(pName + "_" + caseName); allPatchTypes.push_back(pType); Pout<< "label patchIndex(const polyPatch& p) : " << "Patch " << p.index() << " named " << pName << " in mesh " << caseName << " already exists, but patch types" << " do not match.\nCreating a composite name as " << allPatchNames.back() << endl; } return patchi; } // Get index of zone in new set of zone names Foam::label Foam::polyMeshAdder::zoneIndex ( const word& curName, DynamicList& names ) { label zonei = names.find(curName); if (zonei < 0) { // Not found - add to the list zonei = names.size(); names.push_back(curName); } return zonei; } void Foam::polyMeshAdder::mergePatchNames ( const polyBoundaryMesh& patches0, const polyBoundaryMesh& patches1, DynamicList& allPatchNames, DynamicList& allPatchTypes, labelList& from1ToAllPatches, labelList& fromAllTo1Patches ) { // Insert the mesh0 patches and zones allPatchNames.push_back(patches0.names()); allPatchTypes.push_back(patches0.types()); // Patches // ~~~~~~~ // Patches from 0 are taken over as is; those from 1 get either merged // (if they share name and type) or appended. // Empty patches are filtered out much much later on. // Add mesh1 patches and build map both ways. from1ToAllPatches.setSize(patches1.size()); forAll(patches1, patchi) { from1ToAllPatches[patchi] = patchIndex ( patches1[patchi], allPatchNames, allPatchTypes ); } allPatchTypes.shrink(); allPatchNames.shrink(); // Invert 1 to all patch map fromAllTo1Patches.setSize(allPatchNames.size()); fromAllTo1Patches = -1; forAll(from1ToAllPatches, i) { fromAllTo1Patches[from1ToAllPatches[i]] = i; } } Foam::List Foam::polyMeshAdder::combinePatches ( const polyMesh& mesh0, const polyMesh& mesh1, const polyBoundaryMesh& allBoundaryMesh, const label nAllPatches, const labelList& fromAllTo1Patches, const label nInternalFaces, const labelList& nFaces, labelList& from0ToAllPatches, labelList& from1ToAllPatches ) { const polyBoundaryMesh& patches0 = mesh0.boundaryMesh(); const polyBoundaryMesh& patches1 = mesh1.boundaryMesh(); // Compacted new patch list. DynamicList allPatches(nAllPatches); // Map from 0 to all patches (since gets compacted) from0ToAllPatches.setSize(patches0.size()); from0ToAllPatches = -1; label startFacei = nInternalFaces; // Copy patches0 with new sizes. First patches always come from // mesh0 and will always be present. forAll(patches0, patchi) { // Originates from mesh0. Clone with new size & filter out empty // patch. label filteredPatchi; if (nFaces[patchi] == 0 && isA(patches0[patchi])) { //Pout<< "Removing zero sized mesh0 patch " // << patches0[patchi].name() << endl; filteredPatchi = -1; } else { filteredPatchi = allPatches.size(); allPatches.append ( patches0[patchi].clone ( allBoundaryMesh, filteredPatchi, nFaces[patchi], startFacei ).ptr() ); startFacei += nFaces[patchi]; } // Record new index in allPatches from0ToAllPatches[patchi] = filteredPatchi; // Check if patch was also in mesh1 and update its addressing if so. if (fromAllTo1Patches[patchi] != -1) { from1ToAllPatches[fromAllTo1Patches[patchi]] = filteredPatchi; } } // Copy unique patches of mesh1. forAll(from1ToAllPatches, patchi) { label allPatchi = from1ToAllPatches[patchi]; if (allPatchi >= patches0.size()) { // Patch has not been merged with any mesh0 patch. label filteredPatchi; if ( nFaces[allPatchi] == 0 && isA(patches1[patchi]) ) { //Pout<< "Removing zero sized mesh1 patch " // << patches1[patchi].name() << endl; filteredPatchi = -1; } else { filteredPatchi = allPatches.size(); allPatches.append ( patches1[patchi].clone ( allBoundaryMesh, filteredPatchi, nFaces[allPatchi], startFacei ).ptr() ); startFacei += nFaces[allPatchi]; } from1ToAllPatches[patchi] = filteredPatchi; } } allPatches.shrink(); return allPatches; } Foam::labelList Foam::polyMeshAdder::getFaceOrder ( const cellList& cells, const label nInternalFaces, const labelList& owner, const labelList& neighbour ) { labelList oldToNew(owner.size(), -1); // Leave boundary faces in order for (label facei = nInternalFaces; facei < owner.size(); ++facei) { oldToNew[facei] = facei; } // First unassigned face label newFacei = 0; forAll(cells, celli) { const labelList& cFaces = cells[celli]; SortableList