netgen/libsrc/interface/readtetmesh.cpp
mhochsteger@cerbsim.com cf59f297a7 use std::filesystem::path
2022-02-23 11:56:00 +01:00

796 lines
25 KiB
C++

//
// Read CST file format
//
#include <mystdlib.h>
#include <myadt.hpp>
#include <linalg.hpp>
#include <csg.hpp>
#include <meshing.hpp>
#include <sys/stat.h>
namespace netgen
{
#include "writeuser.hpp"
void ReadTETFormat (Mesh & mesh,
const filesystem::path & filename)
{
cout << "Reading .tet mesh" << endl;
ifstream in (filename);
int inputsection = 0;
bool done = false;
char ch;
string str;
string version;
int unitcode;
double tolerance;
double dS1, dS2, alphaDeg, x3D, y3D, z3D;
int nelts,nfaces,nedges,nnodes;
int nperiodicmasternodes,ncornerperiodicmasternodes,ncubicperiodicmasternodes;
int nperiodicmasteredges,ncornerperiodicmasteredges;
int nperiodicmasterfaces;
int nodeid,type,pid;
int dummyint;
int modelverts,modeledges,modelfaces,modelcells;
Point3d p;
int numObj3D,numObj2D,numObj1D,numObj0D;
// bool nullstarted;
NgArray<int> eldom;
int minId3D = -1, minId2D = -1;
int maxId3D(-1), maxId2D(-1), maxId1D(-1), maxId0D(-1);
NgArray<NgArray<int> *> segmentdata;
NgArray<Element2d* > tris;
NgArray<int> userdata_int; // just save data for 1:1 output
NgArray<double> userdata_double;
NgArray<int> point_pids;
NgArray<int> tetfacedata;
NgArray<int> uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D;
while(!done)
{
// skip "//" comment
bool comment = true;
while(comment)
{
ch = in.get();
while(ch == ' ' || ch == '\n' || ch == '\t' || ch =='\r')
ch = in.get();
if(ch != '/')
{
comment = false;
in.putback(ch);
}
else
{
ch = in.get();
if(ch != '/')
{
comment = false;
in.putback(ch);
in.putback('/');
}
else
{
in.ignore(10000,'\n');
}
}
}
switch(inputsection)
{
case 0:
// version number
in >> version;
cout << "Version number " << version << endl;
if(version != "1.1" && version != "2" && version != "2.0")
{
cerr << "WARNING: import only tested for versions 1.1 and 2" << endl;
//done = true;
}
userdata_double.Append(atof(version.c_str()));
break;
case 1:
// unit code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL)
in >> unitcode;
cout << "unit code " << unitcode << endl;
userdata_int.Append(unitcode);
break;
case 2:
// Geometric coord "zero" tolerance threshold
in >> tolerance;
cout << "tolerance " << tolerance << endl;
userdata_double.Append(tolerance);
break;
case 3:
// Periodic UnitCell dS1 , dS2 , alphaDeg
in >> dS1 >> dS2 >> alphaDeg;
userdata_double.Append(dS1);
userdata_double.Append(dS2);
userdata_double.Append(alphaDeg);
break;
case 4:
// Periodic UnitCell origin in global coords (x3D,y3D,z3D)
in >> x3D >> y3D >> z3D;
userdata_double.Append(x3D);
userdata_double.Append(y3D);
userdata_double.Append(z3D);
break;
case 5:
// Model entity count: Vertices, Edges, Faces, Cells (Version 2)
in >> modelverts >> modeledges >> modelfaces >> modelcells;
userdata_int.Append(modelverts);
userdata_int.Append(modeledges);
userdata_int.Append(modelfaces);
userdata_int.Append(modelcells);
break;
case 6:
// Topological mesh-entity counts (#elements,#faces,#edges,#nodes)
in >> nelts >> nfaces >> nedges >> nnodes;
cout << nelts << " elements, " << nfaces << " faces, " << nedges << " edges, " << nnodes << " nodes" << endl;
mesh.SetAllocSize(nnodes,2*nedges,nfaces,nelts);
break;
case 7:
// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PMinion 3=CPMaster 4=CPMinion), PID:
{
cout << "read nodes" << endl;
for(int i=0; i<nnodes; i++)
{
in >> nodeid >> p.X() >> p.Y() >> p.Z() >> type >> pid;
mesh.AddPoint(p);
point_pids.Append(pid);
if(pid > maxId0D)
maxId0D = pid;
//(*testout) << "point " << p << " type " << type << " mastersexist " << mastersexist << endl;
}
}
break;
case 8:
// Number of Periodic Master Nodes
in >> nperiodicmasternodes;
break;
case 9:
// MasterNodeID, MinionNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2)
for(int i=0; i<nperiodicmasternodes; i++)
{
for(int j=0; j<2; j++)
in >> dummyint;
in >> dummyint;
}
break;
case 10:
// Number of Corner Periodic Master Nodes
in >> ncornerperiodicmasternodes;
break;
case 11:
// MasterNodeID, 3-MinionNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2)
for(int i=0; i<ncornerperiodicmasternodes; i++)
{
for(int j=0; j<4; j++)
in >> dummyint;
for(int j=0; j<3; j++)
in >> dummyint;
}
break;
case 12:
// Number of Cubic Periodic Master Nodes
in >> ncubicperiodicmasternodes;
break;
case 13:
//MasterNodeID, 7-MinionNodeID's, TranslCodes
for(int i=0; i<ncubicperiodicmasternodes; i++)
{
for(int j=0; j<8; j++)
in >> dummyint;
for(int j=0; j<7; j++)
in >> dummyint;
}
break;
case 14:
// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PMinion 3=CPMaster 4=CPMinion), PID
cout << "read edges" << endl;
// nullstarted = false;
segmentdata.SetSize(nedges);
for(int i=0; i<nedges; i++)
{
segmentdata[i] = new NgArray<int>(7);
*segmentdata[i] = -1;
in >> dummyint;
in >> (*segmentdata[i])[0] >> (*segmentdata[i])[1];
in >> type;
in >> (*segmentdata[i])[2];
if((*segmentdata[i])[2] > maxId1D)
maxId1D = (*segmentdata[i])[2];
}
break;
case 15:
// Number of Periodic Master Edges
in >> nperiodicmasteredges;
break;
case 16:
// MasterEdgeID, MinionEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2)
for(int i=0; i<nperiodicmasteredges; i++)
in >> dummyint >> dummyint >> dummyint;
break;
case 17:
// Number of Corner Periodic Master Edges
in >> ncornerperiodicmasteredges;
break;
case 18:
// MasterEdgeID, 3 MinionEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2)
for(int i=0; i<ncornerperiodicmasteredges; i++)
{
in >> dummyint;
for(int j=0; j<3; j++)
in >> dummyint;
for(int j=0; j<3; j++)
in >> dummyint;
}
break;
case 19:
// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PMinion), PID
{
//Segment seg;
int segnum_ng[3];
bool neg[3];
cout << "read faces" << endl;
// nullstarted = false;
for(int i=0; i<nfaces; i++)
{
int trinum;
int segnum;
tris.Append(new Element2d(TRIG));
in >> trinum;
for(int j=0; j<3; j++)
{
in >> segnum;
neg[j] = (segnum<0);
if(!neg[j])
segnum_ng[j] = segnum-1;
else
segnum_ng[j] = -segnum-1;
if(neg[j])
tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[1];
else
tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[0];
tris.Last()->GeomInfoPi(j+1).trignum = trinum;
}
in >> type;
int faceid;
in >> faceid;
if(faceid > maxId2D)
maxId2D = faceid;
if(i==0 || faceid < minId2D)
minId2D = faceid;
tris.Last()->SetIndex(faceid);
if(faceid > 0)
{
//if(nullstarted)
// {
// cout << "Faces: Assumption about index 0 wrong (face"<<trinum <<")" << endl;
// }
//mesh.AddSurfaceElement(tri);
for(int j=0; j<3; j++)
{
if(neg[j])
{
(*segmentdata[segnum_ng[j]])[4] = faceid;
(*segmentdata[segnum_ng[j]])[6] = trinum;
}
else
{
(*segmentdata[segnum_ng[j]])[3] = faceid;
(*segmentdata[segnum_ng[j]])[5] = trinum;
}
}
}
// else
// nullstarted = true;
}
}
break;
case 20:
// Number of Periodic Master Faces
in >> nperiodicmasterfaces;
break;
case 21:
// MasterFaceID, MinionFaceID, TranslCode (1=dS1 2=dS2)
{
Vec<3> randomvec(-1.32834,3.82399,0.5429151);
int maxtransl = -1;
for(int i=0; i<nperiodicmasterfaces; i++)
{
int tri1,tri2,transl;
NgArray<PointIndex> nodes1(3),nodes2(3);
NgArray<double> sortval1(3),sortval2(3);
in >> tri1 >> tri2 >> transl;
if(transl > maxtransl)
maxtransl = transl;
for(int j=0; j<3; j++)
{
nodes1[j] = tris[tri1-1]->PNum(j+1);
sortval1[j] = Vec<3>(mesh[nodes1[j]])*randomvec;
nodes2[j] = tris[tri2-1]->PNum(j+1);
sortval2[j] = Vec<3>(mesh[nodes2[j]])*randomvec;
}
BubbleSort(sortval1,nodes1);
BubbleSort(sortval2,nodes2);
for(int j=0; j<3; j++)
mesh.GetIdentifications().Add(nodes1[j],nodes2[j],transl);
}
for(int i=1; i<= maxtransl; i++)
mesh.GetIdentifications().SetType(i,Identifications::PERIODIC);
}
break;
case 22:
// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, PID
{
cout << "read elements (1)" << endl;
//SurfaceElementIndex surf[4];
bool neg[4];
int elemid;
int domain;
eldom.SetSize(nelts);
for(int i=0; i<nelts; i++)
{
if(int(100.*i/nelts) % 5 == 0)
cout << int(100.*i/nelts)
#ifdef WIN32
<< "%%\r"
#else
<< "%\r"
#endif
<< flush;
in >> elemid;
for(int j=0; j<4;j++)
{
in >> dummyint;
neg[j] = (dummyint < 0);
if(neg[j])
tetfacedata.Append(-dummyint-1);
//surf[j] = -dummyint-1;
else
tetfacedata.Append(dummyint-1);
tetfacedata.Append(((neg[j]) ? 1 : 0));
//surf[j] = dummyint-1;
}
in >> domain;
eldom[i] = domain;
tetfacedata.Append(domain);
if(i==0 || domain < minId3D)
minId3D = domain;
if(domain > maxId3D)
maxId3D = domain;
// for(int j=0; j<4; j++)
// {
// if(mesh.GetNSE() <= surf[j])
// continue;
// int faceind = 0;
// for(int k=1; k<=mesh.GetNFD(); k++)
// {
// if(mesh.GetFaceDescriptor(k).SurfNr() == mesh[surf[j]].GetIndex())
// faceind = k;
// }
// if(faceind)
// {
// if(neg[j])
// mesh.GetFaceDescriptor(faceind).SetDomainOut(domain);
// else
// mesh.GetFaceDescriptor(faceind).SetDomainIn(domain);
// }
// else
// {
// if(neg[j])
// faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),0,domain,0));
// else
// faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),domain,0,0));
// mesh.GetFaceDescriptor(faceind).SetBCProperty(mesh[surf[j]].GetIndex());
// }
// }
}
cout << endl;
// NgArray<int> indextodescriptor(maxId2D+1);
// for(int i=1; i<=mesh.GetNFD(); i++)
// indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i;
// for(SurfaceElementIndex i=0; i<mesh.GetNSE(); i++)
// mesh[i].SetIndex(indextodescriptor[mesh[i].GetIndex()]);
}
break;
case 23:
// ElemID, NodeID0, NodeID1, NodeID2, NodeID3
{
cout << "read elements (2)" << endl;
Element el(TET);
for(ElementIndex i=0; i<nelts; i++)
{
in >> dummyint;
for(int j=1; j<=4; j++)
in >> el.PNum(j);
swap(el.PNum(1),el.PNum(2));
el.SetIndex(eldom[i]);
mesh.AddVolumeElement(el);
}
}
break;
case 24:
// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D)
{
in >> numObj3D;
userdata_int.Append(numObj3D);
in >> numObj2D;
userdata_int.Append(numObj2D);
in >> numObj1D;
userdata_int.Append(numObj1D);
in >> numObj0D;
userdata_int.Append(numObj0D);
}
break;
case 25:
// Number of Ports (Ports are a subset of Object2D list)
{
in >> dummyint;
//userdata_int.Append(dummyint);
}
break;
case 26:
// Object3D GroupID, #Elems <immediately followed by> ElemID List
{
uid_to_group_3D.SetSize(maxId3D+1);
uid_to_group_3D = -1;
for(int i=0; i<numObj3D; i++)
{
int groupid;
in >> groupid;
(*testout) << "3d groupid " << groupid << endl;
//userdata_int.Append(groupid);
int nelems;
in >> nelems;
//userdata_int.Append(nelems);
for(int j=0; j<nelems; j++)
{
in >> dummyint;
(*testout) << "read " << dummyint << endl;
//userdata_int.Append(dummyint);
if(dummyint < 0)
dummyint *= -1;
uid_to_group_3D[eldom[dummyint-1]] = groupid;
}
}
}
break;
case 27:
// Object2D GroupID, #Faces <immediately followed by> FaceID List
{
NgArray<int> ports;
//int totnum = 0;
uid_to_group_2D.SetSize(maxId2D+1);
uid_to_group_2D = -1;
for(int i=0; i<numObj2D; i++)
{
int groupid;
in >> groupid;
(*testout) << "2d groupid " << groupid << endl;
//userdata_int.Append(groupid);
int nelems;
in >> nelems;
//userdata_int.Append(nelems);
for(int j=0; j<nelems; j++)
{
in >> dummyint;
char port;
while((port = in.get()) == ' ')
;
(*testout) << "read " << dummyint << endl;
if(dummyint < 0)
dummyint *= -1;
int uid = tris[dummyint-1]->GetIndex();
if(port == 'P' || port == 'p')
{
if(!ports.Contains(uid))
ports.Append(uid);
}
else
in.putback(port);
//userdata_int.Append(dummyint);
uid_to_group_2D[uid] = groupid;
(*testout) << "setting " << uid << endl;
//totnum++;
}
}
mesh.SetUserData("TETmesh:ports",ports);
}
break;
case 28:
// Object1D GroupID, #Edges <immediately followed by> EdgeID List
{
uid_to_group_1D.SetSize(maxId1D+1);
uid_to_group_1D = -1;
for(int i=0; i<numObj1D; i++)
{
int groupid;
in >> groupid;
//userdata_int.Append(groupid);
int nelems;
in >> nelems;
//userdata_int.Append(nelems);
for(int j=0; j<nelems; j++)
{
in >> dummyint;
//userdata_int.Append(dummyint);
if(dummyint < 0)
dummyint *= -1;
uid_to_group_1D[(*segmentdata[dummyint-1])[2]] = groupid;
}
}
}
break;
case 29:
// Object0D GroupID, #Nodes <immediately followed by> NodeID List
{
uid_to_group_0D.SetSize(maxId0D+1);
uid_to_group_0D = -1;
for(int i=0; i<numObj0D; i++)
{
int groupid;
in >> groupid;
//userdata_int.Append(groupid);
int nelems;
in >> nelems;
//userdata_int.Append(nelems);
for(int j=0; j<nelems; j++)
{
in >> dummyint;
//userdata_int.Append(dummyint);
if(dummyint < 0)
dummyint *= -1;
uid_to_group_0D[point_pids[dummyint-1]] = groupid;
}
}
}
break;
default:
done = true;
}
if(inputsection == 4 && version == "1.1")
inputsection++;
inputsection++;
}
in.close();
mesh.SetUserData("TETmesh:double",userdata_double);
userdata_int.Append(minId2D);
userdata_int.Append(minId3D);
mesh.SetUserData("TETmesh:int",userdata_int);
//if(version == "1.1")
mesh.SetUserData("TETmesh:point_id",point_pids);
mesh.SetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D);
mesh.SetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D);
mesh.SetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D);
mesh.SetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D);
NgArray<SurfaceElementIndex> surfindices(tris.Size());
surfindices = -1;
for(int i=0; i<tris.Size(); i++)
{
if(atof(version.c_str()) <= 1.999999)
{
if(tris[i]->GetIndex() > 0)
surfindices[i] = mesh.AddSurfaceElement(*tris[i]);
}
else
{
if(tris[i]->GetIndex() > 0 &&
tris[i]->GetIndex() < minId3D)
{
tris[i]->SetIndex(tris[i]->GetIndex()-minId2D+1);
surfindices[i] = mesh.AddSurfaceElement(*tris[i]);
}
}
delete tris[i];
}
mesh.ClearFaceDescriptors();
if(atof(version.c_str()) <= 1.999999)
for(int i = 1; i <= maxId2D; i++)
mesh.AddFaceDescriptor(FaceDescriptor(i,0,0,0));
else
for(int i=minId2D; i<minId3D; i++)
mesh.AddFaceDescriptor(FaceDescriptor(i,0,0,0));
for(int i=0; i<tetfacedata.Size(); i+=9)
{
for(int j=0; j<4; j++)
{
SurfaceElementIndex surf = surfindices[tetfacedata[i+2*j]];
//if(mesh.GetNSE() <= surf)
if(surf == -1)
continue;
if(tetfacedata[i+2*j+1] == 1)
mesh.GetFaceDescriptor(mesh[surf].GetIndex()).SetDomainOut(tetfacedata[i+8]);
else
mesh.GetFaceDescriptor(mesh[surf].GetIndex()).SetDomainIn(tetfacedata[i+8]);
/*
int faceind = 0;
for(int k=1; k<=mesh.GetNFD(); k++)
{
if(mesh.GetFaceDescriptor(k).SurfNr() == mesh[surf].GetIndex())
faceind = k;
}
if(faceind)
{
if(tetfacedata[i+4+j] == 1)
mesh.GetFaceDescriptor(faceind).SetDomainOut(tetfacedata[i+8]);
else
mesh.GetFaceDescriptor(faceind).SetDomainIn(tetfacedata[i+8]);
}
else
{
if(tetfacedata[i+4+j] == 1)
faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf].GetIndex(),0,tetfacedata[i+8],0));
else
faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf].GetIndex(),tetfacedata[i+8],0,0));
mesh.GetFaceDescriptor(faceind).SetBCProperty(mesh[surf].GetIndex());
}
*/
}
}
// NgArray<int> indextodescriptor(maxId2D+1);
// for(int i=1; i<=mesh.GetNFD(); i++)
// indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i;
// for(SurfaceElementIndex i=0; i<mesh.GetNSE(); i++)
// mesh[i].SetIndex(indextodescriptor[mesh[i].GetIndex()]);
for(int i=0; i<segmentdata.Size(); i++)
{
Segment seg;
if((atof(version.c_str()) <= 1.999999 && (*segmentdata[i])[2] > 0) ||
(atof(version.c_str()) > 1.999999 && (*segmentdata[i])[2] > 0 && (*segmentdata[i])[2] < minId2D))
{
seg[0] = (*segmentdata[i])[0];
seg[1] = (*segmentdata[i])[1];
seg.edgenr = (*segmentdata[i])[2];
seg.epgeominfo[0].edgenr = (*segmentdata[i])[2];
seg.epgeominfo[1].edgenr = (*segmentdata[i])[2];
seg.si = (*segmentdata[i])[3]-minId2D+1;
seg.surfnr1 = -1;//(*segmentdata[i])[3];
seg.surfnr2 = -1;//(*segmentdata[i])[4];
seg.geominfo[0].trignum = (*segmentdata[i])[5];
seg.geominfo[1].trignum = (*segmentdata[i])[5];
mesh.AddSegment(seg);
seg[0] = (*segmentdata[i])[1];
seg[1] = (*segmentdata[i])[0];
seg.si = (*segmentdata[i])[4]-minId2D+1;
seg.surfnr1 = -1;//(*segmentdata[i])[3];
seg.surfnr2 = -1;//(*segmentdata[i])[4];
seg.geominfo[0].trignum = (*segmentdata[i])[6];
seg.geominfo[1].trignum = (*segmentdata[i])[6];
mesh.AddSegment(seg);
}
delete segmentdata[i];
}
/*
for(int i=mesh.GetNSeg(); i>=1; i--)
if(mesh.LineSegment(i).epgeominfo[0].edgenr == 0 ||
mesh.LineSegment(i).epgeominfo[1].edgenr == 0)
mesh.FullDeleteSegment(i);
*/
mesh.CalcSurfacesOfNode();
}
}