template<class T> void Convert_To_Tetrahedralized_Volume( tetgenio& out, TETRAHEDRALIZED_VOLUME<T>& volume ) { ARRAY<VECTOR<T,3> > X; for( int i=0; i < out.numberofpoints; i++){ VECTOR<T,3> p; p.x = out.pointlist[ i*out.mesh_dim + 0 ]; p.y = out.pointlist[ i*out.mesh_dim + 1 ]; p.z = out.pointlist[ i*out.mesh_dim + 2 ]; X.Append(p); //LOG::cout << "V" << i+1 << " : " << p << std::endl; } ARRAY<VECTOR<int,4> > elements; for( int i=0; i < out.numberoftetrahedra; i++){ VECTOR<int,4> e; e(1) = out.tetrahedronlist[ i*out.numberofcorners + 0 ]; e(2) = out.tetrahedronlist[ i*out.numberofcorners + 1 ]; e(3) = out.tetrahedronlist[ i*out.numberofcorners + 2 ]; e(4) = out.tetrahedronlist[ i*out.numberofcorners + 3 ]; elements.Append(e); //LOG::cout << "T" << i+1 << " : " << e << std::endl; } int m = X.m; int n = elements.m; volume.mesh.Initialize_Mesh(m,elements); volume.particles.array_collection->Resize(m); volume.particles.X=X; }
void LineSeg<D> :: GetRawData (ARRAY<double> & data) const { data.Append(2); for(int i=0; i<D; i++) data.Append(p1[i]); for(int i=0; i<D; i++) data.Append(p2[i]); }
void SplineSeg3<D> :: GetRawData (ARRAY<double> & data) const { data.Append(3); for(int i=0; i<D; i++) data.Append(p1[i]); for(int i=0; i<D; i++) data.Append(p2[i]); for(int i=0; i<D; i++) data.Append(p3[i]); }
//##################################################################### // Function Cubic_MN_Weights //##################################################################### template<class T,class T2> ARRAY<T> CUBIC_MN_INTERPOLATION<T,T2>:: Cubic_MN_Weights(const T alpha) const { T alpha2=alpha*alpha; T alpha3=alpha2*alpha; ARRAY<T> weights; weights.Append(-alpha3/2.+alpha2-.5*alpha); //f_k-1 weights.Append(alpha3/2.-5*alpha2/2.+1); //f_k weights.Append(-alpha3/2.+2*alpha2+alpha/2.); //f_k+1 weights.Append(alpha3/2.-alpha2/2.); //f_k+2 for(int i=1;i<=weights.m;i++) weights(i)=max((T)0.,min((T)1.,weights(i))); return weights; }
// Template method that works for BaseArray, BlockArray, PointerArray or BaseList template <class ARRAY, typename T> void GenericSample(ARRAY& test, const T& aValue, const T& bValue) { const Int ARRAY_TEST_SIZE = 1024; Int i; // append ARRAY_TEST_SIZE elements (all initialized by the default constructor) for (i = 0; i < ARRAY_TEST_SIZE; i++) test.Append(); // use an AutoIterator to iterate over the whole array and assign aValue to every element for (AutoIterator<ARRAY> it(test); it; ++it) *it = aValue; // insert an element with bValue at index 10 test.Insert(10, bValue); // erase the element at index 11 test.Erase(11); // just a quick check: we should still have the same number of elements if (test.GetCount() != ARRAY_TEST_SIZE) GeBoom(); // using an Iterator: assign bValue to all elements from test[25] to test[49] typename ARRAY::Iterator end = test.Begin() + 50; for (typename ARRAY::Iterator it = test.Begin() + 25; it != end; it++) *it = bValue; }
void RegisterUserFormats (ARRAY<const char*> & names) { char *types[] = { "Neutral Format", "Surface Mesh Format" , "DIFFPACK Format", "TecPlot Format", "Tochnog Format", "Abaqus Format", "Fluent Format", "Permas Format", "FEAP Format", "Elmer Format", "STL Format", "VRML Format", "Gmsh Format", "JCMwave Format", "TET Format", // { "Chemnitz Format" }, 0 }; for (int i = 0; types[i]; i++) names.Append (types[i]); }
void Add (int ind) { if (!flags.Test(ind)) { set.Append (ind); flags.Set (ind); } }
void Primitive :: GetTangentialSurfaceIndices (const Point<3> & p, ARRAY<int> & surfind, double eps) const { for (int j = 0; j < GetNSurfaces(); j++) if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) if (!surfind.Contains (GetSurfaceId(j))) surfind.Append (GetSurfaceId(j)); }
void Intersection (const FlatArray<T> & in1, const FlatArray<T> & in2, const FlatArray<T> & in3, ARRAY<T> & out) { out.SetSize(0); for(int i=0; i<in1.Size(); i++) if(in2.Contains(in1[i]) && in3.Contains(in1[i])) out.Append(in1[i]); }
void SplineSeg3<D> :: LineIntersections (const double a, const double b, const double c, ARRAY < Point<D> > & points, const double eps) const { points.SetSize(0); double t; const double c1 = a*p1(0) - sqrt(2.)*a*p2(0) + a*p3(0) + b*p1(1) - sqrt(2.)*b*p2(1) + b*p3(1) + (2.-sqrt(2.))*c; const double c2 = -2.*a*p1(0) + sqrt(2.)*a*p2(0) -2.*b*p1(1) + sqrt(2.)*b*p2(1) + (sqrt(2.)-2.)*c; const double c3 = a*p1(0) + b*p1(1) + c; if(fabs(c1) < 1e-20) { if(fabs(c2) < 1e-20) return; t = -c3/c2; if((t > -eps) && (t < 1.+eps)) points.Append(GetPoint(t)); return; } const double discr = c2*c2-4.*c1*c3; if(discr < 0) return; if(fabs(discr/(c1*c1)) < 1e-14) { t = -0.5*c2/c1; if((t > -eps) && (t < 1.+eps)) points.Append(GetPoint(t)); return; } t = (-c2 + sqrt(discr))/(2.*c1); if((t > -eps) && (t < 1.+eps)) points.Append(GetPoint(t)); t = (-c2 - sqrt(discr))/(2.*c1); if((t > -eps) && (t < 1.+eps)) points.Append(GetPoint(t)); }
//##################################################################### // Function Compute_Level_Set_Helper //##################################################################### template<class T> void LEVELSET_MAKER_UNIFORM_2D<T>:: Compute_Level_Set_Helper(const TV_INT& index,T next,ARRAY<TV_INT>& next_todo,ARRAY<T,TV_INT>& phi) { if(!phi.Valid_Index(index)) return; T& p=phi(index); if(p!=FLT_MAX) return; p=next; next_todo.Append(index); }
//##################################################################### // Function Simplices_On_Subsimplex //##################################################################### template<int d> template<int d2> void SIMPLEX_MESH<d>:: Simplices_On_Subsimplex(const VECTOR<int,d2>& subsimplex_nodes,ARRAY<int>& simplices_on_subsimplex) const { assert(incident_elements); const ARRAY<int>& incident=(*incident_elements)(subsimplex_nodes[1]); VECTOR<int,d2-1> other_nodes=subsimplex_nodes.Remove_Index(1); for(int i=1;i<=incident.m;i++){ int simplex=incident(i); if(Nodes_In_Simplex(other_nodes,simplex)) simplices_on_subsimplex.Append(simplex);} }
//##################################################################### // Function Get_Simplex_Bounding_Boxes //##################################################################### template<class T> void RIGID_COLLISION_GEOMETRY<VECTOR<T,3> >:: Get_Simplex_Bounding_Boxes(ARRAY<RANGE<TV> >& bounding_boxes,const bool with_body_motion,const T extra_thickness,const T body_thickness_factor) const { if(!rigid_geometry.simplicial_object->triangle_list) rigid_geometry.simplicial_object->Update_Triangle_List(); for(int t=1;t<=rigid_geometry.simplicial_object->mesh.elements.m;t++){ RANGE<TV> box=rigid_geometry.World_Space_Simplex_Bounding_Box(t); if(with_body_motion) box.Enlarge_To_Include_Box(rigid_geometry.World_Space_Simplex_Bounding_Box(t,saved_states(1).x)); box.Change_Size(extra_thickness+body_thickness_factor*collision_thickness); bounding_boxes.Append(box);} }
void CircleSeg<D> :: LineIntersections (const double a, const double b, const double c, ARRAY < Point<D> > & points, const double eps) const { points.SetSize(0); double px=0,py=0; if(fabs(b) > 1e-20) py = -c/b; else px = -c/a; const double c1 = a*a + b*b; const double c2 = 2. * ( a*(py-pm(1)) - b*(px-pm(0))); const double c3 = pow(px-pm(0),2) + pow(py-pm(1),2) - pow(Radius(),2); const double discr = c2*c2 - 4*c1*c3; if(discr < 0) return; ARRAY<double> t; if(fabs(discr) < 1e-20) t.Append(-0.5*c2/c1); else { t.Append((-c2+sqrt(discr))/(2.*c1)); t.Append((-c2-sqrt(discr))/(2.*c1)); } for(int i=0; i<t.Size(); i++) { Point<D> p (px-t[i]*b,py+t[i]*a); double angle = atan2(p(1),p(0))+M_PI; if(angle > StartAngle()-eps && angle < EndAngle()+eps) points.Append(p); } }
void LineSeg<D> :: LineIntersections (const double a, const double b, const double c, ARRAY < Point<D> > & points, const double eps) const { points.SetSize(0); double denom = -a*p2(0)+a*p1(0)-b*p2(1)+b*p1(1); if(fabs(denom) < 1e-20) return; double t = (a*p1(0)+b*p1(1)+c)/denom; if((t > -eps) && (t < 1.+eps)) points.Append(GetPoint(t)); }
//##################################################################### // Function Command_Prompt_Response //##################################################################### template<class T,class RW> void OPENGL_COMPONENT_DEBUG_PARTICLES_2D<T,RW>:: Command_Prompt_Response() { if(!OPENGL_WORLD::Singleton()->prompt_response.empty()){ std::string command; std::istringstream sstream(OPENGL_WORLD::Singleton()->prompt_response); sstream>>command; if(command=="s"){ ARRAY<int> indices; int index; while(sstream>>index) indices.Append(index); opengl_particles.Clear_Selection(); opengl_particles.Select_Points(indices);}}
//##################################################################### // Function Get_All_Face_Neighbors //##################################################################### template<class T> void QUADTREE_CELL<T>:: Get_All_Face_Neighbors(int face_index,ARRAY<QUADTREE_CELL<T>*>& face_neighbors,const QUADTREE_GRID<T>* grid) const { int face_index_to_offset[][2]={{-1,0},{1,0},{0,-1},{0,1}}; // convertes from face index to x and y offsets for use in neighbor search QUADTREE_CELL<T>* neighbor=Get_Neighbor(face_index_to_offset[face_index][0],face_index_to_offset[face_index][1],grid,0,false); if(!neighbor) return; if(neighbor->Has_Children()){ GET_ALL_FACE_NEIGHBORS_HELPER<T> helper;helper.face_neighbors=&face_neighbors; if(face_index==0){helper.cell_to_add=0;MAP_QUADTREE_MESH<T>::Map_Face_Process_Face(&helper,neighbor,this,X_AXIS,Get_All_Face_Neighbors_Helper);} else if(face_index==1){helper.cell_to_add=1;MAP_QUADTREE_MESH<T>::Map_Face_Process_Face(&helper,this,neighbor,X_AXIS,Get_All_Face_Neighbors_Helper);} else if(face_index==2){helper.cell_to_add=0;MAP_QUADTREE_MESH<T>::Map_Face_Process_Face(&helper,neighbor,this,Y_AXIS,Get_All_Face_Neighbors_Helper);} else{assert(face_index==3);helper.cell_to_add=1; MAP_QUADTREE_MESH<T>::Map_Face_Process_Face(&helper,this,neighbor,Y_AXIS,Get_All_Face_Neighbors_Helper);}} else face_neighbors.Append(neighbor); }
void Polyhedra :: GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const { classname = "Polyhedra"; coeffs.SetSize(0); coeffs.Append (points.Size()); coeffs.Append (faces.Size()); coeffs.Append (planes.Size()); /* int i, j; for (i = 1; i <= planes.Size(); i++) { planes.Elem(i)->Print (*testout); } for (i = 1; i <= faces.Size(); i++) { (*testout) << "face " << i << " has plane " << faces.Get(i).planenr << endl; for (j = 1; j <= 3; j++) (*testout) << points.Get(faces.Get(i).pnums[j-1]); (*testout) << endl; } */ }
void LocalH :: GetOuterPoints (ARRAY<Point3d> & points) { int i, nb = boxes.Size(); for (i = 1; i <= nb; i++) { GradingBox * box = boxes.Get(i); if (!box->flags.isinner && !box->flags.cutboundary) { Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); points.Append (c); } } }
void Polyhedra :: GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, ARRAY<int> & surfind, double eps) const { Vec<3> v1n = v1; v1n.Normalize(); Vec<3> v2n = v2; // - (v2 * v1n) * v1n; v2n.Normalize(); for (int i = 0; i < faces.Size(); i++) { const Point<3> & p1 = points[faces[i].pnums[0]]; Vec<3> v0 = p - p1; if (fabs (v0 * faces[i].nn) > eps) continue; // n->nn if (fabs (v1n * faces[i].nn) > eps_base1) continue; // n->nn if (fabs (v2n * faces[i].nn) > eps_base1) continue; // n->nn double lam01 = (faces[i].w1 * v0); double lam02 = (faces[i].w2 * v0); double lam03 = 1-lam01-lam02; double lam11 = (faces[i].w1 * v1); double lam12 = (faces[i].w2 * v1); double lam13 = -lam11-lam12; double lam21 = (faces[i].w1 * v2); double lam22 = (faces[i].w2 * v2); double lam23 = -lam21-lam22; bool ok1 = lam01 > eps_base1 || lam01 > -eps_base1 && lam11 > eps_base1 || lam01 > -eps_base1 && lam11 > -eps_base1 && lam21 > eps_base1; bool ok2 = lam02 > eps_base1 || lam02 > -eps_base1 && lam12 > eps_base1 || lam02 > -eps_base1 && lam12 > -eps_base1 && lam22 > eps_base1; bool ok3 = lam03 > eps_base1 || lam03 > -eps_base1 && lam13 > eps_base1 || lam03 > -eps_base1 && lam13 > -eps_base1 && lam23 > eps_base1; if (ok1 && ok2 && ok3) { if (!surfind.Contains (GetSurfaceId(faces[i].planenr))) surfind.Append (GetSurfaceId(faces[i].planenr)); } } }
void Primitive :: GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, ARRAY<int> & surfind, double eps) const { for (int j = 0; j < GetNSurfaces(); j++) { if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) { Vec<3> grad; GetSurface(j).CalcGradient (p, grad); if (sqr (grad * v1) < 1e-6 * v1.Length2() * grad.Length2() && sqr (grad * v2) < 1e-6 * v2.Length2() * grad.Length2() ) // new, 18032006 JS { if (!surfind.Contains (GetSurfaceId(j))) surfind.Append (GetSurfaceId(j)); } } } }
void Polyhedra :: GetTangentialSurfaceIndices (const Point<3> & p, ARRAY<int> & surfind, double eps) const { for (int i = 0; i < faces.Size(); i++) { const Point<3> & p1 = points[faces[i].pnums[0]]; Vec<3> v0 = p - p1; double lam3 = -(faces[i].nn * v0); // n->nn if (fabs (lam3) > eps) continue; double lam1 = (faces[i].w1 * v0); double lam2 = (faces[i].w2 * v0); if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) if (!surfind.Contains (GetSurfaceId(i))) surfind.Append (GetSurfaceId(i)); } }
void LocalH :: GetInnerPoints (ARRAY<Point3d> & points) { int i, nb = boxes.Size(); for (i = 1; i <= nb; i++) { GradingBox * box = boxes.Get(i); /* if (box->flags.pinner) points.Append (box->randomip); */ // if (box->flags.pinner) if (box->flags.isinner) { Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); points.Append (c); /* cout << "add point " << c << "; h = " << box->hopt << "; max-min = " << (box->x2[0]-box->x1[0]) << endl; */ } } }
//##################################################################### // Function Exchange_Boundary_Columns //##################################################################### template<class T_GRID> template<class T_ARRAYS_HORIZONTAL_COLUMN> void MPI_RLE_GRID<T_GRID>:: Exchange_Boundary_Columns(const int bandwidth,T_ARRAYS_HORIZONTAL_COLUMN& columns) { int tag=Get_Unique_Tag(); T_BOX_HORIZONTAL_INT sentinels=T_GRID::CELL_ITERATOR::Sentinels(); // send ARRAY<MPI::Request> requests; ARRAY<T_BOX_HORIZONTAL_INT> send_regions; Find_Boundary_Regions(send_regions,sentinels,false,RANGE<VECTOR<int,1> >(0,bandwidth-1),true); ARRAY<ARRAY<char> > buffers(send_regions.m); // must stay alive until after Wait_All for(int n=1; n<=send_regions.m; n++)if(all_neighbor_ranks(n)!=MPI::PROC_NULL) requests.Append(ISend_Columns(columns,send_regions,n,tag,buffers(n))); // probe and receive ARRAY<T_BOX_HORIZONTAL_INT> recv_regions; Find_Boundary_Regions(recv_regions,sentinels,false,RANGE<VECTOR<int,1> >(-bandwidth,-1),true); for(int message=1; message<=requests.m; message++) { MPI::Status probe_status; comm->Probe(MPI::ANY_SOURCE,tag,probe_status); Recv_Columns(columns,recv_regions,tag,probe_status); } // wait for sends to complete MPI_UTILITIES::Wait_All(requests); }
//##################################################################### // Function Find_Or_Read_Structure //##################################################################### template<class TV> bool RIGID_GEOMETRY_COLLECTION<TV>:: Find_Or_Read_Structure(const STREAM_TYPE stream_type,ARRAY<int>& structure_ids,const std::string& filename,const T scaling_factor,const TV& center) { int id; if(!FILE_UTILITIES::File_Exists(filename)) return false; std::string hashname=STRING_UTILITIES::string_sprintf("%s@%.6f",filename.c_str(),scaling_factor); // mangle hash name if(!always_create_structure&&structure_hash.Get(hashname,id)){ // already read in if(!structure_list.Is_Active(id)) PHYSBAM_FATAL_ERROR();} // // only works if the referenced geometry is still in memory else{ // read in for the first time STRUCTURE<TV>* structure=0; if(!stream_type.use_doubles) structure=Read_Write<STRUCTURE<TV>,float>::Create_From_File(filename); #ifndef COMPILE_WITHOUT_DOUBLE_SUPPORT else structure=Read_Write<STRUCTURE<TV>,double>::Create_From_File(filename); #endif if(scaling_factor!=1){ Wrap_Structure_Helper(structure,center); structure->Rescale(scaling_factor);} id=structure_list.Add_Element(structure); if(!always_create_structure) structure_hash.Insert(hashname,id);} structure_ids.Append(id); return true; }
void AddILimit(twoint l) { ilimit->Append(l); }
void AddOLimit(twoint l) { olimit->Append(l); }
//don't check, if already exists! void AddNewSegment(const STLBoundarySeg & seg) { boundary.Append(seg); };
void WriteTETFormat (const Mesh & mesh, const string & filename)//, const string& problemType ) { string problemType = ""; if(!mesh.PureTetMesh()) throw NgException("Can only export pure tet mesh in this format"); cout << "starting .tet export to file " << filename << endl; ARRAY<int> point_ids,edge_ids,face_ids; ARRAY<int> elnum(mesh.GetNE()); elnum = -1; ARRAY<int> userdata_int; ARRAY<double> userdata_double; ARRAY<int> ports; ARRAY<int> uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D; int pos_int = 0; int pos_double = 0; bool haveuserdata = (mesh.GetUserData("TETmesh:double",userdata_double) && mesh.GetUserData("TETmesh:int",userdata_int) && mesh.GetUserData("TETmesh:ports",ports) && mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) && mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) && mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) && mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) && mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D)); int version,subversion; if(haveuserdata) { version = int(userdata_double[0]); subversion = int(10*(userdata_double[0] - version)); pos_double++; } else { version = 2; subversion = 0; } if(version >= 2) { // test if ids are disjunct, if not version 2.0 not possible int maxbc(-1),mindomain(-1); for(ElementIndex i=0; i<mesh.GetNE(); i++) if(i==0 || mesh[i].GetIndex() < mindomain) mindomain = mesh[i].GetIndex(); for(int i=1; i<=mesh.GetNFD(); i++) if(i==1 || mesh.GetFaceDescriptor(i).BCProperty() > maxbc) maxbc = mesh.GetFaceDescriptor(i).BCProperty(); if(maxbc >= mindomain) { cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, "; version = 1; subversion = 1; cout << "using version " << version << "." << subversion << endl; } } int startsize = point_ids.Size(); point_ids.SetSize(mesh.GetNP()+1); for(int i=startsize; i<point_ids.Size(); i++) point_ids[i] = -1; for(int i=0; i<PointIndex::BASE; i++) point_ids[i] = -1; INDEX_2_CLOSED_HASHTABLE<int> edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());; INDEX_3_CLOSED_HASHTABLE<int> facenumbers(4*mesh.GetNE()+mesh.GetNSE()); ARRAY<INDEX_2> edge2node; ARRAY<INDEX_3> face2edge; ARRAY<INDEX_4> element2face; int numelems(0),numfaces(0),numedges(0),numnodes(0); for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++) { const Segment & seg = mesh[si]; INDEX_2 i2(seg.p1,seg.p2); i2.Sort(); if(edgenumbers.Used(i2)) continue; numedges++; edgenumbers.Set(i2,numedges); edge2node.Append(i2); edge_ids.Append(seg.edgenr); if(point_ids[seg.p1] == -1) point_ids[seg.p1] = (version >= 2) ? seg.edgenr : 0; if(point_ids[seg.p2] == -1) point_ids[seg.p2] = (version >= 2) ? seg.edgenr : 0; } for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++) { if(mesh[si].IsDeleted()) continue; const Element2d & elem = mesh[si]; numfaces++; INDEX_3 i3(elem[0], elem[1], elem[2]); int min = i3[0]; int minpos = 0; for(int j=1; j<3; j++) if(i3[j] < min) { min = i3[j]; minpos = j; } if(minpos == 1) { int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux; } else if(minpos == 2) { int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux; } facenumbers.Set(i3,numfaces); int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty(); face_ids.Append(bc); for(int j=0; j<3; j++) if(point_ids[elem[j]] == -1) point_ids[elem[j]] = (version >= 2) ? bc : 0; INDEX_2 i2a,i2b; INDEX_3 f_to_n; for(int j=0; j<3; j++) { i2a = INDEX_2(i3[j],i3[(j+1)%3]); i2b[0] = i2a[1]; i2b[1] = i2a[0]; if(edgenumbers.Used(i2a)) f_to_n[j] = edgenumbers.Get(i2a); else if(edgenumbers.Used(i2b)) f_to_n[j] = -edgenumbers.Get(i2b); else { numedges++; edgenumbers.Set(i2a,numedges); edge2node.Append(i2a); f_to_n[j] = numedges; if(version >= 2) edge_ids.Append(bc); else edge_ids.Append(0); } } face2edge.Append(f_to_n); } for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) { const Element & el = mesh[ei]; if(el.IsDeleted()) continue; numelems++; elnum[ei] = numelems; static int tetfaces[4][3] = { { 0, 2, 1 }, { 0, 1, 3 }, { 1, 2, 3 }, { 2, 0, 3 } }; for(int j=0; j<4; j++) if(point_ids[el[j]] == -1) point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0; INDEX_4 e_to_f; for(int i = 0; i < 4; i++) { INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]); int min = i3a[0]; int minpos = 0; for(int j=1; j<3; j++) if(i3a[j] < min) { min = i3a[j]; minpos = j; } if(minpos == 1) { int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux; } else if(minpos == 2) { int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux; } INDEX_3 i3b(i3a[0],i3a[2],i3a[1]); if(facenumbers.Used(i3a)) e_to_f[i] = facenumbers.Get(i3a); else if(facenumbers.Used(i3b)) e_to_f[i] = -facenumbers.Get(i3b); else { numfaces++; facenumbers.Set(i3a,numfaces); e_to_f[i] = numfaces; if(version >= 2) face_ids.Append(el.GetIndex()); else face_ids.Append(0); INDEX_2 i2a,i2b; INDEX_3 f_to_n; for(int j=0; j<3; j++) { i2a = INDEX_2(i3a[j],i3a[(j+1)%3]); i2b[0] = i2a[1]; i2b[1] = i2a[0]; if(edgenumbers.Used(i2a)) f_to_n[j] = edgenumbers.Get(i2a); else if(edgenumbers.Used(i2b)) f_to_n[j] = -edgenumbers.Get(i2b); else { numedges++; edgenumbers.Set(i2a,numedges); edge2node.Append(i2a); f_to_n[j] = numedges; if(version >= 2) edge_ids.Append(el.GetIndex()); else edge_ids.Append(0); } } face2edge.Append(f_to_n); } } element2face.Append(e_to_f); } ofstream outfile(filename.c_str()); outfile.precision(16); int unitcode; double tolerance; double dS1,dS2, alphaDeg; double x3D,y3D,z3D; int modelverts(0), modeledges(0), modelfaces(0), modelcells(0); int numObj0D,numObj1D,numObj2D,numObj3D; int numports = ports.Size(); ARRAY<int> nodenum(point_ids.Size()+1); nodenum = -1; numnodes = 0; for(int i=0; i<point_ids.Size(); i++) { if(point_ids[i] != -1) { numnodes++; nodenum[i] = numnodes; } } if(haveuserdata) { unitcode = userdata_int[pos_int]; pos_int++; tolerance = userdata_double[pos_double]; pos_double++; dS1 = userdata_double[pos_double]; pos_double++; dS2 = userdata_double[pos_double]; pos_double++; alphaDeg = userdata_double[pos_double]; pos_double++; x3D = userdata_double[pos_double]; pos_double++; y3D = userdata_double[pos_double]; pos_double++; z3D = userdata_double[pos_double]; pos_double++; if(version == 2) { modelverts = userdata_int[pos_int]; pos_int++; modeledges = userdata_int[pos_int]; pos_int++; modelfaces = userdata_int[pos_int]; pos_int++; modelcells = userdata_int[pos_int]; pos_int++; } numObj3D = userdata_int[pos_int]; pos_int++; numObj2D = userdata_int[pos_int]; pos_int++; numObj1D = userdata_int[pos_int]; pos_int++; numObj0D = userdata_int[pos_int]; pos_int++; } else { unitcode = 3; tolerance = 1e-5; dS1 = dS2 = alphaDeg = 0; x3D = y3D = z3D = 0; modelverts = modeledges = modelfaces = modelcells = 0; numObj3D = numObj2D = numObj1D = numObj0D = 0; } string uidpid; if(version == 1) uidpid = "PID"; else if (version == 2) uidpid = "UID"; ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps; for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) { if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) { idmaps.Append(new ARRAY<int,PointIndex::BASE>); mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true); } } ARRAY<int> id_num,id_type; ARRAY< ARRAY<int> *> id_groups; // sst 2008-03-12: Write problem class... { std::string block; block = "// CST Tetrahedral "; block += !problemType.empty() ? problemType : "High Frequency"; block += " Mesh, Version no.:\n"; size_t size = block.size()-3; block += "// "; block.append( size, '^' ); block += "\n"; outfile << block << version << "." << subversion << "\n\n"; } outfile << "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << unitcode << "\n\n" \ << "// Geometric coord \"zero\" tolerance threshold:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << tolerance << "\n\n" \ << "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << dS1 << " " << dS2 << " " << alphaDeg <<"\n\n" \ << "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << x3D << " " << y3D << " " << z3D << "\n" << endl; if(version == 2) { outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl; } outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; outfile << numelems << " " << numfaces << " " << numedges << " " << numnodes << endl << endl; outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; id_num.SetSize(mesh.GetNP()+1); id_type.SetSize(mesh.GetNP()+1); id_num = 0; id_type = 0; int n2,n4,n8; n2 = n4 = n8 = 0; for(int i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++) { if(id_num[i] != 0) continue; if(nodenum[i] == -1) continue; ARRAY<int> group; group.Append(i); for(int j=0; j<idmaps.Size(); j++) { startsize = group.Size(); for(int k=0; k<startsize; k++) { int id = (*idmaps[j])[group[k]]; if(id != 0 && !group.Contains(id) && nodenum[id] != -1) { group.Append(id); id_num[id] = j+1+id_num[group[k]]; } } } if(group.Size() > 1) { id_groups.Append(new ARRAY<int>(group)); if(group.Size() == 2) { id_type[i] = 1; id_type[group[1]] = 2; n2++; } else if(group.Size() == 4) { id_type[i] = 3; for(int j=1; j<group.Size(); j++) id_type[group[j]] = 4; n4++; } else if(group.Size() == 8) { id_type[i] = 5; for(int j=1; j<group.Size(); j++) id_type[group[j]] = 6; n8++; } else cerr << "ERROR: Identification group size = " << group.Size() << endl; } } for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++) { if(nodenum[i] == -1) continue; outfile << nodenum[i] << " " << mesh[i](0) << " " << mesh[i](1) << " " << mesh[i](2) << " " << id_type[i] << " "; if(i-PointIndex::BASE < point_ids.Size()) outfile << point_ids[i]; else outfile << "0"; outfile << "\n"; } outfile << endl; outfile << "\n// Number of Periodic Master Nodes:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << n2 << "\n" \ << "\n" \ << "// MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(id_groups[i]->Size() != 2) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << nodenum[(*id_groups[i])[j]] << " "; for(int j=1; j<id_groups[i]->Size(); j++) outfile << id_num[(*id_groups[i])[j]] << " "; outfile << "\n"; delete id_groups[i]; id_groups[i] = NULL; } outfile << endl; outfile << "// Number of Corner Periodic Master Nodes:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << n4 << "\n" \ << "\n" \ << "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(!id_groups[i] || id_groups[i]->Size() != 4) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << nodenum[(*id_groups[i])[j]] << " "; for(int j=1; j<id_groups[i]->Size(); j++) { outfile << id_num[(*id_groups[i])[j]] << " "; } outfile << "\n"; delete id_groups[i]; id_groups[i] = NULL; } outfile << endl; outfile << "// Number of Cubic Periodic Master Nodes:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << n8 << "\n" \ << "\n" \ << "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(!id_groups[i] || id_groups[i]->Size() != 8) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << nodenum[(*id_groups[i])[j]] << " "; for(int j=1; j<id_groups[i]->Size(); j++) outfile << id_num[(*id_groups[i])[j]] << " "; outfile << "\n"; delete id_groups[i]; id_groups[i] = NULL; } outfile << endl; outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<<uidpid<<":\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; ARRAY< ARRAY<int>* > vertex_to_edge(mesh.GetNP()+1); for(int i=0; i<=mesh.GetNP(); i++) vertex_to_edge[i] = new ARRAY<int>; ARRAY< ARRAY<int,PointIndex::BASE>* > idmaps_edge(idmaps.Size()); for(int i=0; i<idmaps_edge.Size(); i++) { idmaps_edge[i] = new ARRAY<int,PointIndex::BASE>(numedges); (*idmaps_edge[i]) = 0; } ARRAY<int> possible; for(int i=0; i<edge2node.Size(); i++) { const INDEX_2 & v = edge2node[i]; for(int j=0; j<idmaps.Size(); j++) { INDEX_2 vid((*idmaps[j])[v[0]], (*idmaps[j])[v[1]]); if(vid[0] != 0 && vid[0] != v[0] && vid[1] != 0 && vid[1] != v[1]) { Intersection(*vertex_to_edge[vid[0]],*vertex_to_edge[vid[1]],possible); if(possible.Size() == 1) { (*idmaps_edge[j])[possible[0]] = i+1; (*idmaps_edge[j])[i+1] = possible[0]; } else if(possible.Size() > 0) { cerr << "ERROR: too many possible edge identifications" << endl; (*testout) << "ERROR: too many possible edge identifications" << endl << "*vertex_to_edge["<<vid[0]<<"] " << *vertex_to_edge[vid[0]] << endl << "*vertex_to_edge["<<vid[1]<<"] " << *vertex_to_edge[vid[1]] << endl << "possible " << possible << endl; } } } vertex_to_edge[v[0]]->Append(i+1); vertex_to_edge[v[1]]->Append(i+1); } for(int i=0; i<vertex_to_edge.Size(); i++) delete vertex_to_edge[i]; id_groups.SetSize(0); id_num.SetSize(numedges+1); id_num = 0; id_type.SetSize(numedges+1); id_type = 0; n2 = n4 = n8 = 0; for(int i=1; i<=edge2node.Size(); i++) { if(id_num[i] != 0) continue; ARRAY<int> group; group.Append(i); for(int j=0; j<idmaps_edge.Size(); j++) { startsize = group.Size(); for(int k=0; k<startsize; k++) { int id = (*idmaps_edge[j])[group[k]]; if(id != 0 && !group.Contains(id)) { group.Append(id); id_num[id] = j+1+id_num[group[k]]; } } } if(group.Size() > 1) { id_num[i] = 1; id_groups.Append(new ARRAY<int>(group)); if(group.Size() == 2) { id_type[i] = 1; id_type[group[1]] = 2; n2++; } else if(group.Size() == 4) { id_type[i] = 3; for(int j=1; j<group.Size(); j++) id_type[group[j]] = 4; n4++; } else { cerr << "ERROR: edge identification group size = " << group.Size() << endl; (*testout) << "edge group " << group << endl; for(int j=0; j<idmaps_edge.Size(); j++) { (*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl; } } } } for(int i=1; i<=edge2node.Size(); i++) { if(id_num[i] != 0) continue; ARRAY<int> group; group.Append(i); for(int j=0; j<idmaps_edge.Size(); j++) { startsize = group.Size(); for(int k=0; k<startsize; k++) { int id = (*idmaps_edge[j])[group[k]]; if(id != 0 && !group.Contains(id)) { group.Append(id); id_num[id] = j+1+id_num[group[k]]; } } } if(group.Size() > 1) { id_num[i] = 1; id_groups.Append(new ARRAY<int>(group)); if(group.Size() == 2) { id_type[i] = 1; id_type[group[1]] = 2; n2++; } else if(group.Size() == 4) { id_type[i] = 3; for(int j=1; j<group.Size(); j++) id_type[group[j]] = 4; n4++; } else { cerr << "ERROR: edge identification group size = " << group.Size() << endl; (*testout) << "edge group " << group << endl; for(int j=0; j<idmaps_edge.Size(); j++) { (*testout) << "edge id map " << j << endl << *idmaps_edge[j] << endl; } } } } for(int i=0; i<edge2node.Size(); i++) outfile << i+1 << " " << nodenum[edge2node[i][0]] << " " << nodenum[edge2node[i][1]] << " " << id_type[i+1] << " " << edge_ids[i] << "\n"; outfile << endl; outfile << "// Number of Periodic Master Edges:\n"\ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\ << n2 << "\n" \ << "\n"\ << "// MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(id_groups[i]->Size() != 2) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << (*id_groups[i])[j] << " "; for(int j=1; j<id_groups[i]->Size(); j++) outfile << id_num[(*id_groups[i])[j]] << " "; outfile << "\n"; delete id_groups[i]; id_groups[i] = NULL; } outfile << endl; outfile << "// Number of Corner Periodic Master Edges:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\ << n4 << "\n" \ << "\n"\ << "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(!id_groups[i] || id_groups[i]->Size() != 4) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << (*id_groups[i])[j] << " "; for(int j=1; j<id_groups[i]->Size(); j++) outfile << id_num[(*id_groups[i])[j]] << " "; outfile << "\n"; delete id_groups[i]; id_groups[i] = NULL; } outfile << endl; outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<<uidpid<<":\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; ARRAY< ARRAY<int>* > edge_to_face(numedges+1); for(int i=0; i<edge_to_face.Size(); i++) edge_to_face[i] = new ARRAY<int>; for(int i=0; i<idmaps.Size(); i++) { idmaps[i]->SetSize(numfaces); (*idmaps[i]) = 0; } for(int i=0; i<face2edge.Size(); i++) { for(int j=0; j<idmaps_edge.Size(); j++) { int e1id,e2id,e3id; e1id = (*idmaps_edge[j])[abs(face2edge[i][0])]; e2id = (*idmaps_edge[j])[abs(face2edge[i][1])]; e3id = (*idmaps_edge[j])[abs(face2edge[i][2])]; if(e1id != 0 && e1id != abs(face2edge[i][0]) && e2id != 0 && e2id != abs(face2edge[i][1]) && e3id != 0 && e3id != abs(face2edge[i][2])) { Intersection(*edge_to_face[e1id],*edge_to_face[e2id],*edge_to_face[e3id],possible); if(possible.Size() == 1) { (*idmaps[j])[possible[0]] = i+1; (*idmaps[j])[i+1] = possible[0]; } else if(possible.Size() > 0) cerr << "ERROR: too many possible face identifications" << endl; } } edge_to_face[abs(face2edge[i][0])]->Append(i+1); edge_to_face[abs(face2edge[i][1])]->Append(i+1); edge_to_face[abs(face2edge[i][2])]->Append(i+1); } for(int i=0; i<edge_to_face.Size(); i++) delete edge_to_face[i]; for(int i=0; i<idmaps_edge.Size(); i++) delete idmaps_edge[i]; id_groups.SetSize(0); id_num.SetSize(numfaces+1); id_num = 0; n2 = n4 = n8 = 0; for(int i=1; i<=numfaces; i++) { if(id_num[i] != 0) continue; ARRAY<int> group; group.Append(i); for(int j=0; j<idmaps.Size(); j++) { startsize = group.Size(); for(int k=0; k<startsize; k++) { int id = (*idmaps[j])[group[k]]; if(id != 0 && !group.Contains(id)) { group.Append(id); id_num[id] = j+1+id_num[group[k]]; } } } if(group.Size() > 1) { id_num[i] = -1; id_groups.Append(new ARRAY<int>(group)); if(group.Size() == 2) n2++; else cerr << "ERROR: face identification group size = " << group.Size() << endl; } } for(int i=0; i<idmaps.Size(); i++) delete idmaps[i]; for(int i=0; i<face2edge.Size(); i++) { outfile << i+1 << " "; for(int j=0; j<3; j++) outfile << face2edge[i][j] << " "; if(id_num[i+1] == 0) outfile << 0; else if(id_num[i+1] == -1) outfile << 1; else outfile << 2; outfile << " " << face_ids[i] <<"\n"; } outfile << endl; outfile << "// Number of Periodic Master Faces:\n"\ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\ << n2 << "\n" \ << "\n"\ << "// MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2):\n"\ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<id_groups.Size(); i++) { if(id_groups[i]->Size() != 2) continue; for(int j=0; j<id_groups[i]->Size(); j++) outfile << (*id_groups[i])[j] << " "; for(int j=1; j<id_groups[i]->Size(); j++) outfile << id_num[(*id_groups[i])[j]] << " "; outfile << "\n"; delete id_groups[i]; } outfile << endl; outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<<uidpid<<":\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(ElementIndex i=0; i<mesh.GetNE(); i++) { if(elnum[i] >= 0) { outfile << elnum[i] << " "; for(int j=0; j<4; j++) outfile << element2face[elnum[i]-1][j] << " "; outfile << mesh[i].GetIndex() << "\n"; } } outfile << endl; outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(ElementIndex i=0; i<mesh.GetNE(); i++) { if(elnum[i] >= 0) outfile << elnum[i] << " " << nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n"; } outfile << endl; outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n" << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" << " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \ << "\n" \ << "// Number of Ports (Ports are a subset of Object2D list):\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ << numports << "\n" \ << endl; ARRAY< ARRAY<int> * > groups; int maxg = -1; for(int i = 0; i<uid_to_group_3D.Size(); i++) if(uid_to_group_3D[i] > maxg) maxg = uid_to_group_3D[i]; for(int i = 0; i<uid_to_group_2D.Size(); i++) if(uid_to_group_2D[i] > maxg) maxg = uid_to_group_2D[i]; for(int i = 0; i<uid_to_group_1D.Size(); i++) if(uid_to_group_1D[i] > maxg) maxg = uid_to_group_1D[i]; for(int i = 0; i<uid_to_group_0D.Size(); i++) if(uid_to_group_0D[i] > maxg) maxg = uid_to_group_0D[i]; groups.SetSize(maxg+1); for(int i=0; i<groups.Size(); i++) groups[i] = new ARRAY<int>; for(ElementIndex i=0; i<mesh.GetNE(); i++) if(uid_to_group_3D[mesh[i].GetIndex()] >= 0) groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1); outfile << "// Object3D GroupID, #Elems <immediately followed by> ElemID List:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<numObj3D; i++) { outfile << i << " " << groups[i]->Size() << "\n"; for(int j=0; j<groups[i]->Size(); j++) outfile << (*groups[i])[j] << "\n"; } for(int i=0; i<groups.Size(); i++) groups[i]->SetSize(0); for(int i=0; i<face_ids.Size(); i++) if(uid_to_group_2D[face_ids[i]] >= 0) groups[uid_to_group_2D[face_ids[i]]]->Append(i+1); outfile << "// Object2D GroupID, #Faces <immediately followed by> FaceID List:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<numObj2D; i++) { outfile << i << " " << groups[i]->Size() << "\n"; for(int j=0; j<groups[i]->Size(); j++) { outfile << (*groups[i])[j]; if(ports.Contains(face_ids[(*groups[i])[j]-1])) outfile << " P"; outfile << "\n"; } } outfile << endl; for(int i=0; i<groups.Size(); i++) groups[i]->SetSize(0); for(int i=0; i<edge_ids.Size(); i++) if(uid_to_group_1D[edge_ids[i]] >= 0) groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1); outfile << "// Object1D GroupID, #Edges <immediately followed by> EdgeID List:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<numObj1D; i++) { outfile << i << " " << groups[i]->Size() << "\n"; for(int j=0; j<groups[i]->Size(); j++) outfile << (*groups[i])[j] << "\n"; } outfile << endl; for(int i=0; i<groups.Size(); i++) groups[i]->SetSize(0); for(PointIndex i=PointIndex::BASE; i<mesh.GetNP()+PointIndex::BASE; i++) { if(i-PointIndex::BASE < point_ids.Size()) { if(uid_to_group_0D[point_ids[i]] >= 0) groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE); } else groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE); } outfile << "// Object0D GroupID, #Nodes <immediately followed by> NodeID List:\n" \ << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; for(int i=0; i<numObj0D; i++) { outfile << i << " " << groups[i]->Size() << "\n"; for(int j=0; j<groups[i]->Size(); j++) outfile << (*groups[i])[j] << "\n"; } outfile << endl; for(int i=0; i<groups.Size(); i++) delete groups[i]; outfile.close(); cout << ".tet export done" << endl; }
void WriteFile (int typ, const Mesh & mesh, const CSGeometry & geom, const char * filename, const char * geomfile, double h) { int inverttets = mparam.inverttets; int invertsurf = mparam.inverttrigs; if (typ == WRITE_EDGEELEMENT) { // write edge element file // Peter Harscher, ETHZ cout << "Write Edge-Element Format" << endl; ofstream outfile (filename); int i, j; int ned; // hash table representing edges; INDEX_2_HASHTABLE<int> edgeht(mesh.GetNP()); // list of edges ARRAY<INDEX_2> edgelist; // edge (point) on boundary ? BitArray bedge, bpoint(mesh.GetNP()); static int eledges[6][2] = { { 1, 2 } , { 1, 3 } , { 1, 4 }, { 2, 3 } , { 2, 4 } , { 3, 4 } }; // fill hashtable (point1, point2) ----> edgenr for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement (i); INDEX_2 edge; for (j = 1; j <= 6; j++) { edge.I1() = el.PNum (eledges[j-1][0]); edge.I2() = el.PNum (eledges[j-1][1]); edge.Sort(); if (!edgeht.Used (edge)) { edgelist.Append (edge); edgeht.Set (edge, edgelist.Size()); } } } // set bedges, bpoints bedge.SetSize (edgelist.Size()); bedge.Clear(); bpoint.Clear(); for (i = 1; i <= mesh.GetNSE(); i++) { const Element2d & sel = mesh.SurfaceElement(i); for (j = 1; j <= 3; j++) { bpoint.Set (sel.PNum(j)); INDEX_2 edge; edge.I1() = sel.PNum(j); edge.I2() = sel.PNum(j%3+1); edge.Sort(); bedge.Set (edgeht.Get (edge)); } } outfile << mesh.GetNE() << endl; // write element ---> point for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement(i); outfile.width(8); outfile << i; for (j = 1; j <= 4; j++) { outfile.width(8); outfile << el.PNum(j); } outfile << endl; } // write element ---> edge for (i = 1; i <= mesh.GetNE(); i++) { const Element & el = mesh.VolumeElement (i); INDEX_2 edge; for (j = 1; j <= 6; j++) { edge.I1() = el.PNum (eledges[j-1][0]); edge.I2() = el.PNum (eledges[j-1][1]); edge.Sort(); outfile.width(8); outfile << edgeht.Get (edge); } outfile << endl; } // write points outfile << mesh.GetNP() << endl; outfile.precision (6); for (i = 1; i <= mesh.GetNP(); i++) { const Point3d & p = mesh.Point(i); for (j = 1; j <= 3; j++) { outfile.width(8); outfile << p.X(j); } outfile << " " << (bpoint.Test(i) ? "1" : 0) << endl; } // write edges outfile << edgelist.Size() << endl; for (i = 1; i <= edgelist.Size(); i++) { outfile.width(8); outfile << edgelist.Get(i).I1(); outfile.width(8); outfile << edgelist.Get(i).I2(); outfile << " " << (bedge.Test(i) ? "1" : "0") << endl; } } }