mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-14 18:08:33 +05:00
476 lines
16 KiB
C++
476 lines
16 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>
|
|
|
|
#include "writeuser.hpp"
|
|
|
|
namespace netgen
|
|
{
|
|
|
|
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;
|
|
NgArray<double> places;
|
|
};
|
|
|
|
|
|
|
|
|
|
void ReadFNFFormat (Mesh & mesh,
|
|
const filesystem::path & filename)
|
|
{
|
|
ifstream fin (filename);
|
|
|
|
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;
|
|
PrintMessage(3, "Title: ", name);
|
|
}
|
|
else if (token == "%STATISTICS")
|
|
{
|
|
;
|
|
}
|
|
else if (token == "%END_SECT")
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
PrintMessage(1, "SECTION HEADER, unknown field: ",buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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
|
|
{
|
|
PrintMessage(1, "SECTION ELEM_TYPE, unknown field: ", buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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 == "ANALYSIS")
|
|
{
|
|
// ignore this section
|
|
while (1)
|
|
{
|
|
ReadLine (fin, buf);
|
|
stringstream sbuf(buf);
|
|
string token;
|
|
sbuf >> token;
|
|
if (token == "%END_SECT")
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (token == "MATERIALS")
|
|
{
|
|
*testout << "parse materials" << endl;
|
|
NgArray<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")
|
|
{
|
|
string name;
|
|
sbuf >> name;
|
|
mesh.SetMaterial(nr, name);
|
|
}
|
|
else
|
|
{
|
|
sbuf >> val;
|
|
*testout << "prop = " << prop << ", val = " << val << endl;
|
|
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);
|
|
*testout << "young = " << young_modulus << endl;
|
|
*testout << "poisson = " << poisson_ratio << endl;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
PrintMessage(1, "SECTION MATERIALS, unknown field: ", buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
NgArray<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
|
|
{
|
|
PrintMessage(1, "SECTION MESH, unknown: ", buf);
|
|
}
|
|
}
|
|
}
|
|
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")
|
|
{
|
|
NgArray<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[0] = enums[j];
|
|
seg[1] = enums[j+2];
|
|
seg[2] = enums[j+1];
|
|
seg.edgenr = nr;
|
|
mesh.AddSegment (seg);
|
|
}
|
|
}
|
|
}
|
|
else if (token == "%SURFACE")
|
|
{
|
|
sbuf >> nr >> kw >> ch;
|
|
if (kw == "FACES")
|
|
{
|
|
NgArray<int> fnums;
|
|
while (1)
|
|
{
|
|
int fn;
|
|
sbuf >> fn;
|
|
if (!sbuf.good()) break;
|
|
fnums.Append (fn);
|
|
}
|
|
|
|
FaceDescriptor fd(-1, -1, -1, -1);
|
|
fd.SetBCProperty (nr);
|
|
*testout << "add fd " << mesh.GetNFD() << ", nr = " << nr << endl;
|
|
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);
|
|
if(j == 0)
|
|
mesh.GetFaceDescriptor(nr).SetDomainIn(el.GetIndex());
|
|
Element2d el2d;
|
|
el.GetFace (fnr, el2d);
|
|
el2d.SetIndex (nr);
|
|
|
|
mesh.AddSurfaceElement (el2d);
|
|
}
|
|
}
|
|
}
|
|
else if (token == "%END_SECT")
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
PrintMessage(1, "SECTION MESH, unknown: ", buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (token == "LOADS")
|
|
{
|
|
NgArray<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")
|
|
PrintMessage(3, "loadtype DISPLACEMENT found");
|
|
|
|
if (lt->placement != "FACE" && lt->placement != "EDGE" && lt->placement != "NODE")
|
|
PrintMessage(1, "unsupported placement ", lt->placement);
|
|
|
|
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 == "%CON_CASE")
|
|
{ ; }
|
|
|
|
else if (token == "%END_SECT")
|
|
{
|
|
for (int i = 0; i < loadtypes.Size(); i++)
|
|
{
|
|
stringstream str;
|
|
str << loadtypes[i]->places;
|
|
if (loadtypes[i]->placement == "FACE" && loadtypes[i]->name == "DISPLACEMENT")
|
|
{
|
|
mesh.SetUserData ("CONSTRAINT_DISP_FACE", loadtypes[i]->places);
|
|
PrintMessage(3, "constrained faces: ", str.str());
|
|
}
|
|
if (loadtypes[i]->placement == "EDGE" && loadtypes[i]->name == "DISPLACEMENT")
|
|
{
|
|
mesh.SetUserData ("CONSTRAINT_DISP_EDGE", loadtypes[i]->places);
|
|
PrintMessage(3,"constrained edges: ", str.str());
|
|
}
|
|
if (loadtypes[i]->placement == "NODE" && loadtypes[i]->name == "DISPLACEMENT")
|
|
{
|
|
mesh.SetUserData ("CONSTRAINT_DISP_NODE", loadtypes[i]->places);
|
|
PrintMessage(3, "constrained nodes: ", str.str());
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
PrintMessage(1, "SECTION LOADS, unknown field: ", buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
else
|
|
{
|
|
PrintMessage(1, "unknown section ", token);
|
|
}
|
|
}
|
|
else
|
|
PrintMessage(3, "parse line: (", buf, ")");
|
|
}
|
|
mesh.ComputeNVertices();
|
|
}
|
|
static RegisterUserFormat reg_fnf ("Pro/ENGINEER Format", {".fnf"}, ReadFNFFormat, nullopt);
|
|
}
|