mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-14 10:08:32 +05:00
323 lines
7.7 KiB
C++
323 lines
7.7 KiB
C++
// Write Chemnitz file format
|
|
|
|
|
|
#include <mystdlib.h>
|
|
|
|
#include <myadt.hpp>
|
|
|
|
#include <linalg.hpp>
|
|
#include <csg.hpp>
|
|
#include <meshing.hpp>
|
|
|
|
#include "writeuser.hpp"
|
|
|
|
namespace netgen
|
|
{
|
|
|
|
class POINT3D
|
|
{
|
|
public:
|
|
POINT3D () { };
|
|
double x, y, z;
|
|
};
|
|
|
|
class VOLELEMENT
|
|
{
|
|
public:
|
|
int domnr, p1, p2, p3, p4;
|
|
int faces[4];
|
|
|
|
VOLELEMENT ()
|
|
{ for (int i = 0; i < 4; i++) faces[i] = 0; }
|
|
};
|
|
|
|
class SURFELEMENT
|
|
{
|
|
public:
|
|
SURFELEMENT () { };
|
|
int snr, p1, p2, p3;
|
|
};
|
|
|
|
|
|
class FACE
|
|
{
|
|
public:
|
|
int p1, p2, p3;
|
|
int edges[3];
|
|
|
|
FACE ()
|
|
{ for (int i = 0; i < 3; i++) edges[i] = 0; }
|
|
};
|
|
|
|
class EDGE
|
|
{
|
|
public:
|
|
EDGE () { };
|
|
int p1, p2;
|
|
};
|
|
|
|
static NgArray<POINT3D> points;
|
|
static NgArray<VOLELEMENT> volelements;
|
|
static NgArray<SURFELEMENT> surfelements;
|
|
|
|
static NgArray<FACE> faces;
|
|
static NgArray<EDGE> edges;
|
|
|
|
|
|
void ReadFile (char * filename)
|
|
{
|
|
int i, n;
|
|
ifstream infile(filename);
|
|
char reco[100];
|
|
|
|
|
|
infile >> reco; // file format recognition
|
|
|
|
infile >> n; // number of surface elements
|
|
cout << n << " Surface elements" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
SURFELEMENT sel;
|
|
infile >> sel.snr >> sel.p1 >> sel.p2 >> sel.p3;
|
|
surfelements.Append (sel);
|
|
}
|
|
|
|
infile >> n; // number of volume elements
|
|
cout << n << " Volume elements" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
VOLELEMENT el;
|
|
infile >> el.p1 >> el.p2 >> el.p3 >> el.p4;
|
|
volelements.Append (el);
|
|
}
|
|
|
|
infile >> n; // number of points
|
|
cout << n << " Points" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
POINT3D p;
|
|
infile >> p.x >> p.y >> p.z;
|
|
points.Append (p);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ReadFileMesh (const Mesh & mesh)
|
|
{
|
|
int i, n;
|
|
|
|
n = mesh.GetNSE(); // number of surface elements
|
|
cout << n << " Surface elements" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
SURFELEMENT sel;
|
|
const Element2d & el = mesh.SurfaceElement(i);
|
|
sel.snr = el.GetIndex();
|
|
sel.p1 = el.PNum(1);
|
|
sel.p2 = el.PNum(2);
|
|
sel.p3 = el.PNum(3);
|
|
surfelements.Append (sel);
|
|
}
|
|
|
|
n = mesh.GetNE(); // number of volume elements
|
|
cout << n << " Volume elements" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
VOLELEMENT el;
|
|
const Element & nel = mesh.VolumeElement(i);
|
|
el.p1 = nel.PNum(1);
|
|
el.p2 = nel.PNum(2);
|
|
el.p3 = nel.PNum(3);
|
|
el.p4 = nel.PNum(4);
|
|
// infile >> el.p1 >> el.p2 >> el.p3 >> el.p4;
|
|
volelements.Append (el);
|
|
}
|
|
|
|
n = mesh.GetNP(); // number of points
|
|
cout << n << " Points" << endl;
|
|
|
|
for (i = 1; i <= n; i++)
|
|
{
|
|
POINT3D p;
|
|
Point3d mp = mesh.Point(i);
|
|
p.x = mp.X();
|
|
p.y = mp.Y();
|
|
p.z = mp.Z();
|
|
// infile >> p.x >> p.y >> p.z;
|
|
points.Append (p);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Convert ()
|
|
{
|
|
int i, j, facei, edgei;
|
|
INDEX_3 i3;
|
|
INDEX_2 i2;
|
|
|
|
INDEX_3_HASHTABLE<int> faceindex(volelements.Size()/5 + 1);
|
|
INDEX_2_HASHTABLE<int> edgeindex(volelements.Size()/5 + 1);
|
|
|
|
for (i = 1; i <= volelements.Size(); i++)
|
|
{
|
|
for (j = 1; j <= 4; j++)
|
|
{
|
|
switch (j)
|
|
{
|
|
case 1:
|
|
i3.I1() = volelements.Get(i).p2;
|
|
i3.I2() = volelements.Get(i).p3;
|
|
i3.I3() = volelements.Get(i).p4;
|
|
break;
|
|
case 2:
|
|
i3.I1() = volelements.Get(i).p1;
|
|
i3.I2() = volelements.Get(i).p3;
|
|
i3.I3() = volelements.Get(i).p4;
|
|
break;
|
|
case 3:
|
|
i3.I1() = volelements.Get(i).p1;
|
|
i3.I2() = volelements.Get(i).p2;
|
|
i3.I3() = volelements.Get(i).p4;
|
|
break;
|
|
case 4:
|
|
i3.I1() = volelements.Get(i).p1;
|
|
i3.I2() = volelements.Get(i).p2;
|
|
i3.I3() = volelements.Get(i).p3;
|
|
break;
|
|
default:
|
|
i3.I1()=i3.I2()=i3.I3()=0;
|
|
}
|
|
i3.Sort();
|
|
if (faceindex.Used (i3))
|
|
facei = faceindex.Get(i3);
|
|
else
|
|
{
|
|
FACE fa;
|
|
fa.p1 = i3.I1();
|
|
fa.p2 = i3.I2();
|
|
fa.p3 = i3.I3();
|
|
faces.Append (fa);
|
|
facei = faces.Size();
|
|
faceindex.Set (i3, facei);
|
|
}
|
|
|
|
volelements.Elem(i).faces[j-1] = facei;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
for (i = 1; i <= faces.Size(); i++)
|
|
{
|
|
for (j = 1; j <= 3; j++)
|
|
{
|
|
switch (j)
|
|
{
|
|
case 1:
|
|
i2.I1() = faces.Get(i).p2;
|
|
i2.I2() = faces.Get(i).p3;
|
|
break;
|
|
case 2:
|
|
i2.I1() = faces.Get(i).p1;
|
|
i2.I2() = faces.Get(i).p3;
|
|
break;
|
|
case 3:
|
|
i2.I1() = faces.Get(i).p1;
|
|
i2.I2() = faces.Get(i).p2;
|
|
break;
|
|
default:
|
|
i2.I1()=i2.I2()=0;
|
|
}
|
|
if (i2.I1() > i2.I2()) swap (i2.I1(), i2.I2());
|
|
if (edgeindex.Used (i2))
|
|
edgei = edgeindex.Get(i2);
|
|
else
|
|
{
|
|
EDGE ed;
|
|
ed.p1 = i2.I1();
|
|
ed.p2 = i2.I2();
|
|
edges.Append (ed);
|
|
edgei = edges.Size();
|
|
edgeindex.Set (i2, edgei);
|
|
}
|
|
|
|
faces.Elem(i).edges[j-1] = edgei;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void WriteFile (ostream & outfile)
|
|
{
|
|
int i;
|
|
|
|
outfile
|
|
<< "#VERSION: 1.0" << endl
|
|
<< "#PROGRAM: NETGEN" << endl
|
|
<< "#EQN_TYPE: POISSON" << endl
|
|
<< "#DIMENSION: 3D" << endl
|
|
<< "#DEG_OF_FREE: 1" << endl
|
|
<< "#DESCRIPTION: I don't know" << endl
|
|
<< "##RENUM: not done" << endl
|
|
<< "#USER: Kleinzen" << endl
|
|
<< "DATE: 10.06.1996" << endl;
|
|
|
|
outfile << "#HEADER: 8" << endl
|
|
<< points.Size() << " " << edges.Size() << " "
|
|
<< faces.Size() << " " << volelements.Size() << " 0 0 0 0" << endl;
|
|
|
|
outfile << "#VERTEX: " << points.Size() << endl;
|
|
for (i = 1; i <= points.Size(); i++)
|
|
outfile << " " << i << " " << points.Get(i).x << " " << points.Get(i).y
|
|
<< " " << points.Get(i).z << endl;
|
|
|
|
outfile << "#EDGE: " << edges.Size() << endl;
|
|
for (i = 1; i <= edges.Size(); i++)
|
|
outfile << " " << i << " 1 "
|
|
<< edges.Get(i).p1 << " "
|
|
<< edges.Get(i).p2
|
|
<< " 0" << endl;
|
|
|
|
outfile << "#FACE: " << faces.Size() << endl;
|
|
for (i = 1; i <= faces.Size(); i++)
|
|
outfile << " " << i << " 1 3 "
|
|
<< faces.Get(i).edges[0] << " "
|
|
<< faces.Get(i).edges[1] << " "
|
|
<< faces.Get(i).edges[2] << endl;
|
|
|
|
outfile << "#SOLID: " << volelements.Size() << endl;
|
|
for (i = 1; i <= volelements.Size(); i++)
|
|
outfile << " " << i << " 1 4 "
|
|
<< volelements.Get(i).faces[0] << " "
|
|
<< volelements.Get(i).faces[1] << " "
|
|
<< volelements.Get(i).faces[2] << " "
|
|
<< volelements.Get(i).faces[3] << endl;
|
|
|
|
outfile << "#END_OF_DATA" << endl;
|
|
}
|
|
|
|
|
|
void WriteUserChemnitz (const Mesh & mesh,
|
|
const filesystem::path & filename)
|
|
{
|
|
ofstream outfile (filename);
|
|
|
|
ReadFileMesh (mesh);
|
|
Convert ();
|
|
|
|
WriteFile (outfile);
|
|
cout << "Wrote Chemnitz standard file" << endl;
|
|
}
|
|
static RegisterUserFormat reg_chemnitz ("Chemnitz Format", {"*"}, nullopt, WriteUserChemnitz );
|
|
}
|