Chi-Tech
unpartmesh_00a_general.cc
Go to the documentation of this file.
2
3#include "mesh/Cell/cell.h"
4
5#include "chi_runtime.h"
6#include "chi_log.h"
7
8#include "utils/chi_timer.h"
9
10/**Destructor.*/
12{
13 for (auto& cell : raw_cells_)
14 delete cell;
15 for (auto& cell : raw_boundary_cells_)
16 delete cell;
17 Chi::log.Log0Verbose1() << "Unpartitioned Mesh destructor called";
18}
19
20/**Compute centroids for all cells.*/
22{
23 const chi_mesh::Vector3 khat(0.0, 0.0, 1.0);
24
25 Chi::log.Log0Verbose1() << "Computing cell-centroids.";
26 for (auto cell : raw_cells_)
27 {
28 cell->centroid = chi_mesh::Vertex(0.0, 0.0, 0.0);
29 for (auto vid : cell->vertex_ids)
30 cell->centroid += vertices_[vid];
31
32 cell->centroid =
33 cell->centroid / static_cast<double>(cell->vertex_ids.size());
34 }
35 Chi::log.Log0Verbose1() << "Done computing cell-centroids.";
36
37 Chi::log.Log0Verbose1() << "Checking cell-center-to-face orientations";
38 size_t num_negative_volume_elements = 0;
39 for (auto cell : raw_cells_)
40 {
41 if (cell->type == CellType::POLYGON)
42 {
43 // Form triangles
44 size_t num_verts = cell->vertex_ids.size();
45 for (size_t v = 0; v < num_verts; ++v)
46 {
47 size_t vp1 = (v < (num_verts - 1)) ? v + 1 : 0;
48
49 const auto& v0 = vertices_[cell->vertex_ids[v]];
50 const auto& v1 = vertices_[cell->vertex_ids[vp1]];
51
52 auto E01 = v1 - v0;
53 auto n = E01.Cross(khat).Normalized();
54
55 if (n.Dot(v0 - cell->centroid) < 0.0) ++num_negative_volume_elements;
56 } // for v
57 }
58 else if (cell->type == CellType::POLYHEDRON)
59 {
60 for (auto& face : cell->faces)
61 {
62 if (face.vertex_ids.size() < 2)
63 throw std::logic_error(std::string(__PRETTY_FUNCTION__) +
64 ": cell-center-to-face check encountered face "
65 "with less than 2 vertices on a face, making "
66 "normal computation impossible.");
67
68 // Compute centroid
69 chi_mesh::Vector3 face_centroid;
70 for (uint64_t vid : face.vertex_ids)
71 face_centroid += vertices_[vid];
72 face_centroid /= static_cast<double>(face.vertex_ids.size());
73
74 // Form tets for each face edge
75 size_t num_face_verts = face.vertex_ids.size();
76 for (size_t fv = 0; fv < face.vertex_ids.size(); ++fv)
77 {
78 size_t fvp1 = (fv < (num_face_verts - 1)) ? fv + 1 : 0;
79
80 const auto& fv1 = vertices_[face.vertex_ids[fv]];
81 const auto& fv2 = vertices_[face.vertex_ids[fvp1]];
82
83 auto E0 = fv1 - face_centroid;
84 auto E1 = fv2 - face_centroid;
85 auto n = E0.Cross(E1).Normalized();
86
87 if (n.Dot(fv1 - cell->centroid) < 0.0) ++num_negative_volume_elements;
88 }
89 } // for face
90 } // if polyhedron
91 } // for cell in raw_cells
92
93 Chi::log.Log0Verbose1() << "Checking face sizes";
94 size_t cell_id = 0;
95 for (auto cell : raw_cells_)
96 {
97 if (cell->type == CellType::POLYGON)
98 {
99 size_t f = 0;
100 for (const auto& face : cell->faces)
101 {
102 const auto& v0 = vertices_.at(face.vertex_ids[0]);
103 const auto& v1 = vertices_.at(face.vertex_ids[1]);
104 ChiLogicalErrorIf((v1 - v0).Norm() < 1.0e-12,
105 "Cell " + std::to_string(cell_id) + " (centroid=" +
106 cell->centroid.PrintStr() + ") face " +
107 std::to_string(f) + ": Face has length < 1.0e-12.");
108 ++f;
109 }
110 } // if polygon
111 if (cell->type == CellType::POLYHEDRON)
112 {
113 size_t f = 0;
114 for (const auto& face : cell->faces)
115 {
116 size_t num_face_verts = face.vertex_ids.size();
117 for (size_t s = 0; s < face.vertex_ids.size(); ++s)
118 {
119 size_t fvp1 = (s < (num_face_verts - 1)) ? s + 1 : 0;
120
121 const auto& v0 = vertices_.at(face.vertex_ids[s]);
122 const auto& v1 = vertices_.at(face.vertex_ids[fvp1]);
123
124 ChiLogicalErrorIf((v1 - v0).Norm() < 1.0e-12,
125 "Cell " + std::to_string(cell_id) + " (centroid=" +
126 cell->centroid.PrintStr() + ") face " +
127 std::to_string(f) + " side " + std::to_string(s) +
128 ": Side has length < 1.0e-12.");
129 }
130
131 ++f;
132 }
133 } // if polyhedron
134 ++cell_id;
135 } // for cell in raw_cells
136
137 if (num_negative_volume_elements > 0)
139 << "Cell quality checks detected " << num_negative_volume_elements
140 << " negative volume sub-elements (sub-triangle or sub-tetrahedron)."
141 << " This issue could result in incorrect quantities"
142 << " under some circumstances.";
143 Chi::log.Log() << "Done checking cell-center-to-face orientations";
144}
145
146// ##################################################################
147/**Makes or gets a boundary that uniquely identifies the given name.*/
148uint64_t
149chi_mesh::UnpartitionedMesh::MakeBoundaryID(const std::string& boundary_name)
150{
151 auto& boundary_id_map = mesh_options_.boundary_id_map;
152 if (boundary_id_map.empty()) return 0;
153
154 for (const auto& [id, name] : boundary_id_map)
155 if (boundary_name == name) return id;
156
157 uint64_t max_id = 0;
158 for (const auto& [id, name] : boundary_id_map)
159 max_id = std::max(id, max_id);
160
161 return max_id + 1;
162}
163
164// ##################################################################
166 std::array<size_t, 3> ortho_Nis)
167{
168 attributes_ = attributes_ | new_attribs;
169 mesh_options_.ortho_Nx = ortho_Nis[0];
170 mesh_options_.ortho_Ny = ortho_Nis[1];
171 mesh_options_.ortho_Nz = ortho_Nis[2];
172}
#define ChiLogicalErrorIf(condition, message)
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
LogStream LogAllWarning()
Definition: chi_log.h:238
LogStream Log0Verbose1()
Definition: chi_log.h:234
void SetAttributes(MeshAttributes new_attribs, std::array< size_t, 3 > ortho_Nis={0, 0, 0})
std::vector< LightWeightCell * > raw_cells_
std::vector< LightWeightCell * > raw_boundary_cells_
uint64_t MakeBoundaryID(const std::string &boundary_name)
MeshAttributes
Definition: chi_mesh.h:70
Vector3 Vertex
Definition: chi_mesh.h:20
Vector3 Cross(const Vector3 &that) const
Vector3 Normalized() const