Path: blob/devel/ElmerGUI/netgen/libsrc/interface/writetet.cpp
3206 views
1#include <mystdlib.h>23#include <myadt.hpp>4#include <linalg.hpp>5#include <csg.hpp>6#include <acisgeom.hpp>7#include <meshing.hpp>89namespace netgen10{1112#include "writeuser.hpp"131415void WriteTETFormat (const Mesh & mesh,16const string & filename)//, const string& problemType )17{18string problemType = "";19if(!mesh.PureTetMesh())20throw NgException("Can only export pure tet mesh in this format");2122cout << "starting .tet export to file " << filename << endl;232425ARRAY<int> point_ids,edge_ids,face_ids;26ARRAY<int> elnum(mesh.GetNE());27elnum = -1;282930ARRAY<int> userdata_int;31ARRAY<double> userdata_double;32ARRAY<int> ports;3334ARRAY<int> uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D;3536int pos_int = 0;37int pos_double = 0;3839bool haveuserdata =40(mesh.GetUserData("TETmesh:double",userdata_double) &&41mesh.GetUserData("TETmesh:int",userdata_int) &&42mesh.GetUserData("TETmesh:ports",ports) &&43mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) &&44mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) &&45mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) &&46mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) &&47mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D));484950int version,subversion;5152if(haveuserdata)53{54version = int(userdata_double[0]);55subversion = int(10*(userdata_double[0] - version));56pos_double++;57}58else59{60version = 2;61subversion = 0;62}636465if(version >= 2)66{67// test if ids are disjunct, if not version 2.0 not possible68int maxbc(-1),mindomain(-1);6970for(ElementIndex i=0; i<mesh.GetNE(); i++)71if(i==0 || mesh[i].GetIndex() < mindomain)72mindomain = mesh[i].GetIndex();73for(int i=1; i<=mesh.GetNFD(); i++)74if(i==1 || mesh.GetFaceDescriptor(i).BCProperty() > maxbc)75maxbc = mesh.GetFaceDescriptor(i).BCProperty();7677if(maxbc >= mindomain)78{79cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, ";80version = 1; subversion = 1;81cout << "using version " << version << "." << subversion << endl;82}83}84858687int startsize = point_ids.Size();88point_ids.SetSize(mesh.GetNP()+1);89for(int i=startsize; i<point_ids.Size(); i++)90point_ids[i] = -1;919293for(int i=0; i<PointIndex::BASE; i++)94point_ids[i] = -1;959697INDEX_2_CLOSED_HASHTABLE<int> edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());;98INDEX_3_CLOSED_HASHTABLE<int> facenumbers(4*mesh.GetNE()+mesh.GetNSE());99100ARRAY<INDEX_2> edge2node;101ARRAY<INDEX_3> face2edge;102ARRAY<INDEX_4> element2face;103104int numelems(0),numfaces(0),numedges(0),numnodes(0);105106for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++)107{108const Segment & seg = mesh[si];109INDEX_2 i2(seg.p1,seg.p2);110i2.Sort();111if(edgenumbers.Used(i2))112continue;113114numedges++;115edgenumbers.Set(i2,numedges);116edge2node.Append(i2);117118edge_ids.Append(seg.edgenr);119120if(point_ids[seg.p1] == -1)121point_ids[seg.p1] = (version >= 2) ? seg.edgenr : 0;122if(point_ids[seg.p2] == -1)123point_ids[seg.p2] = (version >= 2) ? seg.edgenr : 0;124}125126for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++)127{128if(mesh[si].IsDeleted())129continue;130131const Element2d & elem = mesh[si];132133numfaces++;134INDEX_3 i3(elem[0], elem[1], elem[2]);135136int min = i3[0];137int minpos = 0;138for(int j=1; j<3; j++)139if(i3[j] < min)140{141min = i3[j]; minpos = j;142}143if(minpos == 1)144{145int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux;146}147else if(minpos == 2)148{149int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux;150}151facenumbers.Set(i3,numfaces);152153int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty();154face_ids.Append(bc);155156for(int j=0; j<3; j++)157if(point_ids[elem[j]] == -1)158point_ids[elem[j]] = (version >= 2) ? bc : 0;159160INDEX_2 i2a,i2b;161INDEX_3 f_to_n;162for(int j=0; j<3; j++)163{164i2a = INDEX_2(i3[j],i3[(j+1)%3]);165i2b[0] = i2a[1]; i2b[1] = i2a[0];166if(edgenumbers.Used(i2a))167f_to_n[j] = edgenumbers.Get(i2a);168else if(edgenumbers.Used(i2b))169f_to_n[j] = -edgenumbers.Get(i2b);170else171{172numedges++;173edgenumbers.Set(i2a,numedges);174edge2node.Append(i2a);175f_to_n[j] = numedges;176if(version >= 2)177edge_ids.Append(bc);178else179edge_ids.Append(0);180}181}182face2edge.Append(f_to_n);183}184185for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++)186{187const Element & el = mesh[ei];188189if(el.IsDeleted())190continue;191192numelems++;193elnum[ei] = numelems;194195static int tetfaces[4][3] =196{ { 0, 2, 1 },197{ 0, 1, 3 },198{ 1, 2, 3 },199{ 2, 0, 3 } };200201for(int j=0; j<4; j++)202if(point_ids[el[j]] == -1)203point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0;204205INDEX_4 e_to_f;206207for(int i = 0; i < 4; i++)208{209INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]);210211int min = i3a[0];212int minpos = 0;213for(int j=1; j<3; j++)214if(i3a[j] < min)215{216min = i3a[j]; minpos = j;217}218if(minpos == 1)219{220int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux;221}222else if(minpos == 2)223{224int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux;225}226INDEX_3 i3b(i3a[0],i3a[2],i3a[1]);227228229if(facenumbers.Used(i3a))230e_to_f[i] = facenumbers.Get(i3a);231else if(facenumbers.Used(i3b))232e_to_f[i] = -facenumbers.Get(i3b);233else234{235numfaces++;236facenumbers.Set(i3a,numfaces);237e_to_f[i] = numfaces;238if(version >= 2)239face_ids.Append(el.GetIndex());240else241face_ids.Append(0);242243INDEX_2 i2a,i2b;244INDEX_3 f_to_n;245for(int j=0; j<3; j++)246{247i2a = INDEX_2(i3a[j],i3a[(j+1)%3]);248i2b[0] = i2a[1]; i2b[1] = i2a[0];249if(edgenumbers.Used(i2a))250f_to_n[j] = edgenumbers.Get(i2a);251else if(edgenumbers.Used(i2b))252f_to_n[j] = -edgenumbers.Get(i2b);253else254{255numedges++;256edgenumbers.Set(i2a,numedges);257edge2node.Append(i2a);258f_to_n[j] = numedges;259if(version >= 2)260edge_ids.Append(el.GetIndex());261else262edge_ids.Append(0);263}264}265face2edge.Append(f_to_n);266}267}268element2face.Append(e_to_f);269}270271272273274ofstream outfile(filename.c_str());275276outfile.precision(16);277278int unitcode;279double tolerance;280double dS1,dS2, alphaDeg;281double x3D,y3D,z3D;282int modelverts(0), modeledges(0), modelfaces(0), modelcells(0);283284int numObj0D,numObj1D,numObj2D,numObj3D;285int numports = ports.Size();286287ARRAY<int> nodenum(point_ids.Size()+1);288289nodenum = -1;290291292293numnodes = 0;294for(int i=0; i<point_ids.Size(); i++)295{296if(point_ids[i] != -1)297{298numnodes++;299nodenum[i] = numnodes;300}301}302303304if(haveuserdata)305{306unitcode = userdata_int[pos_int];307pos_int++;308309tolerance = userdata_double[pos_double];310pos_double++;311312dS1 = userdata_double[pos_double];313pos_double++;314dS2 = userdata_double[pos_double];315pos_double++;316alphaDeg = userdata_double[pos_double];317pos_double++;318319x3D = userdata_double[pos_double];320pos_double++;321y3D = userdata_double[pos_double];322pos_double++;323z3D = userdata_double[pos_double];324pos_double++;325326if(version == 2)327{328modelverts = userdata_int[pos_int];329pos_int++;330modeledges = userdata_int[pos_int];331pos_int++;332modelfaces = userdata_int[pos_int];333pos_int++;334modelcells = userdata_int[pos_int];335pos_int++;336}337338numObj3D = userdata_int[pos_int];339pos_int++;340numObj2D = userdata_int[pos_int];341pos_int++;342numObj1D = userdata_int[pos_int];343pos_int++;344numObj0D = userdata_int[pos_int];345pos_int++;346}347else348{349unitcode = 3;350351tolerance = 1e-5;352353dS1 = dS2 = alphaDeg = 0;354355x3D = y3D = z3D = 0;356357modelverts = modeledges = modelfaces = modelcells = 0;358359numObj3D = numObj2D = numObj1D = numObj0D = 0;360}361362string uidpid;363if(version == 1)364uidpid = "PID";365else if (version == 2)366uidpid = "UID";367368369ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps;370for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++)371{372if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC)373{374idmaps.Append(new ARRAY<int,PointIndex::BASE>);375mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true);376}377}378379ARRAY<int> id_num,id_type;380ARRAY< ARRAY<int> *> id_groups;381382383// sst 2008-03-12: Write problem class...384{385std::string block;386block = "// CST Tetrahedral ";387block += !problemType.empty() ? problemType : "High Frequency";388block += " Mesh, Version no.:\n";389390size_t size = block.size()-3;391block += "// ";392block.append( size, '^' );393block += "\n";394395outfile396<< block397<< version << "." << subversion << "\n\n";398}399400outfile401<< "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \402<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \403<< unitcode << "\n\n" \404<< "// Geometric coord \"zero\" tolerance threshold:\n" \405<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \406<< tolerance << "\n\n" \407<< "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \408<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \409<< dS1 << " " << dS2 << " " << alphaDeg <<"\n\n" \410<< "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \411<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \412<< x3D << " " << y3D << " " << z3D << "\n" << endl;413414if(version == 2)415{416outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \417<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \418<< modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl;419}420421422outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \423<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";424outfile << numelems << " "425<< numfaces << " "426<< numedges << " "427<< numnodes << endl << endl;428429outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \430<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";431432433434id_num.SetSize(mesh.GetNP()+1);435id_type.SetSize(mesh.GetNP()+1);436id_num = 0;437id_type = 0;438439int n2,n4,n8;440n2 = n4 = n8 = 0;441442443for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)444{445if(id_num[i] != 0)446continue;447448if(nodenum[i] == -1)449continue;450451ARRAY<int> group;452group.Append(i);453for(int j=0; j<idmaps.Size(); j++)454{455startsize = group.Size();456for(int k=0; k<startsize; k++)457{458int id = (*idmaps[j])[group[k]];459if(id != 0 && !group.Contains(id) && nodenum[id] != -1)460{461group.Append(id);462id_num[id] = j+1+id_num[group[k]];463}464}465}466if(group.Size() > 1)467{468id_groups.Append(new ARRAY<int>(group));469if(group.Size() == 2)470{471id_type[i] = 1;472id_type[group[1]] = 2;473n2++;474}475else if(group.Size() == 4)476{477id_type[i] = 3;478for(int j=1; j<group.Size(); j++)479id_type[group[j]] = 4;480n4++;481}482else if(group.Size() == 8)483{484id_type[i] = 5;485for(int j=1; j<group.Size(); j++)486id_type[group[j]] = 6;487n8++;488}489else490cerr << "ERROR: Identification group size = " << group.Size() << endl;491}492493}494495496for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)497{498if(nodenum[i] == -1)499continue;500outfile << nodenum[i] << " "501<< mesh[i](0) << " "502<< mesh[i](1) << " "503<< mesh[i](2) << " " << id_type[i] << " ";504if(i-PointIndex::BASE < point_ids.Size())505outfile << point_ids[i];506else507outfile << "0";508outfile << "\n";509}510outfile << endl;511512outfile << "\n// Number of Periodic Master Nodes:\n" \513<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \514<< n2 << "\n" \515<< "\n" \516<< "// MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n" \517<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";518for(int i=0; i<id_groups.Size(); i++)519{520if(id_groups[i]->Size() != 2)521continue;522523for(int j=0; j<id_groups[i]->Size(); j++)524outfile << nodenum[(*id_groups[i])[j]] << " ";525for(int j=1; j<id_groups[i]->Size(); j++)526outfile << id_num[(*id_groups[i])[j]] << " ";527outfile << "\n";528529delete id_groups[i];530id_groups[i] = NULL;531}532outfile << endl;533534535outfile << "// Number of Corner Periodic Master Nodes:\n" \536<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \537<< n4 << "\n" \538<< "\n" \539<< "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \540<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";541542543for(int i=0; i<id_groups.Size(); i++)544{545if(!id_groups[i] || id_groups[i]->Size() != 4)546continue;547548for(int j=0; j<id_groups[i]->Size(); j++)549outfile << nodenum[(*id_groups[i])[j]] << " ";550for(int j=1; j<id_groups[i]->Size(); j++)551{552outfile << id_num[(*id_groups[i])[j]] << " ";553}554outfile << "\n";555556delete id_groups[i];557id_groups[i] = NULL;558}559outfile << endl;560561562outfile << "// Number of Cubic Periodic Master Nodes:\n" \563<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \564<< n8 << "\n" \565<< "\n" \566<< "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \567<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";568for(int i=0; i<id_groups.Size(); i++)569{570if(!id_groups[i] || id_groups[i]->Size() != 8)571continue;572573for(int j=0; j<id_groups[i]->Size(); j++)574outfile << nodenum[(*id_groups[i])[j]] << " ";575for(int j=1; j<id_groups[i]->Size(); j++)576outfile << id_num[(*id_groups[i])[j]] << " ";577outfile << "\n";578579delete id_groups[i];580id_groups[i] = NULL;581}582outfile << endl;583584585586587outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<<uidpid<<":\n" \588<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";589590591592ARRAY< ARRAY<int>* > vertex_to_edge(mesh.GetNP()+1);593for(int i=0; i<=mesh.GetNP(); i++)594vertex_to_edge[i] = new ARRAY<int>;595596ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps_edge(idmaps.Size());597for(int i=0; i<idmaps_edge.Size(); i++)598{599idmaps_edge[i] = new ARRAY<int,PointIndex::BASE>(numedges);600(*idmaps_edge[i]) = 0;601}602603ARRAY<int> possible;604for(int i=0; i<edge2node.Size(); i++)605{606const INDEX_2 & v = edge2node[i];607for(int j=0; j<idmaps.Size(); j++)608{609INDEX_2 vid((*idmaps[j])[v[0]], (*idmaps[j])[v[1]]);610if(vid[0] != 0 && vid[0] != v[0] && vid[1] != 0 && vid[1] != v[1])611{612Intersection(*vertex_to_edge[vid[0]],*vertex_to_edge[vid[1]],possible);613if(possible.Size() == 1)614{615(*idmaps_edge[j])[possible[0]] = i+1;616(*idmaps_edge[j])[i+1] = possible[0];617}618else if(possible.Size() > 0)619{620cerr << "ERROR: too many possible edge identifications" << endl;621(*testout) << "ERROR: too many possible edge identifications" << endl622<< "*vertex_to_edge["<<vid[0]<<"] " << *vertex_to_edge[vid[0]] << endl623<< "*vertex_to_edge["<<vid[1]<<"] " << *vertex_to_edge[vid[1]] << endl624<< "possible " << possible << endl;625}626}627}628vertex_to_edge[v[0]]->Append(i+1);629vertex_to_edge[v[1]]->Append(i+1);630}631632633for(int i=0; i<vertex_to_edge.Size(); i++)634delete vertex_to_edge[i];635636637id_groups.SetSize(0);638id_num.SetSize(numedges+1);639id_num = 0;640id_type.SetSize(numedges+1);641id_type = 0;642643n2 = n4 = n8 = 0;644645for(int i=1; i<=edge2node.Size(); i++)646{647if(id_num[i] != 0)648continue;649650651ARRAY<int> group;652group.Append(i);653for(int j=0; j<idmaps_edge.Size(); j++)654{655startsize = group.Size();656for(int k=0; k<startsize; k++)657{658int id = (*idmaps_edge[j])[group[k]];659if(id != 0 && !group.Contains(id))660{661group.Append(id);662id_num[id] = j+1+id_num[group[k]];663}664}665}666if(group.Size() > 1)667{668id_num[i] = 1;669id_groups.Append(new ARRAY<int>(group));670if(group.Size() == 2)671{672id_type[i] = 1;673id_type[group[1]] = 2;674n2++;675}676else if(group.Size() == 4)677{678id_type[i] = 3;679for(int j=1; j<group.Size(); j++)680id_type[group[j]] = 4;681n4++;682}683else684{685cerr << "ERROR: edge identification group size = " << group.Size() << endl;686(*testout) << "edge group " << group << endl;687for(int j=0; j<idmaps_edge.Size(); j++)688{689(*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;690}691}692}693}694695696697for(int i=1; i<=edge2node.Size(); i++)698{699if(id_num[i] != 0)700continue;701702703ARRAY<int> group;704group.Append(i);705for(int j=0; j<idmaps_edge.Size(); j++)706{707startsize = group.Size();708for(int k=0; k<startsize; k++)709{710int id = (*idmaps_edge[j])[group[k]];711if(id != 0 && !group.Contains(id))712{713group.Append(id);714id_num[id] = j+1+id_num[group[k]];715}716}717}718if(group.Size() > 1)719{720id_num[i] = 1;721id_groups.Append(new ARRAY<int>(group));722if(group.Size() == 2)723{724id_type[i] = 1;725id_type[group[1]] = 2;726n2++;727}728else if(group.Size() == 4)729{730id_type[i] = 3;731for(int j=1; j<group.Size(); j++)732id_type[group[j]] = 4;733n4++;734}735else736{737cerr << "ERROR: edge identification group size = " << group.Size() << endl;738(*testout) << "edge group " << group << endl;739for(int j=0; j<idmaps_edge.Size(); j++)740{741(*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl;742}743}744}745746}747748749for(int i=0; i<edge2node.Size(); i++)750outfile << i+1 << " " << nodenum[edge2node[i][0]] << " " << nodenum[edge2node[i][1]]751<< " " << id_type[i+1] << " " << edge_ids[i] << "\n";752753outfile << endl;754755756757outfile << "// Number of Periodic Master Edges:\n"\758<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\759<< n2 << "\n" \760<< "\n"\761<< "// MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\762<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";763for(int i=0; i<id_groups.Size(); i++)764{765if(id_groups[i]->Size() != 2)766continue;767768for(int j=0; j<id_groups[i]->Size(); j++)769outfile << (*id_groups[i])[j] << " ";770for(int j=1; j<id_groups[i]->Size(); j++)771outfile << id_num[(*id_groups[i])[j]] << " ";772outfile << "\n";773774delete id_groups[i];775id_groups[i] = NULL;776}777outfile << endl;778779outfile << "// Number of Corner Periodic Master Edges:\n" \780<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\781<< n4 << "\n" \782<< "\n"\783<< "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\784<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";785for(int i=0; i<id_groups.Size(); i++)786{787if(!id_groups[i] || id_groups[i]->Size() != 4)788continue;789790for(int j=0; j<id_groups[i]->Size(); j++)791outfile << (*id_groups[i])[j] << " ";792for(int j=1; j<id_groups[i]->Size(); j++)793outfile << id_num[(*id_groups[i])[j]] << " ";794outfile << "\n";795796delete id_groups[i];797id_groups[i] = NULL;798}799outfile << endl;800801802outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<<uidpid<<":\n" \803<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";804805806807ARRAY< ARRAY<int>* > edge_to_face(numedges+1);808for(int i=0; i<edge_to_face.Size(); i++)809edge_to_face[i] = new ARRAY<int>;810811812for(int i=0; i<idmaps.Size(); i++)813{814idmaps[i]->SetSize(numfaces);815(*idmaps[i]) = 0;816}817818819for(int i=0; i<face2edge.Size(); i++)820{821for(int j=0; j<idmaps_edge.Size(); j++)822{823int e1id,e2id,e3id;824e1id = (*idmaps_edge[j])[abs(face2edge[i][0])];825e2id = (*idmaps_edge[j])[abs(face2edge[i][1])];826e3id = (*idmaps_edge[j])[abs(face2edge[i][2])];827if(e1id != 0 && e1id != abs(face2edge[i][0]) &&828e2id != 0 && e2id != abs(face2edge[i][1]) &&829e3id != 0 && e3id != abs(face2edge[i][2]))830{831Intersection(*edge_to_face[e1id],*edge_to_face[e2id],*edge_to_face[e3id],possible);832if(possible.Size() == 1)833{834(*idmaps[j])[possible[0]] = i+1;835(*idmaps[j])[i+1] = possible[0];836}837else if(possible.Size() > 0)838cerr << "ERROR: too many possible face identifications" << endl;839}840}841842edge_to_face[abs(face2edge[i][0])]->Append(i+1);843edge_to_face[abs(face2edge[i][1])]->Append(i+1);844edge_to_face[abs(face2edge[i][2])]->Append(i+1);845}846847for(int i=0; i<edge_to_face.Size(); i++)848delete edge_to_face[i];849850851for(int i=0; i<idmaps_edge.Size(); i++)852delete idmaps_edge[i];853854855id_groups.SetSize(0);856id_num.SetSize(numfaces+1);857id_num = 0;858859n2 = n4 = n8 = 0;860861for(int i=1; i<=numfaces; i++)862{863if(id_num[i] != 0)864continue;865866ARRAY<int> group;867group.Append(i);868for(int j=0; j<idmaps.Size(); j++)869{870startsize = group.Size();871for(int k=0; k<startsize; k++)872{873int id = (*idmaps[j])[group[k]];874if(id != 0 && !group.Contains(id))875{876group.Append(id);877id_num[id] = j+1+id_num[group[k]];878}879}880}881if(group.Size() > 1)882{883id_num[i] = -1;884id_groups.Append(new ARRAY<int>(group));885if(group.Size() == 2)886n2++;887else888cerr << "ERROR: face identification group size = " << group.Size() << endl;889}890891}892893894for(int i=0; i<idmaps.Size(); i++)895delete idmaps[i];896897898899900for(int i=0; i<face2edge.Size(); i++)901{902outfile << i+1 << " ";903for(int j=0; j<3; j++)904outfile << face2edge[i][j] << " ";905906if(id_num[i+1] == 0)907outfile << 0;908else if(id_num[i+1] == -1)909outfile << 1;910else911outfile << 2;912913outfile << " " << face_ids[i] <<"\n";914}915outfile << endl;916917918outfile << "// Number of Periodic Master Faces:\n"\919<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\920<< n2 << "\n" \921<< "\n"\922<< "// MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2):\n"\923<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";924for(int i=0; i<id_groups.Size(); i++)925{926if(id_groups[i]->Size() != 2)927continue;928929for(int j=0; j<id_groups[i]->Size(); j++)930outfile << (*id_groups[i])[j] << " ";931for(int j=1; j<id_groups[i]->Size(); j++)932outfile << id_num[(*id_groups[i])[j]] << " ";933outfile << "\n";934935delete id_groups[i];936}937outfile << endl;938939940941942outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<<uidpid<<":\n" \943<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";944945for(ElementIndex i=0; i<mesh.GetNE(); i++)946{947if(elnum[i] >= 0)948{949outfile << elnum[i] << " ";950for(int j=0; j<4; j++)951outfile << element2face[elnum[i]-1][j] << " ";952953outfile << mesh[i].GetIndex() << "\n";954}955}956outfile << endl;957958outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \959<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";960961962for(ElementIndex i=0; i<mesh.GetNE(); i++)963{964if(elnum[i] >= 0)965outfile << elnum[i] << " "966<< nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n";967}968outfile << endl;969970971972973outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n"974<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"975<< " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \976<< "\n" \977<< "// Number of Ports (Ports are a subset of Object2D list):\n" \978<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \979<< numports << "\n" \980<< endl;981982983ARRAY< ARRAY<int> * > groups;984985int maxg = -1;986for(int i = 0; i<uid_to_group_3D.Size(); i++)987if(uid_to_group_3D[i] > maxg)988maxg = uid_to_group_3D[i];989for(int i = 0; i<uid_to_group_2D.Size(); i++)990if(uid_to_group_2D[i] > maxg)991maxg = uid_to_group_2D[i];992for(int i = 0; i<uid_to_group_1D.Size(); i++)993if(uid_to_group_1D[i] > maxg)994maxg = uid_to_group_1D[i];995for(int i = 0; i<uid_to_group_0D.Size(); i++)996if(uid_to_group_0D[i] > maxg)997maxg = uid_to_group_0D[i];998999groups.SetSize(maxg+1);1000for(int i=0; i<groups.Size(); i++)1001groups[i] = new ARRAY<int>;10021003for(ElementIndex i=0; i<mesh.GetNE(); i++)1004if(uid_to_group_3D[mesh[i].GetIndex()] >= 0)1005groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1);10061007100810091010outfile << "// Object3D GroupID, #Elems <immediately followed by> ElemID List:\n" \1011<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";1012for(int i=0; i<numObj3D; i++)1013{1014outfile << i << " " << groups[i]->Size() << "\n";1015for(int j=0; j<groups[i]->Size(); j++)1016outfile << (*groups[i])[j] << "\n";1017}10181019for(int i=0; i<groups.Size(); i++)1020groups[i]->SetSize(0);10211022for(int i=0; i<face_ids.Size(); i++)1023if(uid_to_group_2D[face_ids[i]] >= 0)1024groups[uid_to_group_2D[face_ids[i]]]->Append(i+1);102510261027outfile << "// Object2D GroupID, #Faces <immediately followed by> FaceID List:\n" \1028<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";1029for(int i=0; i<numObj2D; i++)1030{1031outfile << i << " " << groups[i]->Size() << "\n";1032for(int j=0; j<groups[i]->Size(); j++)1033{1034outfile << (*groups[i])[j];1035if(ports.Contains(face_ids[(*groups[i])[j]-1]))1036outfile << " P";1037outfile << "\n";1038}1039}1040outfile << endl;104110421043for(int i=0; i<groups.Size(); i++)1044groups[i]->SetSize(0);10451046for(int i=0; i<edge_ids.Size(); i++)1047if(uid_to_group_1D[edge_ids[i]] >= 0)1048groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1);1049105010511052outfile << "// Object1D GroupID, #Edges <immediately followed by> EdgeID List:\n" \1053<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";1054for(int i=0; i<numObj1D; i++)1055{1056outfile << i << " " << groups[i]->Size() << "\n";1057for(int j=0; j<groups[i]->Size(); j++)1058outfile << (*groups[i])[j] << "\n";1059}1060outfile << endl;106110621063for(int i=0; i<groups.Size(); i++)1064groups[i]->SetSize(0);1065for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++)1066{1067if(i-PointIndex::BASE < point_ids.Size())1068{1069if(uid_to_group_0D[point_ids[i]] >= 0)1070groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE);1071}1072else1073groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE);1074}107510761077outfile << "// Object0D GroupID, #Nodes <immediately followed by> NodeID List:\n" \1078<< "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";1079for(int i=0; i<numObj0D; i++)1080{1081outfile << i << " " << groups[i]->Size() << "\n";1082for(int j=0; j<groups[i]->Size(); j++)1083outfile << (*groups[i])[j] << "\n";1084}1085outfile << endl;10861087for(int i=0; i<groups.Size(); i++)1088delete groups[i];108910901091outfile.close();10921093cout << ".tet export done" << endl;1094}1095}109610971098