LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
tp_quad_mesh_builder.cc
1#include "tp_quad_mesh_builder.h"
2
3#include <lf/geometry/geometry.h>
4#include <spdlog/spdlog.h>
5
6#include <iostream>
7
8#include "lf/mesh/mesh_interface.h"
9
10namespace lf::mesh::utils {
11
12std::shared_ptr<spdlog::logger>& TPQuadMeshBuilder::Logger() {
13 static auto logger =
14 base::InitLogger("lf::mesh::utils::TPQuadMeshBuilder::Logger");
15 return logger;
16}
17
18std::shared_ptr<mesh::Mesh> TPQuadMeshBuilder::Build() {
19 using coord_t = Eigen::Vector2d;
20 const size_type nx = num_of_x_cells_;
21 const size_type ny = num_of_y_cells_;
22 // Total number of entities in the mesh
23 // Each triangle is split into two squares
24 const unsigned no_of_cells = nx * ny; // no of rectangles
25 const unsigned no_of_edges = (nx + 1) * ny + nx * (ny + 1);
26 const unsigned no_of_vertices = (nx + 1) * (ny + 1);
27 // No mesh to build
28 if (no_of_cells == 0) {
29 return nullptr;
30 }
31 // define rectangle; return if none
32 const double x_size = top_right_corner_[0] - bottom_left_corner_[0];
33 const double y_size = top_right_corner_[1] - bottom_left_corner_[1];
34 if ((x_size <= 0.0) || (y_size <= 0.0)) {
35 return nullptr;
36 }
37 // meshwidths
38 const double hx = x_size / nx;
39 const double hy = y_size / ny;
40
41 SPDLOG_LOGGER_DEBUG(
42 Logger(),
43 "TPQuadmesh: {} cells, {} edges, {} vertices, meshwidths hx/hy = {}/{}",
44 no_of_cells, no_of_edges, no_of_vertices, hx, hy);
45
46 // Initialize vertices
47 std::vector<size_type> v_idx(no_of_vertices);
48 int node_cnt = 0; // index of current vertex: lexicographic numbering
49 for (size_type j = 0; j <= ny; ++j) {
50 for (size_type i = 0; i <= nx; ++i, ++node_cnt) {
51 // Tensor-product node locations
52 coord_t node_coord(2);
53 node_coord << bottom_left_corner_[0] + i * hx,
54 bottom_left_corner_[1] + j * hy;
55 // Diagnostics
56 SPDLOG_LOGGER_TRACE(Logger(), "Adding vertex {}: {}", node_cnt,
57 node_coord.transpose());
58
59 // Register vertex
60 v_idx[node_cnt] = mesh_factory_->AddPoint(node_coord);
61 }
62 }
63 // Set quadrilateral cells
64 // Index remapping for cells
65 std::vector<size_type> t_idx(no_of_cells);
66
67 size_type quad_cnt = 0; // index of current triangle
68 for (size_type i = 0; i < nx; ++i) {
69 for (size_type j = 0; j < ny; ++j, quad_cnt++) {
70 // Indices of vertices of quadrilateral (i,j)
71 std::vector<size_type> vertex_index_list{
72 v_idx[VertexIndex(i, j)], v_idx[VertexIndex(i + 1, j)],
73 v_idx[VertexIndex(i + 1, j + 1)], v_idx[VertexIndex(i, j + 1)]};
74 // Construct geometry of rectangle
75 Eigen::Matrix<double, 2, 4> quad_geo(2, 4);
76 quad_geo << bottom_left_corner_[0] + i * hx,
77 bottom_left_corner_[0] + (i + 1) * hx,
78 bottom_left_corner_[0] + (i + 1) * hx,
79 bottom_left_corner_[0] + i * hx, bottom_left_corner_[1] + j * hy,
80 bottom_left_corner_[1] + j * hy,
81 bottom_left_corner_[1] + (j + 1) * hy,
82 bottom_left_corner_[1] + (j + 1) * hy;
83 // Diagnostics
84 SPDLOG_LOGGER_TRACE(Logger(), "Adding quad {}:\n{}", quad_cnt, quad_geo);
85
86 // Request production of the cell from the MeshFactory
87 // Straight edges will be created as needed
88 t_idx[quad_cnt] = mesh_factory_->AddEntity(
89 lf::base::RefEl::kQuad(), vertex_index_list,
90 std::make_unique<geometry::QuadO1>(quad_geo));
91 }
92 }
93 return mesh_factory_->Build();
94}
95
96} // namespace lf::mesh::utils
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition: ref_el.h:166
std::unique_ptr< mesh::MeshFactory > mesh_factory_
std::shared_ptr< mesh::Mesh > Build() override
actual construction of the mesh
size_type VertexIndex(size_type i, size_type j) const
vertex index from grid position
static std::shared_ptr< spdlog::logger > & Logger()
is used by the Build() method to output additional information.
std::shared_ptr< spdlog::logger > InitLogger(const std::string &name)
Create a spdlog logger, register it in the spdlog registry and initialize it with LehrFEM++ specific ...
Definition: spdlog_utils.cc:16
Contains helper functions and classes that all operate on the interface classes defined in lf::mesh.