/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | foam-extend: Open Source CFD \\ / O peration | \\ / A nd | For copyright notice see file Copyright \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of foam-extend. foam-extend 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. foam-extend 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 foam-extend. If not, see . Description Utility to split cells with flat faces. Uses a geometric cut with a plane dividing the edge angle into two so might produce funny cells. For hexes it will use by default a cut from edge onto opposite edge (i.e. purely topological). Options: - split cells from cellSet only - use geometric cut for hexes as well The angle is the angle between two faces sharing an edge as seen from inside each cell. So a cube will have all angles 90. If you want to split cells with cell centre outside use e.g. angle 200 \*---------------------------------------------------------------------------*/ #include "argList.H" #include "objectRegistry.H" #include "Time.H" #include "directTopoChange.H" #include "mapPolyMesh.H" #include "polyMesh.H" #include "cellCuts.H" #include "cellSet.H" #include "cellModeller.H" #include "meshCutter.H" #include "mathematicalConstants.H" #include "geomCellLooper.H" #include "plane.H" #include "edgeVertex.H" #include "meshTools.H" #include "ListOps.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // labelList pack(const boolList& lst) { labelList packedLst(lst.size()); label packedI = 0; forAll(lst, i) { if (lst[i]) { packedLst[packedI++] = i; } } packedLst.setSize(packedI); return packedLst; } scalarField pack(const boolList& lst, const scalarField& elems) { scalarField packedElems(lst.size()); label packedI = 0; forAll(lst, i) { if (lst[i]) { packedElems[packedI++] = elems[i]; } } packedElems.setSize(packedI); return packedElems; } // Given sin and cos of max angle between normals calculate whether f0 and f1 // on cellI make larger angle. Uses sinAngle only for quadrant detection. bool largerAngle ( const primitiveMesh& mesh, const scalar cosAngle, const scalar sinAngle, const label cellI, const label f0, // face label const label f1, const vector& n0, // normal at f0 const vector& n1 ) { const labelList& own = mesh.faceOwner(); bool sameFaceOrder = !((own[f0] == cellI) ^ (own[f1] == cellI)); // Get cos between faceArea vectors. Correct so flat angle (180 degrees) // gives -1. scalar normalCosAngle = n0 & n1; if (sameFaceOrder) { normalCosAngle = -normalCosAngle; } // Get cos between faceCentre and normal vector to determine in // which quadrant angle is. (Is correct for unwarped faces only!) // Correct for non-outwards pointing normal. vector c1c0(mesh.faceCentres()[f1] - mesh.faceCentres()[f0]); c1c0 /= mag(c1c0) + VSMALL; scalar fcCosAngle = n0 & c1c0; if (own[f0] != cellI) { fcCosAngle = -fcCosAngle; } if (sinAngle < 0.0) { // Looking for concave angles (quadrant 3 or 4) if (fcCosAngle <= 0) { // Angle is convex so smaller. return false; } else { if (normalCosAngle < cosAngle) { return false; } else { return true; } } } else { // Looking for convex angles (quadrant 1 or 2) if (fcCosAngle > 0) { // Concave angle return true; } else { // Convex. Check cos of normal vectors. if (normalCosAngle > cosAngle) { return false; } else { return true; } } } } // Split hex (and hex only) along edgeI creating two prisms bool splitHex ( const polyMesh& mesh, const label cellI, const label edgeI, DynamicList