gctl_toolkits/archive/gmshset/func.h
2024-09-10 20:25:18 +08:00

496 lines
12 KiB
C++

#ifndef _FUNC_H
#define _FUNC_H
#include "iostream"
#include "fstream"
#include "sstream"
#include "stdio.h"
#include "string.h"
#include "iomanip"
#include "list"
#include "algorithm"
#include "map"
#define MeshFormat "$MeshFormat"
#define EndMeshFormat "$EndMeshFormat"
#define PhysicalNames "$PhysicalNames"
#define EndPhysicalNames "$EndPhysicalNames"
#define Nodes "$Nodes"
#define EndNodes "$EndNodes"
#define Elements "$Elements"
#define EndElements "$EndElements"
#define NodeData "$NodeData"
#define EndNodeData "$EndNodeData"
#define ElementData "$ElementData"
#define EndElementData "$EndElementData"
using namespace std;
struct phys_str
{
int id;
int dim;
char name[1024];
};
struct node_str
{
int id;
double x,y,z;
};
struct element_str
{
int id;
int type;
int tag_num;
int tag[3];
int* node_id;
};
struct nodedata_str
{
int id;
double value;
};
struct elemdata_str
{
int id;
double value;
};
typedef list<int> ListELementType;
typedef list<int> ListPhysical;
typedef list<int> ListGeometry;
typedef map<int,string> TypeMap;
typedef map<string,int> CataMap;
typedef map<int,string> PhysMap;
class MshSet
{
public:
MshSet();
~MshSet();
int init();
int readmsh(char*);
int outmsh(char*,char*,int*,double*,int);
int relese_node_id();
private:
double version_num;
int file_type;
int data_size;
int node_num;
node_str* node;
int elem_num;
element_str* element;
int str_tag_num;
string* str_tag;
int real_tag_num;
double* real_tag;
int int_tag_num;
int int_tag[3];
int nodedata_num;
nodedata_str* nodedata;
double nodedata_max;
double nodedata_min;
int ele_str_tag_num;
string* ele_str_tag;
int ele_real_tag_num;
double* ele_real_tag;
int ele_int_tag_num;
int ele_int_tag[3];
int elemdata_num;
elemdata_str* elemdata;
double elemdata_max;
double elemdata_min;
ListELementType type_list;
ListELementType::iterator it;
ListPhysical phys_list;
ListPhysical::iterator ip;
ListGeometry geom_list;
ListGeometry::iterator ig;
TypeMap map_type;
TypeMap::iterator im;
CataMap map_cata;
CataMap::iterator ic;
PhysMap map_phys;
PhysMap::iterator ih;
int typeint[94];
char* inputname;
};
MshSet::MshSet()
{
node = NULL;
element = NULL;
str_tag = NULL;
real_tag = NULL;
nodedata = NULL;
ele_str_tag = NULL;
ele_real_tag = NULL;
elemdata = NULL;
}
MshSet::~MshSet()
{
if(node!=NULL) delete[] node;
if(element!=NULL) delete[] element;
if(str_tag!=NULL) delete[] str_tag;
if(real_tag!=NULL) delete[] real_tag;
if(nodedata!=NULL) delete[] nodedata;
if(ele_str_tag!=NULL) delete[] ele_str_tag;
if(ele_real_tag!=NULL) delete[] ele_real_tag;
if(elemdata!=NULL) delete[] elemdata;
if(!type_list.empty()) type_list.clear();
if(!phys_list.empty()) phys_list.clear();
if(!geom_list.empty()) geom_list.clear();
if(!map_type.empty()) map_type.clear();
if(!map_cata.empty()) map_cata.clear();
if(!map_phys.empty()) map_phys.clear();
}
int MshSet::init()
{
nodedata_max = -1e+30;
nodedata_min = 1e+30;
elemdata_max = -1e+30;
elemdata_min = 1e+30;
map_type[1] = "2-node line";
map_type[2] = "3-node triangle";
map_type[3] = "4-node quadrangle";
map_type[4] = "4-node tetrahedron";
map_type[5] = "8-node hexahedron";
map_type[6] = "6-node prism";
map_type[7] = "5-node pyramid";
map_type[8] = "3-node second order line";
map_type[9] = "6-ndoe second order line";
map_type[10] = "9-node second order quadrangle";
map_type[11] = "10-node second order tetrahedron";
map_type[12] = "27-node second order hexahedron";
map_type[13] = "18-node second order prism";
map_type[14] = "14-node second order pyramid";
map_type[15] = "1-node point";
map_type[16] = "8-node second order quadrangle";
map_type[17] = "20-ndoe second order hexahedron";
map_type[18] = "15-node second order prism";
map_type[19] = "13-node second order pyramid";
map_type[20] = "9-node third order incomplete triangle";
map_type[21] = "10-ndoe third order triangle";
map_type[22] = "12-node fourth order incomplete triangle";
map_type[23] = "15-node fourth order triangle";
map_type[24] = "15-node fifth order complete triangle";
map_type[25] = "21-node fifth order complete triangle";
map_type[26] = "4-node third order edge";
map_type[27] = "5-node fourth order edge";
map_type[28] = "6-node fifth order edge";
map_type[29] = "20-node third order tetrahedron";
map_type[30] = "35-node fourth order tetrahedron";
map_type[31] = "56-node fifith order tetrahedron";
map_type[92] = "64-node third order hexahedron";
map_type[93] = "125-node fourth order hexahedron";
typeint[1] = 2; typeint[2] = 3; typeint[3] = 4; typeint[4] = 4; typeint[5] = 8;
typeint[6] = 6; typeint[7] = 5; typeint[8] = 3; typeint[9] = 6; typeint[10] = 6;
typeint[11] = 10; typeint[12] = 27; typeint[13] = 18; typeint[14] = 14; typeint[15] = 1;
typeint[16] = 8; typeint[17] = 20; typeint[18] = 15; typeint[19] = 13; typeint[20] = 9;
typeint[21] = 10; typeint[22] = 12; typeint[23] = 15; typeint[24] = 15; typeint[25] = 21;
typeint[26] = 4; typeint[27] = 5; typeint[28] = 6; typeint[29] = 20; typeint[30] = 35;
typeint[31] = 56; typeint[92] = 64; typeint[93] = 125;
return 0;
}
int MshSet::readmsh(char* filename)
{
string curline;
string strtemp,temp_head,temp_middle;
stringstream stemp;
ifstream mshin(filename);
if (!mshin)
{
cout<<filename<<" not found!"<<endl;
return 1;
}
else
{
inputname = filename;
while(getline(mshin,curline))
{
if (curline==MeshFormat)
{
mshin>>version_num>>file_type>>data_size;
if (file_type!=0)
{
cout<<filename<<" not supported!"<<endl;
return 1;
}
}
else if (curline==EndMeshFormat) continue;
else if (curline==PhysicalNames)
{
int phys_num;
phys_str phys_temp;
mshin>>phys_num;
for (int i = 0; i < phys_num; ++i)
{
mshin>>phys_temp.dim>>phys_temp.id>>strtemp;
sscanf(strtemp.c_str(),"\"%[0-9a-zA-Z]",phys_temp.name);
map_phys[phys_temp.id] = phys_temp.name;
}
}
else if (curline==EndPhysicalNames) continue;
else if (curline==Nodes)
{
mshin>>node_num;
node = new node_str [node_num];
for (int i = 0; i < node_num; ++i)
{
mshin>>node[i].id>>node[i].x>>node[i].y>>node[i].z;
}
}
else if (curline==EndNodes) continue;
else if (curline==Elements)
{
mshin>>elem_num;
element = new element_str [elem_num];
for (int i = 0; i < elem_num; ++i)
{
element[i].node_id = NULL;
for (int j = 0; j < 3; ++j)
{
element[i].tag[j] = 1e+5;
}
}
for (int i = 0; i < elem_num; ++i)
{
mshin>>element[i].id>>element[i].type>>element[i].tag_num;
im = map_type.find(element[i].type);
if (im==map_type.end())
{
cout<<"unsupported element type!"<<endl;
return 1;
}
if (type_list.empty())
{
type_list.push_back(element[i].type);
}
else
{
it = find(type_list.begin(),type_list.end(),element[i].type);
if (it==type_list.end()) type_list.push_back(element[i].type);
}
for (int j = 0; j < element[i].tag_num; ++j)
{
mshin>>element[i].tag[j];
}
if (element[i].tag_num==1)
{
if (phys_list.empty())
{
phys_list.push_back(element[i].tag[0]);
}
else
{
ip = find(phys_list.begin(),phys_list.end(),element[i].tag[0]);
if (ip==phys_list.end()) phys_list.push_back(element[i].tag[0]);
}
}
else if (element[i].tag_num==2)
{
if (phys_list.empty())
{
phys_list.push_back(element[i].tag[0]);
}
else
{
ip = find(phys_list.begin(),phys_list.end(),element[i].tag[0]);
if (ip==phys_list.end()) phys_list.push_back(element[i].tag[0]);
}
if (geom_list.empty())
{
geom_list.push_back(element[i].tag[1]);
}
else
{
ig = find(geom_list.begin(),geom_list.end(),element[i].tag[1]);
if (ig==geom_list.end()) geom_list.push_back(element[i].tag[1]);
}
}
element[i].node_id = new int [typeint[element[i].type]];
for (int k = 0; k < typeint[element[i].type]; ++k)
{
mshin>>element[i].node_id[k];
}
temp_head = "";
stemp.clear();
stemp<<element[i].type;
stemp>>temp_head;
for (int j = 0; j < element[i].tag_num; ++j)
{
stemp.clear();
stemp<<element[i].tag[j];
stemp>>temp_middle;
temp_head = temp_head + " " + temp_middle;
}
ic = map_cata.find(temp_head);
if (ic==map_cata.end()) map_cata[temp_head] = 1;
else map_cata[temp_head] = ic->second + 1;
}
}
else if (curline==EndElements) continue;
else if (curline==NodeData)
{
mshin>>str_tag_num;
str_tag = new string [str_tag_num];
getline(mshin,strtemp);//这里加1是因为需要跳过一个上一行的换行符
for (int i = 0; i < str_tag_num; ++i)
{
getline(mshin,strtemp);
str_tag[i] = strtemp;
}
mshin>>real_tag_num;
real_tag = new double [real_tag_num];
for (int i = 0; i < real_tag_num; ++i)
{
mshin>>real_tag[i];
}
mshin>>int_tag_num;
for (int i = 0; i < int_tag_num; ++i)
{
mshin>>int_tag[i];
}
nodedata_num = int_tag[int_tag_num-1];
nodedata = new nodedata_str [nodedata_num];
for (int i = 0; i < nodedata_num; ++i)
{
mshin>>nodedata[i].id>>nodedata[i].value;
if (nodedata[i].value<nodedata_min) nodedata_min = nodedata[i].value;
if (nodedata[i].value>nodedata_max) nodedata_max = nodedata[i].value;
}
}
else if (curline==EndNodeData) continue;
else if (curline==ElementData)
{
mshin>>ele_str_tag_num;
ele_str_tag = new string [ele_str_tag_num];
getline(mshin,strtemp);//这里加1是因为需要跳过一个上一行的换行符
for (int i = 0; i < ele_str_tag_num; ++i)
{
getline(mshin,strtemp);
ele_str_tag[i] = strtemp;
}
mshin>>ele_real_tag_num;
ele_real_tag = new double [ele_real_tag_num];
for (int i = 0; i < ele_real_tag_num; ++i)
{
mshin>>ele_real_tag[i];
}
mshin>>ele_int_tag_num;
for (int i = 0; i < ele_int_tag_num; ++i)
{
mshin>>ele_int_tag[i];
}
elemdata_num = ele_int_tag[ele_int_tag_num-1];
elemdata = new elemdata_str [elemdata_num];
for (int i = 0; i < elemdata_num; ++i)
{
mshin>>elemdata[i].id>>elemdata[i].value;
if (elemdata[i].value<elemdata_min) elemdata_min = elemdata[i].value;
if (elemdata[i].value>elemdata_max) elemdata_max = elemdata[i].value;
}
}
else if (curline==EndElementData) continue;
}
mshin.close();
return 0;
}
}
int MshSet::outmsh(char* infilename,char* outfilename,int* input_type,double* input_value,int input_num)
{
int total_num = 0;
int inttemp;
string strtemp;
stringstream stemp;
ifstream mshin(infilename);
ofstream mshout(outfilename);
if (!mshout)
{
cout<<"can not create "<<outfilename<<endl;
return 1;
}
else
{
while(getline(mshin,strtemp))
{
mshout<<strtemp<<endl;
}
mshin.close();
for (int i = 0; i < input_num; ++i)
{
for (ic=map_cata.begin();ic!=map_cata.end();++ic)
{
strtemp = ic->first;
stemp.clear();
stemp<<strtemp;
stemp>>inttemp>>inttemp;
if (*(input_type+i)==inttemp)
{
//total_num += ic->second;
total_num = ic->second;
mshout<<ElementData<<endl;
mshout<<1<<endl<<"\"PhysicGroup model " << i << "\"" <<endl<<1<<endl<<0<<endl<<3<<endl<<0<<endl<<1<<endl<<total_num<<endl;
for (int j = 0; j < elem_num; ++j)
{
if (element[j].tag[0] == *(input_type+i))
{
mshout<<element[j].id<<" "<< *(input_value+i) <<endl;
}
}
mshout<<EndElementData<<endl;
}
}
}
/*
mshout<<ElementData<<endl;
mshout<<1<<endl<<"\"gmshset model\""<<endl<<1<<endl<<0<<endl<<3<<endl<<0<<endl<<1<<endl<<total_num<<endl;
for (int j = 0; j < input_num; ++j)
{
for (int i = 0; i < elem_num; ++i)
{
if (element[i].tag[0] == *(input_type+j))
{
mshout<<element[i].id<<" "<< *(input_value+j) <<endl;
}
}
}
mshout<<EndElementData;
*/
}
return 0;
}
int MshSet::relese_node_id()
{
for (int i = 0; i < elem_num; ++i)
{
if (element[i].node_id!=NULL) delete[] element[i].node_id;
}
return 0;
}
#endif