#include "MeshPart.hpp" double GetPointAngle(const Vector & pt) { double x = pt(0); double y = pt(1); x = (abs(x)<1e-12) ? 0.0 : x; y = (abs(y)<1e-12) ? 0.0 : y; double theta = (x == 0) ? M_PI/2.0 : atan(y/x); int k = (x<=0.0) ? 1 : ((y<0.0) ? 2 : 0.0); theta += k*M_PI; return theta * 180.0/M_PI; } void GetMeshAngleRange(Mesh * mesh, double & amin, double & amax) { amin = infinity(); amax = -infinity(); int nbe = mesh->GetNBE(); int dim = mesh->Dimension(); for (int i = 0; i < nbe; ++i) { Vector center(dim); int geom = mesh->GetBdrElementBaseGeometry(i); ElementTransformation * T = mesh->GetBdrElementTransformation(i); T->Transform(Geometries.GetCenter(geom),center); double thetad = GetPointAngle(center); amin = min(amin,thetad); amax = max(amax,thetad); } } int get_angle_range(double angle, Array angles) { auto it = std::upper_bound(angles.begin(), angles.end(), angle); return std::distance(angles.begin(),it)-1; } void SetMeshAttributes(Mesh * mesh, int subdivisions, double ovlp) { Array angles(2*subdivisions); double amin, amax; GetMeshAngleRange(mesh,amin,amax); angles[0] = amin; double length = (amax-amin)/subdivisions; double range; for (int i = 1; iGetNE(); int dim = mesh->Dimension(); // set element attributes for (int i = 0; i < ne; ++i) { Element *el = mesh->GetElement(i); // roughly the element center Vector center(dim); mesh->GetElementCenter(i,center); double thetad = GetPointAngle(center); // Find the angle relative to (0,0,z) int attr = get_angle_range(thetad, angles) + 1; el->SetAttribute(attr); } mesh->SetAttributes(); cout << "Max attributes " << mesh->attributes.Max() << endl; cout << "angles = " ; angles.Print(cout, 2*subdivisions); if (!angles.IsSorted()) MFEM_WARNING("Check mesh partitioning angles "); } // remove/leave elements with attributes given by attr Mesh * GetPartMesh(const Mesh * mesh0, const Array & attr_, Array & elem_map, bool complement) { Array bdr_attr; int max_attr = mesh0->attributes.Max(); int min_attr = mesh0->attributes.Min(); Array attr; Array all_attr(max_attr); all_attr = 0; for (int i = 0; ibdr_attributes.Max(); bdr_attr.SetSize(attr.Size()); for (int i=0; i marker(max_attr); Array attr_inv(max_attr); marker = 0; attr_inv = 0; for (int i=0; iGetNE(); e++) { int elem_attr = mesh0->GetElement(e)->GetAttribute(); if (!marker[elem_attr-1]) { num_elements++; } } Mesh * mesh = new Mesh(mesh0->Dimension(), mesh0->GetNV(), num_elements); // Copy vertices for (int v=0; vGetNV(); v++) { mesh->AddVertex(mesh0->GetVertex(v)); } // Copy elements elem_map.SetSize(num_elements); int k = 0; for (int e=0; eGetNE(); e++) { const Element * el = mesh0->GetElement(e); int elem_attr = el->GetAttribute(); if (!marker[elem_attr-1]) { Element * nel = mesh->NewElement(el->GetGeometryType()); nel->SetAttribute(elem_attr); nel->SetVertices(el->GetVertices()); mesh->AddElement(nel); elem_map[k++] = e; } } mesh->FinalizeTopology(); mesh->RemoveUnusedVertices(); const GridFunction * nodes0 = mesh0->GetNodes(); int order = nodes0->FESpace()->GetOrder(0); if (order > 1) { mesh->SetCurvature(order, false, 3, Ordering::byVDIM); } GridFunction * nodes = mesh->GetNodes(); int nel = mesh0->GetNE(); // copy nodes int jel = 0; for (int iel = 0; iel< nel; iel++) { int elem_attr = mesh0->GetElement(iel)->GetAttribute(); if (!marker[elem_attr-1]) { Array vdofs0,vdofs; nodes0->FESpace()->GetElementVDofs(iel,vdofs0); Vector x; nodes0->GetSubVector(vdofs0,x); nodes->FESpace()->GetElementVDofs(jel++,vdofs); nodes->SetSubVector(vdofs,x); } } return mesh; } // Partition mesh to nrsubmeshes (equally spaced in the azimuthal direction) void PartitionMesh(Mesh * mesh, int nrsubmeshes, double ovlp, Array & SubMeshes, Array *> & elems) { cout << "Partitioning the global Mesh" << endl; SetMeshAttributes(mesh,nrsubmeshes,ovlp); int maxattr = mesh->attributes.Max(); // Produce the subdomains char vishost[] = "localhost"; int visport = 19916; SubMeshes.SetSize(nrsubmeshes); elems.SetSize(nrsubmeshes); for (int i = 0; i attr; for (int j = 0; j<3; j++) { if (2*i+j >0 && 2*i+j <= maxattr) attr.Append(2*i+j); } Array elem_map; // attr.Print(); elems[i] = new Array(0); SubMeshes[i] = GetPartMesh(mesh,attr,*elems[i],true); // socketstream mesh_sock(vishost, visport); // mesh_sock << "parallel " << nrsubmeshes << " " << i << "\n"; // mesh_sock.precision(8); // mesh_sock << "mesh\n" << *SubMeshes[i] << flush; // cout << "nrelemes = " << mesh1->GetNE() << endl; } }