/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- 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 . Description Collapse short edges and combines edges that are in line. - collapse short edges. Length of edges to collapse provided as argument. - merge two edges if they are in line. Maximum angle provided as argument. - remove unused points. Cannot remove cells. Can remove faces and points but does not check for nonsense resulting topology. When collapsing an edge with one point on the boundary it will leave the boundary point intact. When both points inside it chooses random. When both points on boundary random again. Note: it should in fact use features where if one point is on a feature it collapses to that one. Alas we don't have features on a polyMesh. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "polyTopoChange.H" #include "polyTopoChanger.H" #include "polyMesh.H" #include "fvMesh.H" #include "mapPolyMesh.H" #include "mathematicalConstants.H" #include "PackedBoolList.H" #include "SortableList.H" #include "unitConversion.H" #include "globalMeshData.H" #include "globalIndex.H" #include "PointEdgeWave.H" #include "pointEdgeCollapse.H" #include "motionSmoother.H" #include "OFstream.H" #include "meshTools.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // label findIndex ( const labelList& elems, const label start, const label size, const label val ) { for (label i = start; i < size; i++) { if (elems[i] == val) { return i; } } return -1; } void filterFace ( const label faceI, face& f, const List& allPointInfo, const Map >& collapseStrings ) { label newFp = 0; face oldFace = f; forAll(f, fp) { label pointI = f[fp]; label collapsePoint = allPointInfo[pointI].collapseIndex(); if (collapseStrings.found(collapsePoint)) { collapsePoint = collapseStrings[collapsePoint][0]; } if (collapsePoint == -1) { WarningIn ( "filterFace" "(const label, face&, const List&)" ) << "Point " << pointI << " was not visited by PointEdgeWave" << endl; } else if (collapsePoint == -2) { f[newFp++] = pointI; } else { if (findIndex(f, 0, newFp, collapsePoint) == -1) { f[newFp++] = collapsePoint; } } } // Check for pinched face. Tries to correct // - consecutive duplicate vertex. Removes duplicate vertex. // - duplicate vertex with one other vertex in between (spike). // Both of these should not really occur! and should be checked before // collapsing edges. const label size = newFp; newFp = 2; for (label fp = 2; fp < size; fp++) { label fp1 = fp-1; label fp2 = fp-2; label pointI = f[fp]; // Search for previous occurrence. label index = findIndex(f, 0, fp, pointI); if (index == fp1) { WarningIn ( "Foam::edgeCollapser::filterFace(const label faceI, " "face& f) const" ) << "Removing consecutive duplicate vertex in face " << f << endl; // Don't store current pointI } else if (index == fp2) { WarningIn ( "Foam::edgeCollapser::filterFace(const label faceI, " "face& f) const" ) << "Removing non-consecutive duplicate vertex in face " << f << endl; // Don't store current pointI and remove previous newFp--; } else if (index != -1) { WarningIn ( "Foam::edgeCollapser::filterFace(const label faceI, " "face& f) const" ) << "Pinched face " << f << endl; f[newFp++] = pointI; } else { f[newFp++] = pointI; } } f.setSize(newFp); } bool setRefinement ( const polyMesh& mesh, polyTopoChange& meshMod, const List& allPointInfo ) { const cellList& cells = mesh.cells(); const labelList& faceOwner = mesh.faceOwner(); const labelList& faceNeighbour = mesh.faceNeighbour(); const labelListList& pointFaces = mesh.pointFaces(); const pointZoneMesh& pointZones = mesh.pointZones(); globalIndex globalStrings(mesh.nPoints()); boolList removedPoints(mesh.nPoints(), false); // Create strings of edges Map > collapseStrings; forAll(allPointInfo, pointI) { const label collapseIndex = allPointInfo[pointI].collapseIndex(); if (collapseIndex != -1 && collapseIndex != -2) { collapseStrings(collapseIndex).append(pointI); } } bool meshChanged = false; // Current faces (is also collapseStatus: f.size() < 3) faceList newFaces(mesh.faces()); // Current cellCollapse status boolList cellRemoved(mesh.nCells(), false); label nUnvisited = 0; label nUncollapsed = 0; label nCollapsed = 0; forAll(allPointInfo, pI) { const pointEdgeCollapse& pec = allPointInfo[pI]; if (pec.collapseIndex() == -1) { nUnvisited++; } else if (pec.collapseIndex() == -2) { nUncollapsed++; } else if (pec.collapseIndex() >= 0) { nCollapsed++; } } label nPoints = allPointInfo.size(); reduce(nPoints, sumOp