netgen/libsrc/interface/writegmsh2.cpp

264 lines
8.4 KiB
C++
Raw Normal View History

/*! \file writegmsh2.cpp
* \brief Export Netgen Mesh in the GMSH v2.xx File format
* \author Philippose Rajan
* \date 02 November 2008
*
* This function extends the export capabilities of
* Netgen to include the GMSH v2.xx File Format.
*
* Current features of this function include:
*
* 1. Exports Triangles, Quadrangles and Tetrahedra \n
* 2. Supports upto second order elements of each type
*
*/
#include <mystdlib.h>
#include <myadt.hpp>
#include <linalg.hpp>
#include <csg.hpp>
#include <meshing.hpp>
namespace netgen
{
#include "writeuser.hpp"
extern MeshingParameters mparam;
2014-08-30 06:15:59 +06:00
// Mapping of entities from Netgen definitions to GMSH definitions
enum GMSH_ELEMENTS {GMSH_TRIG = 2, GMSH_TRIG6 = 9,
GMSH_QUAD = 3, GMSH_QUAD8 = 16,
GMSH_TET = 4, GMSH_TET10 = 11};
const int triGmsh[7] = {0,1,2,3,6,4,5};
const int quadGmsh[9] = {0,1,2,3,4,5,8,6,7};
const int tetGmsh[11] = {0,1,2,3,4,5,8,6,7,10,9};
/*! GMSH v2.xx mesh format export function
*
* This function extends the export capabilities of
* Netgen to include the GMSH v2.xx File Format.
*
* Current features of this function include:
*
* 1. Exports Triangles, Quadrangles and Tetrahedra \n
* 2. Supports upto second order elements of each type
*
*/
void WriteGmsh2Format (const Mesh & mesh,
2014-08-30 06:15:59 +06:00
const NetgenGeometry & geom,
2022-02-17 20:52:07 +05:00
const filesystem::path & filename)
{
2022-02-17 20:52:07 +05:00
ofstream outfile (filename);
outfile.precision(6);
outfile.setf (ios::fixed, ios::floatfield);
outfile.setf (ios::showpoint);
int np = mesh.GetNP(); /// number of points in mesh
int ne = mesh.GetNE(); /// number of 3D elements in mesh
int nse = mesh.GetNSE(); /// number of surface elements (BC)
int i, j, k, l;
/*
* 3D section : Volume elements (currently only tetrahedra)
*/
if ((ne > 0)
&& (mesh.VolumeElement(1).GetNP() <= 10)
&& (mesh.SurfaceElement(1).GetNP() <= 6))
{
cout << "Write GMSH v2.xx Format \n";
cout << "The GMSH v2.xx export is currently available for elements upto 2nd Order\n" << endl;
int inverttets = mparam.inverttets;
int invertsurf = mparam.inverttrigs;
/// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation)
outfile << "$MeshFormat\n";
outfile << (float)2.0 << " "
<< (int)0 << " "
<< (int)sizeof(double) << "\n";
outfile << "$EndMeshFormat\n";
/// Write nodes
outfile << "$Nodes\n";
outfile << np << "\n";
for (i = 1; i <= np; i++)
{
const Point3d & p = mesh.Point(i);
outfile << i << " "; /// node number
outfile << p.X() << " ";
outfile << p.Y() << " ";
outfile << p.Z() << "\n";
}
outfile << "$EndNodes\n";
/// write elements (both, surface elements and volume elements)
outfile << "$Elements\n";
outfile << ne + nse << "\n"; //// number of elements + number of surfaces BC
for (i = 1; i <= nse; i++)
{
int elType = 0;
Element2d el = mesh.SurfaceElement(i);
if(invertsurf) el.Invert();
if(el.GetNP() == 3) elType = GMSH_TRIG; //// GMSH Type for a 3 node triangle
if(el.GetNP() == 6) elType = GMSH_TRIG6; //// GMSH Type for a 6 node triangle
if(elType == 0)
{
cout << " Invalid surface element type for Gmsh 2.0 3D-Mesh Export Format !\n";
return;
}
outfile << i;
outfile << " ";
outfile << elType;
outfile << " ";
outfile << "2"; //// Number of tags (2 => Physical and elementary entities)
outfile << " ";
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
/// that means that physical entity = elementary entity (arbitrary approach)
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
for (j = 1; j <= el.GetNP(); j++)
{
outfile << " ";
outfile << el.PNum(triGmsh[j]);
}
outfile << "\n";
}
for (i = 1; i <= ne; i++)
{
int elType = 0;
Element el = mesh.VolumeElement(i);
if (inverttets) el.Invert();
if(el.GetNP() == 4) elType = GMSH_TET; //// GMSH Element type for 4 node tetrahedron
if(el.GetNP() == 10) elType = GMSH_TET10; //// GMSH Element type for 10 node tetrahedron
if(elType == 0)
{
cout << " Invalid volume element type for Gmsh 2.0 3D-Mesh Export Format !\n";
return;
}
outfile << nse + i; //// element number (Remember to add on surface elements)
outfile << " ";
outfile << elType;
outfile << " ";
outfile << "2"; //// Number of tags (2 => Physical and elementary entities)
outfile << " ";
outfile << 100000 + el.GetIndex();
/// that means that physical entity = elementary entity (arbitrary approach)
outfile << " ";
outfile << 100000 + el.GetIndex(); /// volume number
outfile << " ";
for (j = 1; j <= el.GetNP(); j++)
{
outfile << " ";
outfile << el.PNum(tetGmsh[j]);
}
outfile << "\n";
}
outfile << "$EndElements\n";
}
/*
* End of 3D section
*/
/*
* 2D section : available for triangles and quadrangles
* upto 2nd Order
*/
else if(ne == 0) /// means that there's no 3D element
{
cout << "\n Write Gmsh v2.xx Surface Mesh (triangle and/or quadrangles upto 2nd Order)" << endl;
/// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation)
outfile << "$MeshFormat\n";
outfile << (float)2.0 << " "
<< (int)0 << " "
<< (int)sizeof(double) << "\n";
outfile << "$EndMeshFormat\n";
/// Write nodes
outfile << "$Nodes\n";
outfile << np << "\n";
for (i = 1; i <= np; i++)
{
const Point3d & p = mesh.Point(i);
outfile << i << " "; /// node number
outfile << p.X() << " ";
outfile << p.Y() << " ";
outfile << p.Z() << "\n";
}
outfile << "$EndNodes\n";
/// write triangles & quadrangles
outfile << "$Elements\n";
outfile << nse << "\n";
for (k = 1; k <= nse; k++)
{
int elType = 0;
const Element2d & el = mesh.SurfaceElement(k);
if(el.GetNP() == 3) elType = GMSH_TRIG; //// GMSH Type for a 3 node triangle
if(el.GetNP() == 6) elType = GMSH_TRIG6; //// GMSH Type for a 6 node triangle
if(el.GetNP() == 4) elType = GMSH_QUAD; //// GMSH Type for a 4 node quadrangle
if(el.GetNP() == 8) elType = GMSH_QUAD8; //// GMSH Type for an 8 node quadrangle
if(elType == 0)
{
cout << " Invalid surface element type for Gmsh 2.0 2D-Mesh Export Format !\n";
return;
}
outfile << k;
outfile << " ";
outfile << elType;
outfile << " ";
outfile << "2";
outfile << " ";
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
/// that means that physical entity = elementary entity (arbitrary approach)
outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
for (l = 1; l <= el.GetNP(); l++)
{
outfile << " ";
if((elType == GMSH_TRIG) || (elType == GMSH_TRIG6))
{
outfile << el.PNum(triGmsh[l]);
}
else if((elType == GMSH_QUAD) || (elType == GMSH_QUAD8))
{
outfile << el.PNum(quadGmsh[l]);
}
}
outfile << "\n";
}
outfile << "$EndElements\n";
}
/*
* End of 2D section
*/
else
{
cout << " Invalid element type for Gmsh v2.xx Export Format !\n";
}
} // End: WriteGmsh2Format
} // End: namespace netgen