netgen/libsrc/interface/read_fnf_mesh.cpp
Joachim Schoeberl 310cb00b13 autotools
2009-01-12 23:40:13 +00:00

447 lines
14 KiB
C++

//
// Read Pro/ENGINEER neutral 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"
bool ReadLine (istream & in, string & buf)
{
do
{
buf = "";
while (in.good())
{
char ch = in.get();
if (ch == '\n') break;
if (ch == '\r') break;
if (ch == '\\')
{
// while (iswhite (ch = in.get() )
ch = in.get(); // '\n' CR
ch = in.get(); // '\n' LF
}
else
buf += ch;
}
}
while (in.good() && (buf == "" || buf[0] == '#'));
return in.good();
}
class LoadType
{
public:
int id;
string name;
string placement;
string valuetype;
ARRAY<double> places;
};
void ReadFNFFormat (Mesh & mesh,
const string & filename)
{
ifstream fin (filename.c_str());
string buf;
mesh.SetDimension (3);
while (ReadLine (fin, buf))
{
stringstream sbuf(buf);
string start_sect, token; char ch;
sbuf >> start_sect;
if (start_sect == "%START_SECT")
{
sbuf >> ch >> token;
if (token == "HEADER")
{
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%TITLE")
{
char ch;
string name;
sbuf >> ch >> name;
cout << "Title: " << name << endl;
}
else if (token == "%STATISTICS")
{
;
}
else if (token == "%END_SECT")
{
break;
}
else
{
cout << "SECTION HEADER, unknown field: " << buf << endl;
}
}
}
else if (token == "ELEM_TYPES")
{
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%ELEM_TYPE")
{
int nr;
string def;
char ch;
sbuf >> nr >> def >> ch;
if (def == "DEF")
{
string classname, type;
sbuf >> classname >> type;
if (classname != "SOLID" || type != "TETRA")
cerr << "Element not supported: " << buf << endl;
}
}
else if (token == "%END_SECT")
{
break;
}
else
{
cout << "SECTION ELEM_TYPE, unknown field: " << buf << endl;
}
}
}
else if (token == "COORD_SYSTEMS")
{
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%END_SECT")
{
break;
}
else
{
// cout << "COORD_SYSTEMS, unknown field: " << buf << endl;
}
}
}
else if (token == "MATERIALS")
{
ARRAY<double> young_modulus, poisson_ratio, mass_density;
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%MATERIAL")
{
int nr;
string prop;
char ch;
double val;
sbuf >> nr >> prop >> ch;
if (prop == "DEF")
{
;
}
else
{
sbuf >> val;
if (prop == "YOUNG_MODULUS")
young_modulus.Append (val);
else if (prop == "POISSON_RATIO")
poisson_ratio.Append (val);
else if (prop == "MASS_DENSITY")
mass_density.Append (val);
}
}
else if (token == "%END_SECT")
{
mesh.SetUserData ("YOUNG_MODULUS", young_modulus);
mesh.SetUserData ("POISSON_RATIO", poisson_ratio);
mesh.SetUserData ("MASS_DENSITY", mass_density);
break;
}
else
{
cout << "SECTION MATERIALS, unknown field: " << buf << endl;
}
}
}
else if (token == "MESH")
{
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%NODE")
{
string st;
char ch;
int nr, ks_id;
double x,y,z;
sbuf >> nr >> st >> ch >> x >> y >> z >> ks_id;
mesh.AddPoint (Point3d (x,y,z) );
}
else if (token == "%ELEM")
{
string elemid, def;
char ch;
int elnr, typid, matid;
string propid;
sbuf >> elnr >> def >> ch;
sbuf >> typid >> matid >> propid;
ARRAY<int> pnums;
while (1)
{
int pn;
sbuf >> pn;
if (!sbuf.good()) break;
pnums.Append (pn);
}
int pe2ng [] = { 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 };
Element el(pnums.Size());
for (int j = 0; j < pnums.Size(); j++)
el[pe2ng[j]] = pnums[j];
el.SetIndex (matid);
mesh.AddVolumeElement (el);
}
else if (token == "%END_SECT")
{
break;
}
else
{
cout << "SECTION MESH, unknown: " << buf << endl;
}
}
}
else if (token == "MESH_TOPOLOGY")
{
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token, kw;
int nr;
char ch;
sbuf >> token;
if (token == "%EDGE")
{
sbuf >> nr >> kw >> ch;
if (kw == "NODES")
{
ARRAY<int> enums;
while (1)
{
int en;
sbuf >> en;
if (!sbuf.good()) break;
enums.Append (en);
}
for (int j = 0; j+2 < enums.Size(); j+=2)
{
Segment seg;
seg.p1 = enums[j];
seg.p2 = enums[j+2];
seg.pmid = enums[j+1];
seg.edgenr = nr;
mesh.AddSegment (seg);
}
}
}
else if (token == "%SURFACE")
{
sbuf >> nr >> kw >> ch;
if (kw == "FACES")
{
ARRAY<int> fnums;
while (1)
{
int fn;
sbuf >> fn;
if (!sbuf.good()) break;
fnums.Append (fn);
}
FaceDescriptor fd(-1, -1, -1, -1);
fd.SetBCProperty (nr);
mesh.AddFaceDescriptor (fd);
for (int j = 0; j < fnums.Size(); j += 2)
{
int elnr = fnums[j];
int fnr = fnums[j+1];
const Element & el = mesh.VolumeElement (elnr);
Element2d el2d;
el.GetFace (fnr, el2d);
el2d.SetIndex (nr);
mesh.AddSurfaceElement (el2d);
}
}
}
else if (token == "%END_SECT")
{
break;
}
else
{
cout << "SECTION MESH, unknown: " << buf << endl;
}
}
}
else if (token == "LOADS")
{
ARRAY<LoadType*> loadtypes;
while (1)
{
ReadLine (fin, buf);
stringstream sbuf(buf);
string token;
sbuf >> token;
if (token == "%LOAD_TYPE")
{
string def;
char ch;
LoadType * lt = new LoadType;
sbuf >> lt->id >> def >> ch >> lt->name >> lt->placement >> lt->valuetype;
if (lt->name == "DISPLACEMENT")
cout << "loadtype DISPLACEMENT found" << endl;
if (lt->placement != "FACE" && lt->placement != "EDGE" && lt->placement != "NODE")
cout << "unsupported placement " << lt->placement << endl;
loadtypes.Append (lt);
}
else if (token == "%LOAD")
{
int id;
string def;
char ch;
int placement;
int load_type_id, con_case_id;
sbuf >> id >> def >> ch;
if (def == "DEF")
{
sbuf >> load_type_id >> con_case_id;
}
if (def == "VAL")
{
sbuf >> placement;
for (int i = 0; i < loadtypes.Size(); i++)
if (load_type_id == loadtypes[i]->id)
loadtypes[i]->places.Append (placement);
}
}
else if (token == "%END_SECT")
{
for (int i = 0; i < loadtypes.Size(); i++)
{
if (loadtypes[i]->placement == "FACE" && loadtypes[i]->name == "DISPLACEMENT")
{
mesh.SetUserData ("CONSTRAINT_DISP_FACE", loadtypes[i]->places);
cout << "constrained faces: " << loadtypes[i]->places << endl;
}
if (loadtypes[i]->placement == "EDGE" && loadtypes[i]->name == "DISPLACEMENT")
{
mesh.SetUserData ("CONSTRAINT_DISP_EDGE", loadtypes[i]->places);
cout << "constrained edges: " << loadtypes[i]->places << endl;
}
if (loadtypes[i]->placement == "NODE" && loadtypes[i]->name == "DISPLACEMENT")
{
mesh.SetUserData ("CONSTRAINT_DISP_NODE", loadtypes[i]->places);
cout << "constrained nodes: " << loadtypes[i]->places << endl;
}
}
break;
}
else
{
cout << "SECTION LOADS, unknown field: " << buf << endl;
}
}
}
else
{
cout << "unknown section " << token << endl;
}
}
else
cout << "parse line: (" << buf << ")" << endl;
}
}
}