From: David Wells Date: Sun, 5 Jan 2025 18:10:20 +0000 (-0500) Subject: Add ReferenceCell::max_n_vertices(). X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ffe4dccd9a97c1e94a4f0e636c0bce8896962ef;p=dealii.git Add ReferenceCell::max_n_vertices(). Like the other max functions, this helps us semantically disambiguate between a maximum value and the hypercube value. I had to add more preprocessor checks to work around Windows Server 2019's MSVC's problems with boost. I'm not sure when GitHub will start removing support for that OS, but it may be soon: it entered extended support a year ago [1]. I think we should just leave these preprocessor defines until we retire support for that OS, which may be after the next release. [1] https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2019 --- diff --git a/include/deal.II/fe/mapping.h b/include/deal.II/fe/mapping.h index e578c85354..7681b7765d 100644 --- a/include/deal.II/fe/mapping.h +++ b/include/deal.II/fe/mapping.h @@ -349,7 +349,12 @@ public: * cell-@>vertex(v). */ virtual boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices( const typename Triangulation::cell_iterator &cell) const; @@ -362,7 +367,12 @@ public: * @param[in] face_no The number of the face within the cell. */ boost::container::small_vector, - GeometryInfo::vertices_per_face> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices(const typename Triangulation::cell_iterator &cell, const unsigned int face_no) const; diff --git a/include/deal.II/fe/mapping_fe_field.h b/include/deal.II/fe/mapping_fe_field.h index 574999ee65..1926de6bb7 100644 --- a/include/deal.II/fe/mapping_fe_field.h +++ b/include/deal.II/fe/mapping_fe_field.h @@ -170,7 +170,12 @@ public: * that was passed at construction time. */ virtual boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices(const typename Triangulation::cell_iterator &cell) const override; diff --git a/include/deal.II/fe/mapping_q1_eulerian.h b/include/deal.II/fe/mapping_q1_eulerian.h index 0bf4e6a9f9..7810f86ee9 100644 --- a/include/deal.II/fe/mapping_q1_eulerian.h +++ b/include/deal.II/fe/mapping_q1_eulerian.h @@ -118,7 +118,12 @@ public: * addition to the geometry of the cell. */ virtual boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices(const typename Triangulation::cell_iterator &cell) const override; diff --git a/include/deal.II/fe/mapping_q_cache.h b/include/deal.II/fe/mapping_q_cache.h index 99dfaf3020..a7a6398af7 100644 --- a/include/deal.II/fe/mapping_q_cache.h +++ b/include/deal.II/fe/mapping_q_cache.h @@ -195,7 +195,12 @@ public: * @copydoc Mapping::get_vertices() */ virtual boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices(const typename Triangulation::cell_iterator &cell) const override; diff --git a/include/deal.II/fe/mapping_q_eulerian.h b/include/deal.II/fe/mapping_q_eulerian.h index 4ca9953b03..f6355b8673 100644 --- a/include/deal.II/fe/mapping_q_eulerian.h +++ b/include/deal.II/fe/mapping_q_eulerian.h @@ -122,7 +122,12 @@ public: * addition to the geometry of the cell. */ virtual boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > get_vertices(const typename Triangulation::cell_iterator &cell) const override; diff --git a/include/deal.II/grid/reference_cell.h b/include/deal.II/grid/reference_cell.h index 64268f40a6..98b363a0cf 100644 --- a/include/deal.II/grid/reference_cell.h +++ b/include/deal.II/grid/reference_cell.h @@ -285,6 +285,17 @@ public: unsigned int n_vertices() const; + /** + * Return the maximum number of vertices an object of dimension `structdim` + * can have. This is always the number of vertices of a + * `structdim`-dimensional hypercube. + * + * @see ReferenceCell::max_n_faces() + */ + template + static constexpr unsigned int + max_n_vertices(); + /** * Return an object that can be thought of as an array containing all * indices from zero to n_vertices(). @@ -1591,6 +1602,15 @@ ReferenceCell::n_vertices() const +template +inline constexpr unsigned int +ReferenceCell::max_n_vertices() +{ + return GeometryInfo::vertices_per_cell; +} + + + inline unsigned int ReferenceCell::n_lines() const { diff --git a/include/deal.II/grid/tria_accessor.h b/include/deal.II/grid/tria_accessor.h index b3ea594ba4..6807698128 100644 --- a/include/deal.II/grid/tria_accessor.h +++ b/include/deal.II/grid/tria_accessor.h @@ -5311,9 +5311,8 @@ TriaAccessor::vertex_index( { // This branch should only be used after the cell vertex index cache is // set up - constexpr unsigned int max_vertices_per_cell = 1 << dim; - const std::size_t my_index = - static_cast(this->present_index) * max_vertices_per_cell; + const auto my_index = static_cast(this->present_index) * + ReferenceCell::max_n_vertices(); AssertIndexRange(my_index + corner, this->tria->levels[this->present_level] ->cell_vertex_indices_cache.size()); @@ -6347,7 +6346,12 @@ double TriaAccessor::diameter() const { boost::container::small_vector, - GeometryInfo::vertices_per_cell> +# ifndef _MSC_VER + ReferenceCell::max_n_vertices() +# else + GeometryInfo::vertices_per_cell +# endif + > vertices(this->n_vertices()); for (unsigned int v = 0; v < vertices.size(); ++v) diff --git a/source/fe/mapping.cc b/source/fe/mapping.cc index c7fb0891e2..a6386f89d4 100644 --- a/source/fe/mapping.cc +++ b/source/fe/mapping.cc @@ -34,12 +34,22 @@ DEAL_II_NAMESPACE_OPEN template boost::container::small_vector, - GeometryInfo::vertices_per_cell> +# ifndef _MSC_VER + ReferenceCell::max_n_vertices() +# else + GeometryInfo::vertices_per_cell +# endif + > Mapping::get_vertices( const typename Triangulation::cell_iterator &cell) const { boost::container::small_vector, - GeometryInfo::vertices_per_cell> +# ifndef _MSC_VER + ReferenceCell::max_n_vertices() +# else + GeometryInfo::vertices_per_cell +# endif + > vertices; for (const unsigned int i : cell->vertex_indices()) vertices.push_back(cell->vertex(i)); @@ -51,13 +61,23 @@ Mapping::get_vertices( template boost::container::small_vector, - GeometryInfo::vertices_per_face> +# ifndef _MSC_VER + ReferenceCell::max_n_vertices() +# else + GeometryInfo::vertices_per_cell +# endif + > Mapping::get_vertices( const typename Triangulation::cell_iterator &cell, const unsigned int face_no) const { boost::container::small_vector, - GeometryInfo::vertices_per_face> +# ifndef _MSC_VER + ReferenceCell::max_n_vertices() +# else + GeometryInfo::vertices_per_cell +# endif + > face_vertices; const auto &cell_vertices = get_vertices(cell); diff --git a/source/fe/mapping_fe_field.cc b/source/fe/mapping_fe_field.cc index 4711207f28..58d9f8f0cb 100644 --- a/source/fe/mapping_fe_field.cc +++ b/source/fe/mapping_fe_field.cc @@ -447,7 +447,12 @@ MappingFEField::is_compatible_with( template boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > MappingFEField::get_vertices( const typename Triangulation::cell_iterator &cell) const { @@ -485,7 +490,12 @@ MappingFEField::get_vertices( uses_level_dofs ? *euler_vector[cell->level()] : *euler_vector[0]; boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > vertices(cell->n_vertices()); for (unsigned int i = 0; i < dofs_per_cell; ++i) { diff --git a/source/fe/mapping_q.cc b/source/fe/mapping_q.cc index 734fb98646..55c2fe6aee 100644 --- a/source/fe/mapping_q.cc +++ b/source/fe/mapping_q.cc @@ -642,7 +642,12 @@ MappingQ::transform_points_real_to_unit_cell( AssertDimension(real_points.size(), unit_points.size()); std::vector> support_points_higher_order; boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > vertices; if (polynomial_degree == 1) vertices = this->get_vertices(cell); diff --git a/source/fe/mapping_q1_eulerian.cc b/source/fe/mapping_q1_eulerian.cc index 0bd74b6c7d..79358a1ccb 100644 --- a/source/fe/mapping_q1_eulerian.cc +++ b/source/fe/mapping_q1_eulerian.cc @@ -49,13 +49,23 @@ MappingQ1Eulerian::MappingQ1Eulerian( template boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > MappingQ1Eulerian::get_vertices( const typename Triangulation::cell_iterator &cell) const { boost::container::small_vector, - GeometryInfo::vertices_per_cell> - vertices(GeometryInfo::vertices_per_cell); +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > + vertices(cell->n_vertices()); // The assertions can not be in the constructor, since this would // require to call dof_handler.distribute_dofs(fe) *before* the mapping // object is constructed, which is not necessarily what we want. diff --git a/source/fe/mapping_q_cache.cc b/source/fe/mapping_q_cache.cc index 750a9602d1..52f0bca873 100644 --- a/source/fe/mapping_q_cache.cc +++ b/source/fe/mapping_q_cache.cc @@ -728,7 +728,12 @@ MappingQCache::compute_mapping_support_points( template boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > MappingQCache::get_vertices( const typename Triangulation::cell_iterator &cell) const { @@ -742,8 +747,12 @@ MappingQCache::get_vertices( AssertIndexRange(cell->index(), (*support_point_cache)[cell->level()].size()); const auto ptr = (*support_point_cache)[cell->level()][cell->index()].begin(); return boost::container::small_vector, - GeometryInfo::vertices_per_cell>( - ptr, ptr + cell->n_vertices()); +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + >(ptr, ptr + cell->n_vertices()); } diff --git a/source/fe/mapping_q_eulerian.cc b/source/fe/mapping_q_eulerian.cc index 63267c1f26..3569730fd1 100644 --- a/source/fe/mapping_q_eulerian.cc +++ b/source/fe/mapping_q_eulerian.cc @@ -99,7 +99,12 @@ MappingQEulerian::SupportQuadrature:: template boost::container::small_vector, - GeometryInfo::vertices_per_cell> +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > MappingQEulerian::get_vertices( const typename Triangulation::cell_iterator &cell) const { @@ -107,9 +112,13 @@ MappingQEulerian::get_vertices( const std::vector> a = compute_mapping_support_points(cell); boost::container::small_vector, - GeometryInfo::vertices_per_cell> - vertex_locations(a.begin(), - a.begin() + GeometryInfo::vertices_per_cell); +#ifndef _MSC_VER + ReferenceCell::max_n_vertices() +#else + GeometryInfo::vertices_per_cell +#endif + > + vertex_locations(a.begin(), a.begin() + cell->n_vertices()); return vertex_locations; } diff --git a/source/grid/tria.cc b/source/grid/tria.cc index 90f9b684e3..109da0ad42 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -3498,7 +3498,7 @@ namespace internal [[maybe_unused]] unsigned int counter = 0; std::vector key; - key.reserve(GeometryInfo::vertices_per_cell); + key.reserve(ReferenceCell::max_n_vertices()); for (unsigned int o = 0; o < obj.n_objects(); ++o) { @@ -15953,14 +15953,15 @@ void Triangulation::reset_cell_vertex_indices_cache() { for (unsigned int l = 0; l < levels.size(); ++l) { - constexpr unsigned int max_vertices_per_cell = 1 << dim; std::vector &cache = levels[l]->cell_vertex_indices_cache; cache.clear(); - cache.resize(levels[l]->refine_flags.size() * max_vertices_per_cell, + cache.resize(levels[l]->refine_flags.size() * + ReferenceCell::max_n_vertices(), numbers::invalid_unsigned_int); for (const auto &cell : cell_iterators_on_level(l)) { - const unsigned int my_index = cell->index() * max_vertices_per_cell; + const unsigned int my_index = + cell->index() * ReferenceCell::max_n_vertices(); // to reduce the cost of this function when passing down into quads, // then lines, then vertices, we use a more low-level access method