#include "MeshPartition.hpp" double GetUniformMeshElementSize(Mesh * mesh) { int dim = mesh->Dimension(); int nrelem = mesh->GetNE(); DenseMatrix J(dim); double hmin, hmax; hmin = infinity(); hmax = -infinity(); Vector attr(nrelem); for (int iel=0; ielGetElementBaseGeometry(iel); ElementTransformation *T = mesh->GetElementTransformation(iel); T->SetIntPoint(&Geometries.GetCenter(geom)); Geometries.JacToPerfJac(geom, T->Jacobian(), J); attr(iel) = J.Det(); attr(iel) = pow(abs(attr(iel)), 1.0/double(dim)); hmin = min(hmin, attr(iel)); hmax = max(hmax, attr(iel)); } MFEM_VERIFY(abs(hmin-hmax) < 1e-12, "Case not supported yet") return hmax; } Mesh * ExtendMesh(Mesh * mesh, const Array & directions) { // extrute on one dimension // flag = 1 +x, -1 -x, 2 +y, -2 +y , 3 +z, -3, -z // copy the original mesh; Mesh * mesh_orig = new Mesh(*mesh); if (!directions.Size()) return mesh_orig; int dim = mesh_orig->Dimension(); Mesh * mesh_ext=nullptr; for (int j=0; j= h*ovlp_nlayers, "Check ovlp size in partition"); } element_map.resize(nrpatch); double ppt[dim]; Vector pt(ppt, dim); int nrelem = mesh->GetNE(); for (int el = 0; el < nrelem; el++) { mesh->GetElementTransformation(el)->Transform( Geometries.GetCenter(mesh->GetElementBaseGeometry(el)), pt); // Given the center coordinates determine the patches that this element contributes to Array idx0(dim); Array idx1(dim); Array idx2(dim); vector> idx(3); if (dim == 2) idx[2].Append(0); for (int i = 0; i= nxyz[i]) idx0[i] = nxyz[i]-1; if (idx1[i] < 0) idx1[i] = 0; if (idx1[i] >= nxyz[i]) idx1[i] = nxyz[i]-1; if (idx2[i] < 0) idx2[i] = 0; if (idx2[i] >= nxyz[i]) idx2[i] = nxyz[i]-1; // convenient to put in one list idx[i].Append(idx0[i]); if (idx1[i] != idx0[i]) idx[i].Append(idx1[i]); if (idx2[i] != idx0[i] && idx2[i] != idx1[i]) idx[i].Append(idx2[i]); } // Now loop through all the combinations according to the idx above // in case of dim = 2 then kk = 0 for (int k=0; kDimension(); nx = 5; ny = 1; nz = 1; nxyz[0] = nx; nxyz[1] = ny; nxyz[2] = nz; nrpatch = nx*ny*nz; subdomains.SetSize(nx,ny,nz); Vector pmin, pmax; mesh->GetBoundingBox(pmin, pmax); int nrelem = mesh->GetNE(); int partitioning[nrelem]; // determine the partitioning using the centers of the elements double ppt[dim]; Vector pt(ppt, dim); for (int el = 0; el < nrelem; el++) { mesh->GetElementTransformation(el)->Transform( Geometries.GetCenter(mesh->GetElementBaseGeometry(el)), pt); int part = 0; for (int i = dim-1; i >= 0; i--) { int idx = (int)floor(nxyz[i]*((pt(i) - pmin[i])/(pmax[i] - pmin[i]))); if (idx < 0) { idx = 0; } if (idx >= nxyz[i]) { idx = nxyz[i]-1; } part = part * nxyz[i] + idx; } partitioning[el] = part; } element_map.resize(nrpatch); for (int iel = 0; iel < nrelem; iel++) { int ip = partitioning[iel]; element_map[ip].Append(iel); } for (int k = 0; kDimension(); nx = 5; ny = 1; nz = 1; int nxyz[3] = {nx,ny,nz}; // nrpatch = nx*ny*nz; Vector pmin, pmax; mesh->GetBoundingBox(pmin, pmax); int nrelem = mesh->GetNE(); int partitioning[nrelem]; // determine the partitioning using the centers of the elements double ppt[dim]; Vector pt(ppt, dim); for (int el = 0; el < nrelem; el++) { mesh->GetElementTransformation(el)->Transform( Geometries.GetCenter(mesh->GetElementBaseGeometry(el)), pt); int part = 0; for (int i = dim-1; i >= 0; i--) { int idx = (int)floor(nxyz[i]*((pt(i) - pmin[i])/(pmax[i] - pmin[i]))); if (idx < 0) { idx = 0; } if (idx >= nxyz[i]) { idx = nxyz[i]-1; } part = part * nxyz[i] + idx; } partitioning[el] = part; } std::vector> elem_map; int npatch = nx*ny*nz; elem_map.resize(npatch); for (int iel = 0; iel < nrelem; iel++) { int ip = partitioning[iel]; elem_map[ip].Append(iel); } // Append the next subdomain to the previous nrpatch = nx*ny*nz-1; element_map.resize(nrpatch); for (int ip = 0; ipDimension(); patch_mesh.SetSize(nrpatch); for (int ip = 0; ip patch_vertices; for (int iel=0; iel elem_vertices; int iel_idx = element_map[ip][iel]; mesh->GetElementVertices(iel_idx,elem_vertices); patch_vertices.Append(elem_vertices); } patch_vertices.Sort(); patch_vertices.Unique(); int patch_nrvertices = patch_vertices.Size(); // create the mesh patch_mesh[ip] = new Mesh(dim,patch_nrvertices,patch_nrelems); // Add the vertices for (int iv = 0; ivAddVertex(mesh->GetVertex(vert_idx)); } // Add the elements (for now search through all the vertices in the patch is needed) for (int iel=0; iel elem_vertices; int iel_idx = element_map[ip][iel]; mesh->GetElementVertices(iel_idx,elem_vertices); int nrvert = elem_vertices.Size(); int ind[nrvert]; for (int iv = 0; ivGetElementType(element_map[ip][iel]); AddElementToMesh(patch_mesh[ip],elem_type,ind); } patch_mesh[ip]->FinalizeTopology(); } } void MeshPartition::AddElementToMesh(Mesh * mesh,mfem::Element::Type elem_type, int * ind) { switch (elem_type) { case Element::QUADRILATERAL: mesh->AddQuad(ind); break; case Element::TRIANGLE : mesh->AddTri(ind); break; case Element::HEXAHEDRON : mesh->AddHex(ind); break; case Element::TETRAHEDRON : mesh->AddTet(ind); break; default: MFEM_ABORT("Unknown element type"); break; } } void MeshPartition::PrintElementMap() { mfem::out << "Element map" << endl; for (int ip = 0; ip meshes, string mfilename, string sfilename) { int nrmeshes = meshes.Size(); for (int ip = 0; ipPrint(mesh_ofs); L2_FECollection L2fec(1,meshes[ip]->Dimension()); FiniteElementSpace L2fes(meshes[ip], &L2fec); GridFunction x(&L2fes); ConstantCoefficient alpha((double)ip); x.ProjectCoefficient(alpha); ostringstream sol_name; sol_name << sfilename << setfill('0') << setw(6) << ip; ofstream sol_ofs(sol_name.str().c_str()); x.Save(sol_ofs); } } MeshPartition::~MeshPartition() { for (int ip = 0; ip