// // Write Elmer file // // #include #include #include #include #include #include #include "writeuser.hpp" namespace netgen { extern MeshingParameters mparam; void WriteElmerFormat (const Mesh &mesh, const filesystem::path &dirname) { cout << "write elmer mesh files" << endl; std::map tmap; tmap[TRIG] = 303; tmap[TRIG6] = 306; tmap[QUAD] = 404; tmap[QUAD8] = 408; tmap[TET] = 504; tmap[TET10] = 510; tmap[PYRAMID] = 605; tmap[PYRAMID13] = 613; tmap[PRISM] = 706; tmap[PRISM15] = 715; tmap[HEX] = 808; tmap[HEX20] = 820; std::map> pmap; pmap[TRIG] = {1,2,3}; pmap[TRIG6] = {1,2,3, 6,4,5}; pmap[QUAD] = {1,2,3,4}; pmap[QUAD8] = {1,2,3,4, 5,8,6,7}; pmap[TET] = {1,2,3,4}; pmap[TET10] = {1,2,3,4, 5,8,6,7,9,10}; pmap[PYRAMID]={1,2,3,4,5}; pmap[PYRAMID13]= {1,2,3,4,5,6,7,8,9,10,11,12,13}; pmap[PRISM] = {1,2,3,4,5,6}; pmap[PRISM15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; pmap[HEX] = {1,2,3,4,5,6,7,8}; pmap[HEX20] = {1,2,3,4,5,8,6,7,8, 9,12,10,11, 17,20,19,18, 13,16,14,15}; int np = mesh.GetNP(); int ne = mesh.GetNE(); int nse = mesh.GetNSE(); int i, j; // char str[200]; int inverttets = mparam.inverttets; int invertsurf = mparam.inverttrigs; filesystem::create_directories(dirname); auto get_name = [&dirname]( string s ) { return filesystem::path(dirname).append(s); }; ofstream outfile_h(get_name("mesh.header")); ofstream outfile_n(get_name("mesh.nodes")); ofstream outfile_e(get_name("mesh.elements")); ofstream outfile_b(get_name("mesh.boundary")); ofstream outfile_names(get_name("mesh.names")); for( auto codim : IntRange(0, mesh.GetDimension()-1) ) { auto & names = const_cast(mesh).GetRegionNamesCD(codim); for (auto i0 : Range(names) ) { if(names[i0] == nullptr) continue; string name = *names[i0]; if(name == "" || name == "default") continue; outfile_names << "$" << name << "=" << i0+1 << "\n"; } } auto get3FacePoints = [](const Element2d & el) { INDEX_3 i3; INDEX_4 i4; auto eltype = el.GetType(); switch (eltype) { case TRIG: case TRIG6: i3 = {el[0], el[1], el[2]}; i3.Sort(); break; case QUAD: case QUAD8: i4 = {el[0], el[1], el[2], el[3]}; i4.Sort(); i3 = {i4[0], i4[1], i4[2]}; break; default: throw Exception("Got invalid type (no face)"); } return i3; }; // fill hashtable // use lowest three point numbers of lowest-order face to index faces INDEX_3_HASHTABLE face2volelement(ne); for (int i = 1; i <= ne; i++) { const Element & el = mesh.VolumeElement(i); // getface not working for second order elements -> reconstruct linear element here Element linear_el = el; linear_el.SetNP(el.GetNV()); // GetNV returns 8 for HEX20 for instance for (auto j : Range(1,el.GetNFaces()+1)) { Element2d face; linear_el.GetFace(j, face); face2volelement.Set (get3FacePoints(face), i); cout << "set " << get3FacePoints(face) << "\tto " << i << endl; } } // outfile.precision(6); // outfile.setf (ios::fixed, ios::floatfield); // outfile.setf (ios::showpoint); std::map elcount; for (i = 1; i <= np; i++) { const Point3d & p = mesh.Point(i); outfile_n << i << " -1 "; outfile_n << p.X() << " "; outfile_n << p.Y() << " "; outfile_n << p.Z() << "\n"; } for (i = 1; i <= ne; i++) { Element el = mesh.VolumeElement(i); if (inverttets) el.Invert(); auto eltype = el.GetType(); elcount[eltype]++; outfile_e << i << " " << el.GetIndex() << " " << tmap[eltype] << " "; auto & map = pmap[eltype]; for (j = 1; j <= el.GetNP(); j++) { outfile_e << " "; outfile_e << el.PNum(map[j-1]); } outfile_e << "\n"; } for (i = 1; i <= nse; i++) { Element2d el = mesh.SurfaceElement(i); if (invertsurf) el.Invert(); auto eltype = el.GetType(); elcount[eltype]++; int elind = face2volelement.Get(get3FacePoints(el)); cout << "get " << get3FacePoints(el) << "\t " << elind << endl; outfile_b << i << " " << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << " " << elind << " 0 " << tmap[eltype] << " "; auto & map = pmap[el.GetType()]; for (j = 1; j <= el.GetNP(); j++) { outfile_b << " "; outfile_b << el.PNum(map[j-1]); } outfile_b << "\n"; } outfile_h << np << " " << ne << " " << nse << "\n"; outfile_h << "2" << "\n"; for( auto & [eltype,count] : elcount ) outfile_h << tmap[eltype] << " " << count << "\n"; } static RegisterUserFormat reg_elmer ("Elmer Format", {"*"}, nullopt, WriteElmerFormat); }