2013-12-11 09:25:19 +00:00
|
|
|
/*---------------------------------------------------------------------------*\
|
|
|
|
========= |
|
2013-12-11 16:09:41 +00:00
|
|
|
\\ / F ield | foam-extend: Open Source CFD
|
2015-05-17 13:32:07 +00:00
|
|
|
\\ / O peration | Version: 3.2
|
|
|
|
\\ / A nd | Web: http://www.foam-extend.org
|
|
|
|
\\/ M anipulation | For copyright notice see file Copyright
|
2013-12-11 09:25:19 +00:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
License
|
2013-12-11 16:09:41 +00:00
|
|
|
This file is part of foam-extend.
|
2013-12-11 09:25:19 +00:00
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
foam-extend is free software: you can redistribute it and/or modify it
|
2013-12-11 09:25:19 +00:00
|
|
|
under the terms of the GNU General Public License as published by the
|
2013-12-11 16:09:41 +00:00
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
2013-12-11 09:25:19 +00:00
|
|
|
option) any later version.
|
|
|
|
|
2013-12-11 16:09:41 +00:00
|
|
|
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.
|
2013-12-11 09:25:19 +00:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2013-12-11 16:09:41 +00:00
|
|
|
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
|
2013-12-11 09:25:19 +00:00
|
|
|
|
|
|
|
Description
|
|
|
|
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "vtkPV4Foam.H"
|
|
|
|
|
|
|
|
// Foam includes
|
|
|
|
#include "fvMesh.H"
|
|
|
|
#include "cellModeller.H"
|
|
|
|
#include "vtkPV4FoamPoints.H"
|
|
|
|
|
|
|
|
// VTK includes
|
|
|
|
#include "vtkCellArray.h"
|
|
|
|
#include "vtkUnstructuredGrid.h"
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
vtkUnstructuredGrid* Foam::vtkPV4Foam::volumeVTKMesh
|
|
|
|
(
|
|
|
|
const fvMesh& mesh,
|
|
|
|
polyDecomp& decompInfo
|
|
|
|
)
|
|
|
|
{
|
|
|
|
vtkUnstructuredGrid* vtkmesh = vtkUnstructuredGrid::New();
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "<beg> Foam::vtkPV4Foam::volumeVTKMesh" << endl;
|
|
|
|
printMemory();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Number of additional points needed by the decomposition of polyhedra
|
|
|
|
label nAddPoints = 0;
|
|
|
|
|
|
|
|
// Number of additional cells generated by the decomposition of polyhedra
|
|
|
|
label nAddCells = 0;
|
|
|
|
|
|
|
|
labelList& superCells = decompInfo.superCells();
|
|
|
|
labelList& addPointCellLabels = decompInfo.addPointCellLabels();
|
|
|
|
|
|
|
|
const cellModel& tet = *(cellModeller::lookup("tet"));
|
|
|
|
const cellModel& pyr = *(cellModeller::lookup("pyr"));
|
|
|
|
const cellModel& prism = *(cellModeller::lookup("prism"));
|
|
|
|
const cellModel& wedge = *(cellModeller::lookup("wedge"));
|
|
|
|
const cellModel& tetWedge = *(cellModeller::lookup("tetWedge"));
|
|
|
|
const cellModel& hex = *(cellModeller::lookup("hex"));
|
|
|
|
|
|
|
|
// Scan for cells which need to be decomposed and count additional points
|
|
|
|
// and cells
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "... building cell-shapes" << endl;
|
|
|
|
}
|
|
|
|
const cellShapeList& cellShapes = mesh.cellShapes();
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "... scanning" << endl;
|
|
|
|
}
|
|
|
|
forAll(cellShapes, cellI)
|
|
|
|
{
|
|
|
|
const cellModel& model = cellShapes[cellI].model();
|
|
|
|
|
|
|
|
if
|
|
|
|
(
|
|
|
|
model != hex
|
|
|
|
&& model != wedge
|
|
|
|
&& model != prism
|
|
|
|
&& model != pyr
|
|
|
|
&& model != tet
|
|
|
|
&& model != tetWedge
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const cell& cFaces = mesh.cells()[cellI];
|
|
|
|
|
|
|
|
forAll(cFaces, cFaceI)
|
|
|
|
{
|
|
|
|
const face& f = mesh.faces()[cFaces[cFaceI]];
|
|
|
|
|
|
|
|
label nFacePoints = f.size();
|
|
|
|
|
|
|
|
label nQuads = (nFacePoints - 2)/2;
|
|
|
|
label nTris = (nFacePoints - 2)%2;
|
|
|
|
nAddCells += nQuads + nTris;
|
|
|
|
}
|
|
|
|
|
|
|
|
nAddCells--;
|
|
|
|
nAddPoints++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set size of additional point addressing array
|
|
|
|
// (from added point to original cell)
|
|
|
|
addPointCellLabels.setSize(nAddPoints);
|
|
|
|
|
|
|
|
// Set size of additional cells mapping array
|
|
|
|
// (from added cell to original cell)
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<<" mesh nCells = " << mesh.nCells() << nl
|
|
|
|
<<" nPoints = " << mesh.nPoints() << nl
|
|
|
|
<<" nAddCells = " << nAddCells << nl
|
|
|
|
<<" nAddPoints = " << nAddPoints << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
superCells.setSize(mesh.nCells() + nAddCells);
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "... converting points" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert Foam mesh vertices to VTK
|
|
|
|
vtkPoints *vtkpoints = vtkPoints::New();
|
|
|
|
vtkpoints->Allocate( mesh.nPoints() + nAddPoints );
|
|
|
|
|
|
|
|
const Foam::pointField& points = mesh.points();
|
|
|
|
|
|
|
|
forAll(points, i)
|
|
|
|
{
|
|
|
|
vtkPV4FoamInsertNextPoint(vtkpoints, points[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "... converting cells" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkmesh->Allocate( mesh.nCells() + nAddCells );
|
|
|
|
|
|
|
|
// Set counters for additional points and additional cells
|
|
|
|
label addPointI = 0, addCellI = 0;
|
|
|
|
|
|
|
|
// Create storage for points - needed for mapping from Foam to VTK
|
|
|
|
// data types - max 'order' = hex = 8 points
|
|
|
|
vtkIdType nodeIds[8];
|
|
|
|
|
|
|
|
forAll(cellShapes, cellI)
|
|
|
|
{
|
|
|
|
const cellShape& cellShape = cellShapes[cellI];
|
|
|
|
const cellModel& cellModel = cellShape.model();
|
|
|
|
|
|
|
|
superCells[addCellI++] = cellI;
|
|
|
|
|
|
|
|
if (cellModel == tet)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
|
{
|
|
|
|
nodeIds[j] = cellShape[j];
|
|
|
|
}
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_TETRA,
|
|
|
|
4,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (cellModel == pyr)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 5; j++)
|
|
|
|
{
|
|
|
|
nodeIds[j] = cellShape[j];
|
|
|
|
}
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_PYRAMID,
|
|
|
|
5,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (cellModel == prism)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 6; j++)
|
|
|
|
{
|
|
|
|
nodeIds[j] = cellShape[j];
|
|
|
|
}
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_WEDGE,
|
|
|
|
6,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (cellModel == tetWedge)
|
|
|
|
{
|
|
|
|
// Treat as squeezed prism
|
|
|
|
|
|
|
|
nodeIds[0] = cellShape[0];
|
|
|
|
nodeIds[1] = cellShape[2];
|
|
|
|
nodeIds[2] = cellShape[1];
|
|
|
|
nodeIds[3] = cellShape[3];
|
|
|
|
nodeIds[4] = cellShape[4];
|
|
|
|
nodeIds[5] = cellShape[4];
|
|
|
|
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_WEDGE,
|
|
|
|
6,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (cellModel == wedge)
|
|
|
|
{
|
|
|
|
// Treat as squeezed hex
|
|
|
|
|
|
|
|
nodeIds[0] = cellShape[0];
|
|
|
|
nodeIds[1] = cellShape[1];
|
|
|
|
nodeIds[2] = cellShape[2];
|
|
|
|
nodeIds[3] = cellShape[2];
|
|
|
|
nodeIds[4] = cellShape[3];
|
|
|
|
nodeIds[5] = cellShape[4];
|
|
|
|
nodeIds[6] = cellShape[5];
|
|
|
|
nodeIds[7] = cellShape[6];
|
|
|
|
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_HEXAHEDRON,
|
|
|
|
8,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (cellModel == hex)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 8; j++)
|
|
|
|
{
|
|
|
|
nodeIds[j] = cellShape[j];
|
|
|
|
}
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_HEXAHEDRON,
|
|
|
|
8,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Polyhedral cell. Decompose into tets + prisms.
|
|
|
|
|
|
|
|
// Mapping from additional point to cell
|
|
|
|
addPointCellLabels[addPointI] = cellI;
|
|
|
|
|
|
|
|
// Insert the new vertex from the cell-centre
|
|
|
|
label newVertexLabel = mesh.nPoints() + addPointI;
|
|
|
|
vtkPV4FoamInsertNextPoint(vtkpoints, mesh.C()[cellI]);
|
|
|
|
|
|
|
|
// Whether to insert cell in place of original or not.
|
|
|
|
bool substituteCell = true;
|
|
|
|
|
|
|
|
const labelList& cFaces = mesh.cells()[cellI];
|
|
|
|
|
|
|
|
forAll(cFaces, cFaceI)
|
|
|
|
{
|
|
|
|
const face& f = mesh.faces()[cFaces[cFaceI]];
|
|
|
|
|
|
|
|
label nFacePoints = f.size();
|
|
|
|
|
|
|
|
label nQuads = (nFacePoints - 2)/2;
|
|
|
|
label nTris = (nFacePoints - 2)%2;
|
|
|
|
|
|
|
|
label qpi = 0;
|
|
|
|
|
|
|
|
for (label quadi=0; quadi<nQuads; quadi++)
|
|
|
|
{
|
|
|
|
if (substituteCell)
|
|
|
|
{
|
|
|
|
substituteCell = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
superCells[addCellI++] = cellI;
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeIds[0] = f[0];
|
|
|
|
nodeIds[1] = f[qpi + 1];
|
|
|
|
nodeIds[2] = f[qpi + 2];
|
|
|
|
nodeIds[3] = f[qpi + 3];
|
|
|
|
nodeIds[4] = newVertexLabel;
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_PYRAMID,
|
|
|
|
5,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
|
|
|
|
qpi += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nTris)
|
|
|
|
{
|
|
|
|
if (substituteCell)
|
|
|
|
{
|
|
|
|
substituteCell = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
superCells[addCellI++] = cellI;
|
|
|
|
}
|
|
|
|
|
|
|
|
nodeIds[0] = f[0];
|
|
|
|
nodeIds[1] = f[qpi + 1];
|
|
|
|
nodeIds[2] = f[qpi + 2];
|
|
|
|
nodeIds[3] = newVertexLabel;
|
|
|
|
vtkmesh->InsertNextCell
|
|
|
|
(
|
|
|
|
VTK_TETRA,
|
|
|
|
4,
|
|
|
|
nodeIds
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addPointI++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkmesh->SetPoints(vtkpoints);
|
|
|
|
vtkpoints->Delete();
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "<end> Foam::vtkPV4Foam::volumeVTKMesh" << endl;
|
|
|
|
printMemory();
|
|
|
|
}
|
|
|
|
|
|
|
|
return vtkmesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ************************************************************************* //
|