From 647e4b68a2bada6c7cdf52bfd4315515af7ff1d9 Mon Sep 17 00:00:00 2001 From: David Wells Date: Tue, 20 Dec 2022 10:20:16 -0500 Subject: [PATCH] Compress face types to a single bit. This lowers memory consumption from 712 MB to 707 MB for my 2.4 million cell tet mesh. --- .../deal.II/grid/tria_accessor.templates.h | 2 +- include/deal.II/grid/tria_faces.h | 47 +++++++++++++++++-- source/grid/tria.cc | 25 ++++------ source/grid/tria_faces.cc | 2 +- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/include/deal.II/grid/tria_accessor.templates.h b/include/deal.II/grid/tria_accessor.templates.h index a3bb8eb9c6..20ea7a9f05 100644 --- a/include/deal.II/grid/tria_accessor.templates.h +++ b/include/deal.II/grid/tria_accessor.templates.h @@ -1358,7 +1358,7 @@ TriaAccessor::reference_cell() const return this->tria->levels[this->present_level] ->reference_cell[this->present_index]; else - return this->tria->faces->quad_reference_cell[this->present_index]; + return this->tria->faces->get_quad_type(this->present_index); } diff --git a/include/deal.II/grid/tria_faces.h b/include/deal.II/grid/tria_faces.h index 56ef15c61d..ad12e541fd 100644 --- a/include/deal.II/grid/tria_faces.h +++ b/include/deal.II/grid/tria_faces.h @@ -73,11 +73,26 @@ namespace internal std::vector quads_line_orientations; /** - * Reference cell type of each quad. + * Whether or not each quad is a Quadrilateral. Since, if dim = 3, faces + * are either Triangles or Quadrilaterals, it suffices to store a + * boolean. * * @note Used only for dim=3. */ - std::vector quad_reference_cell; + std::vector quad_is_quadrilateral; + + /** + * Helper accessor function for quad_is_quadrilateral + */ + dealii::ReferenceCell + get_quad_type(const std::size_t index) const; + + /** + * Helper accessor function for quad_is_quadrilateral + */ + void + set_quad_type(const std::size_t index, + const dealii::ReferenceCell face_type); /** * The TriaObject containing the data of lines. @@ -105,12 +120,38 @@ namespace internal + inline dealii::ReferenceCell + TriaFaces::get_quad_type(const std::size_t index) const + { + AssertIndexRange(index, quad_is_quadrilateral.size()); + return quad_is_quadrilateral[index] ? ReferenceCells::Quadrilateral : + ReferenceCells::Triangle; + } + + + + inline void + TriaFaces::set_quad_type(const std::size_t index, + const dealii::ReferenceCell face_type) + { + AssertIndexRange(index, quad_is_quadrilateral.size()); + Assert(face_type == ReferenceCells::Quadrilateral || + face_type == ReferenceCells::Triangle, + ExcInternalError()); + if (face_type == ReferenceCells::Quadrilateral) + quad_is_quadrilateral[index] = true; + else + quad_is_quadrilateral[index] = false; + } + + + template void TriaFaces::serialize(Archive &ar, const unsigned int) { ar &dim; - ar &quads &lines &quads_line_orientations &quad_reference_cell; + ar &quads &lines &quads_line_orientations &quad_is_quadrilateral; } } // namespace TriangulationImplementation } // namespace internal diff --git a/source/grid/tria.cc b/source/grid/tria.cc index 11a3e08b06..91072928a5 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -1126,11 +1126,9 @@ namespace internal tria_faces.quads_line_orientations.size(), 1u); - tria_faces.quad_reference_cell.reserve(new_size); - tria_faces.quad_reference_cell.insert( - tria_faces.quad_reference_cell.end(), - new_size - tria_faces.quad_reference_cell.size(), - dealii::ReferenceCells::Quadrilateral); + auto &q_is_q = tria_faces.quad_is_quadrilateral; + q_is_q.reserve(new_size); + q_is_q.insert(q_is_q.end(), new_size - q_is_q.size(), true); } } @@ -2347,7 +2345,7 @@ namespace internal for (unsigned int q = 0, k = 0; q < n_quads; ++q) { // set entity type of quads - faces.quad_reference_cell[q] = connectivity.entity_types(2)[q]; + faces.set_quad_type(q, connectivity.entity_types(2)[q]); // loop over all its lines for (unsigned int i = crs.ptr[q], j = 0; i < crs.ptr[q + 1]; @@ -2622,8 +2620,7 @@ namespace internal if (dim == 3 && structdim == 2) { // quad entity types - faces.quad_reference_cell.assign(size, - dealii::ReferenceCells::Invalid); + faces.quad_is_quadrilateral.assign(size, true); // quad line orientations faces.quads_line_orientations.assign(size * max_faces_per_cell, -1); @@ -5477,8 +5474,8 @@ namespace internal // TODO: we assume here that all children have the same type // as the parent - triangulation.faces->quad_reference_cell[new_quad->index()] = - reference_face_type; + triangulation.faces->set_quad_type(new_quad->index(), + reference_face_type); if (reference_face_type == ReferenceCells::Triangle) new_quad->set_bounding_object_indices( @@ -5634,11 +5631,9 @@ namespace internal // TODO: faces of children have the same type as the faces // of the parent - triangulation.faces - ->quad_reference_cell[new_quad->index()] = - (reference_cell_type == ReferenceCells::Hexahedron) ? - ReferenceCells::Quadrilateral : - ReferenceCells::Triangle; + triangulation.faces->set_quad_type( + new_quad->index(), + reference_cell_type.face_reference_cell(0)); AssertIsNotUsed(new_quad); new_quad->set_used_flag(); diff --git a/source/grid/tria_faces.cc b/source/grid/tria_faces.cc index a747850864..ac0c9271a1 100644 --- a/source/grid/tria_faces.cc +++ b/source/grid/tria_faces.cc @@ -39,7 +39,7 @@ namespace internal if (dim == 3) return (MemoryConsumption::memory_consumption(quads) + MemoryConsumption::memory_consumption(quads_line_orientations) + - MemoryConsumption::memory_consumption(quad_reference_cell) + + MemoryConsumption::memory_consumption(quad_is_quadrilateral) + MemoryConsumption::memory_consumption(lines)); return 0; -- 2.39.5