Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf8b8bc74e | ||
|
|
c0fbd3a2e3 | ||
|
|
31a7a4a71f |
+222
@@ -29,6 +29,7 @@
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <unordered_set>
|
||||
|
||||
// Include the METIS header, if using version 5. If using METIS 4, the needed
|
||||
// declarations are inlined below, i.e. no header is needed.
|
||||
@@ -10549,6 +10550,227 @@ void Mesh::RemoveInternalBoundaries()
|
||||
attribs.Copy(bdr_attributes);
|
||||
}
|
||||
|
||||
void Mesh::RemoveInternalBoundaries(const Array<int> &_keep)
|
||||
{
|
||||
if (NURBSext || ncmesh) { return; }
|
||||
|
||||
std::unordered_set<int> keep(_keep.GetData(),
|
||||
_keep.GetData() + _keep.Size());
|
||||
|
||||
int num_bdr_elem = 0;
|
||||
int new_bel_to_edge_nnz = 0;
|
||||
for (int i = 0; i < GetNBE(); i++)
|
||||
{
|
||||
if (FaceIsInterior(GetBdrElementEdgeIndex(i)) &&
|
||||
(keep.count(boundary[i]->GetAttribute()) == 0))
|
||||
{
|
||||
FreeElement(boundary[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_bdr_elem++;
|
||||
if (Dim == 3)
|
||||
{
|
||||
new_bel_to_edge_nnz += bel_to_edge->RowSize(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_bdr_elem == GetNBE()) { return; }
|
||||
|
||||
Array<Element *> new_boundary(num_bdr_elem);
|
||||
Array<int> new_be_to_edge, new_be_to_face;
|
||||
Table *new_bel_to_edge = NULL;
|
||||
new_boundary.SetSize(0);
|
||||
if (Dim == 2)
|
||||
{
|
||||
new_be_to_edge.Reserve(num_bdr_elem);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
new_be_to_face.Reserve(num_bdr_elem);
|
||||
new_bel_to_edge = new Table;
|
||||
new_bel_to_edge->SetDims(num_bdr_elem, new_bel_to_edge_nnz);
|
||||
}
|
||||
for (int i = 0; i < GetNBE(); i++)
|
||||
{
|
||||
/// if it's not interior or is in the keep boundary list
|
||||
if (!FaceIsInterior(GetBdrElementEdgeIndex(i)) ||
|
||||
keep.count(boundary[i]->GetAttribute()))
|
||||
{
|
||||
new_boundary.Append(boundary[i]);
|
||||
if (Dim == 2)
|
||||
{
|
||||
new_be_to_edge.Append(be_to_edge[i]);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
int row = new_be_to_face.Size();
|
||||
new_be_to_face.Append(be_to_face[i]);
|
||||
int *e = bel_to_edge->GetRow(i);
|
||||
int ne = bel_to_edge->RowSize(i);
|
||||
int *new_e = new_bel_to_edge->GetRow(row);
|
||||
for (int j = 0; j < ne; j++)
|
||||
{
|
||||
new_e[j] = e[j];
|
||||
}
|
||||
new_bel_to_edge->GetI()[row+1] = new_bel_to_edge->GetI()[row] + ne;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NumOfBdrElements = new_boundary.Size();
|
||||
mfem::Swap(boundary, new_boundary);
|
||||
|
||||
if (Dim == 2)
|
||||
{
|
||||
mfem::Swap(be_to_edge, new_be_to_edge);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
mfem::Swap(be_to_face, new_be_to_face);
|
||||
delete bel_to_edge;
|
||||
bel_to_edge = new_bel_to_edge;
|
||||
}
|
||||
|
||||
Array<int> attribs(num_bdr_elem);
|
||||
for (int i = 0; i < attribs.Size(); i++)
|
||||
{
|
||||
attribs[i] = GetBdrAttribute(i);
|
||||
}
|
||||
attribs.Sort();
|
||||
attribs.Unique();
|
||||
bdr_attributes.DeleteAll();
|
||||
attribs.Copy(bdr_attributes);
|
||||
}
|
||||
|
||||
void Mesh::RemoveInternalBoundariesNotAdjacentTo(const Array<int> &_regions)
|
||||
{
|
||||
if (NURBSext || ncmesh) { return; }
|
||||
|
||||
std::unordered_set<int> regions(_regions.GetData(),
|
||||
_regions.GetData() + _regions.Size());
|
||||
|
||||
int num_bdr_elem = 0;
|
||||
int new_bel_to_edge_nnz = 0;
|
||||
for (int i = 0; i < GetNBE(); i++)
|
||||
{
|
||||
auto faceNo = GetBdrElementEdgeIndex(i);
|
||||
bool interior = FaceIsInterior(faceNo);
|
||||
|
||||
auto face_info = faces_info[faceNo];
|
||||
auto adj = regions.count(elements[face_info.Elem1No]->GetAttribute());
|
||||
if (face_info.Elem2No > 0)
|
||||
adj += regions.count(elements[face_info.Elem2No]->GetAttribute());
|
||||
|
||||
bool remove = interior & !adj;
|
||||
|
||||
// if (remove)
|
||||
// {
|
||||
// std::cout << "remove face on: " << boundary[i]->GetAttribute()
|
||||
// << " adj to ("
|
||||
// << elements[face_info.Elem1No]->GetAttribute();
|
||||
// if (face_info.Elem2No > 0)
|
||||
// {
|
||||
// std::cout << ", "
|
||||
// << elements[face_info.Elem2No]->GetAttribute() << ")\n";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::cout << ")\n";
|
||||
// }
|
||||
// }
|
||||
|
||||
if (remove)
|
||||
{
|
||||
FreeElement(boundary[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_bdr_elem++;
|
||||
if (Dim == 3)
|
||||
{
|
||||
new_bel_to_edge_nnz += bel_to_edge->RowSize(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_bdr_elem == GetNBE()) { return; }
|
||||
|
||||
Array<Element *> new_boundary(num_bdr_elem);
|
||||
Array<int> new_be_to_edge, new_be_to_face;
|
||||
Table *new_bel_to_edge = NULL;
|
||||
new_boundary.SetSize(0);
|
||||
if (Dim == 2)
|
||||
{
|
||||
new_be_to_edge.Reserve(num_bdr_elem);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
new_be_to_face.Reserve(num_bdr_elem);
|
||||
new_bel_to_edge = new Table;
|
||||
new_bel_to_edge->SetDims(num_bdr_elem, new_bel_to_edge_nnz);
|
||||
}
|
||||
for (int i = 0; i < GetNBE(); i++)
|
||||
{
|
||||
auto faceNo = GetBdrElementEdgeIndex(i);
|
||||
bool interior = FaceIsInterior(faceNo);
|
||||
|
||||
auto face_info = faces_info[faceNo];
|
||||
auto adj = regions.count(elements[face_info.Elem1No]->GetAttribute());
|
||||
if (face_info.Elem2No > 0)
|
||||
adj += regions.count(elements[face_info.Elem2No]->GetAttribute());
|
||||
|
||||
bool keep = !interior || adj;
|
||||
|
||||
if (keep)
|
||||
{
|
||||
new_boundary.Append(boundary[i]);
|
||||
if (Dim == 2)
|
||||
{
|
||||
new_be_to_edge.Append(be_to_edge[i]);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
int row = new_be_to_face.Size();
|
||||
new_be_to_face.Append(be_to_face[i]);
|
||||
int *e = bel_to_edge->GetRow(i);
|
||||
int ne = bel_to_edge->RowSize(i);
|
||||
int *new_e = new_bel_to_edge->GetRow(row);
|
||||
for (int j = 0; j < ne; j++)
|
||||
{
|
||||
new_e[j] = e[j];
|
||||
}
|
||||
new_bel_to_edge->GetI()[row+1] = new_bel_to_edge->GetI()[row] + ne;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NumOfBdrElements = new_boundary.Size();
|
||||
mfem::Swap(boundary, new_boundary);
|
||||
|
||||
if (Dim == 2)
|
||||
{
|
||||
mfem::Swap(be_to_edge, new_be_to_edge);
|
||||
}
|
||||
else if (Dim == 3)
|
||||
{
|
||||
mfem::Swap(be_to_face, new_be_to_face);
|
||||
delete bel_to_edge;
|
||||
bel_to_edge = new_bel_to_edge;
|
||||
}
|
||||
|
||||
Array<int> attribs(num_bdr_elem);
|
||||
for (int i = 0; i < attribs.Size(); i++)
|
||||
{
|
||||
attribs[i] = GetBdrAttribute(i);
|
||||
}
|
||||
attribs.Sort();
|
||||
attribs.Unique();
|
||||
bdr_attributes.DeleteAll();
|
||||
attribs.Copy(bdr_attributes);
|
||||
}
|
||||
|
||||
void Mesh::FreeElement(Element *E)
|
||||
{
|
||||
#ifdef MFEM_USE_MEMALLOC
|
||||
|
||||
@@ -1306,6 +1306,12 @@ public:
|
||||
have two adjacent faces in 3D, or edges in 2D. */
|
||||
void RemoveInternalBoundaries();
|
||||
|
||||
/** Remove boundary elements that lie in the interior of the mesh, except
|
||||
for those with boundary attributes in `keep` */
|
||||
void RemoveInternalBoundaries(const Array<int> &keep);
|
||||
|
||||
void RemoveInternalBoundariesNotAdjacentTo(const Array<int> ®ions);
|
||||
|
||||
/** @brief Get the size of the i-th element relative to the perfect
|
||||
reference element. */
|
||||
double GetElementSize(int i, int type = 0);
|
||||
|
||||
Reference in New Issue
Block a user