1#include "sphere_triag_mesh_builder.h"
3#include <lf/base/base.h>
4#include <lf/base/span.h>
5#include <lf/geometry/geometry.h>
24 2 + 4 * (ring_count / 2) +
25 4 * ((ring_count - 2) / 2 + 1) * ((ring_count - 2) / 2);
29 const double d_theta = M_PI / (ring_count - 1);
35 std::vector<std::pair<lf::base::size_type, lf::base::size_type>>
36 vertex_loc_glob_map_vector_cache(vertex_count, std::make_pair(0, 0));
43 LF_ASSERT_MSG(0 <= r_idx && r_idx < ring_count,
"ring index out of range");
44 if (r_idx <= (ring_count / 2)) {
47 return ring_count - r_idx - 1;
53 auto vert_count_on_ring =
55 LF_ASSERT_MSG(0 <= r_idx && r_idx < ring_count,
"ring index out of range");
56 if (r_tilde(r_idx) == 0) {
59 return r_tilde(r_idx) * 4;
71 -> std::pair<lf::base::size_type, lf::base::size_type> {
72 LF_ASSERT_MSG(0 <= v_idx && v_idx < vertex_count,
73 "vertex index out of range");
75 std::pair<lf::base::size_type, lf::base::size_type> zero_pair =
82 if (vertex_loc_glob_map_vector_cache[v_idx] == zero_pair) {
86 while (vert_count_on_ring(r_idx) <= v_idx_rest) {
87 v_idx_rest -= vert_count_on_ring(r_idx);
92 vertex_loc_glob_map_vector_cache[v_idx] =
93 std::make_pair(r_idx, v_idx_rest);
96 return vertex_loc_glob_map_vector_cache[v_idx];
104 auto global_vert_idx =
107 LF_ASSERT_MSG(0 <= r_idx && r_idx < ring_count,
"ring index out of range");
108 LF_ASSERT_MSG(0 <= v_local_idx && v_local_idx < vert_count_on_ring(r_idx),
109 "vertex index out of range");
113 v_idx += vert_count_on_ring(r);
115 v_idx += v_local_idx;
126 LF_ASSERT_MSG(0 <= r_idx && r_idx < ring_count,
"ring index out of range");
127 LF_ASSERT_MSG(0 <= v_idx && v_idx < vert_count_on_ring(r_idx),
128 "vertex index out of range");
129 const double theta = r_idx * d_theta;
130 const double d_phi = 2.0 * M_PI / vert_count_on_ring(r_idx);
131 const double phi = v_idx * d_phi;
133 pos << r * std::cos(phi) * std::sin(theta),
134 r * std::sin(phi) * std::sin(theta), r * std::cos(theta);
142 auto global_node_position =
144 LF_ASSERT_MSG(0 <= v_idx && v_idx < vertex_count,
145 "vertex index out of range");
148 std::tie(r_idx, v_local_idx) = local_vert_idx(v_idx);
149 return node_position(r_idx, v_local_idx);
159 LF_ASSERT_MSG(0 < r_idx && r_idx < ring_count,
"ring index out of range");
160 LF_ASSERT_MSG(0 <= v_idx && v_idx < vert_count_on_ring(r_idx),
161 "vertex index out of range");
163 return v_idx / num_v_per_quarter;
170 std::tie(r_idx, v_local_idx) = local_vert_idx(i);
180 std::tie(r_idx, v_local_idx) = local_vert_idx(i);
181 const int quarter = get_quarter(r_idx, v_local_idx);
187 if (vert_count_on_ring(r_idx) > vert_count_on_ring(r_idx - 1)) {
191 global_vert_idx(r_idx, (v_local_idx + 1) % vert_count_on_ring(r_idx));
192 v3 = global_vert_idx(
193 r_idx - 1, (v_local_idx - quarter) % vert_count_on_ring(r_idx - 1));
199 global_vert_idx(r_idx, (v_local_idx + 1) % vert_count_on_ring(r_idx));
200 v3 = global_vert_idx(r_idx - 1, v_local_idx + 1 + quarter);
203 const std::array<lf::base::size_type, 3> upper_trig = {v1, v2, v3};
205 Eigen::Matrix<double, 3, 3> upper_verts;
206 upper_verts << node_position(r_idx, v_local_idx), global_node_position(v2),
207 global_node_position(v3);
209 std::unique_ptr<lf::geometry::Geometry> upper_geom =
210 std::make_unique<lf::geometry::TriaO1>(upper_verts);
212 std::move(upper_geom));
214 if (vert_count_on_ring(r_idx) > vert_count_on_ring(r_idx + 1)) {
217 v2 = global_vert_idx(
218 r_idx + 1, (v_local_idx - quarter) % vert_count_on_ring(r_idx + 1));
220 global_vert_idx(r_idx, (v_local_idx + 1) % vert_count_on_ring(r_idx));
224 v2 = global_vert_idx(r_idx + 1, v_local_idx + 1 + quarter);
226 global_vert_idx(r_idx, (v_local_idx + 1) % vert_count_on_ring(r_idx));
229 const std::array<lf::base::size_type, 3> lower_trig = {v1, v2, v3};
231 Eigen::Matrix<double, 3, 3> lower_verts;
232 lower_verts << node_position(r_idx, v_local_idx), global_node_position(v2),
233 global_node_position(v3);
235 std::unique_ptr<lf::geometry::Geometry> lower_geom =
236 std::make_unique<lf::geometry::TriaO1>(lower_verts);
238 std::move(lower_geom));
Represents a reference element with all its properties.
static constexpr RefEl kTria()
Returns the reference triangle.
lf::base::size_type refinement_level_
std::unique_ptr< lf::mesh::MeshFactory > mesh_factory_
std::shared_ptr< lf::mesh::Mesh > Build()
Build the mesh.
unsigned int size_type
general type for variables related to size of arrays
Contains a generator for triangluations of the surface of the 3-sphere.