/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
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 "foamTime.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