26 for (
auto cell : raw_cells_)
29 for (
auto vid : cell->vertex_ids)
30 cell->centroid += vertices_[vid];
33 cell->centroid /
static_cast<double>(cell->vertex_ids.size());
38 size_t num_negative_volume_elements = 0;
39 for (
auto cell : raw_cells_)
44 size_t num_verts = cell->vertex_ids.size();
45 for (
size_t v = 0; v < num_verts; ++v)
47 size_t vp1 = (v < (num_verts - 1)) ? v + 1 : 0;
49 const auto& v0 = vertices_[cell->vertex_ids[v]];
50 const auto& v1 = vertices_[cell->vertex_ids[vp1]];
53 auto n = E01.Cross(khat).Normalized();
55 if (n.Dot(v0 - cell->centroid) < 0.0) ++num_negative_volume_elements;
60 for (
auto& face : cell->faces)
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.");
70 for (uint64_t vid : face.vertex_ids)
71 face_centroid += vertices_[vid];
72 face_centroid /=
static_cast<double>(face.vertex_ids.size());
75 size_t num_face_verts = face.vertex_ids.size();
76 for (
size_t fv = 0; fv < face.vertex_ids.size(); ++fv)
78 size_t fvp1 = (fv < (num_face_verts - 1)) ? fv + 1 : 0;
80 const auto& fv1 = vertices_[face.vertex_ids[fv]];
81 const auto& fv2 = vertices_[face.vertex_ids[fvp1]];
83 auto E0 = fv1 - face_centroid;
84 auto E1 = fv2 - face_centroid;
87 if (n.Dot(fv1 - cell->centroid) < 0.0) ++num_negative_volume_elements;
95 for (
auto cell : raw_cells_)
100 for (
const auto& face : cell->faces)
102 const auto& v0 = vertices_.at(face.vertex_ids[0]);
103 const auto& v1 = vertices_.at(face.vertex_ids[1]);
105 "Cell " + std::to_string(cell_id) +
" (centroid=" +
106 cell->centroid.PrintStr() +
") face " +
107 std::to_string(f) +
": Face has length < 1.0e-12.");
114 for (
const auto& face : cell->faces)
116 size_t num_face_verts = face.vertex_ids.size();
117 for (
size_t s = 0; s < face.vertex_ids.size(); ++s)
119 size_t fvp1 = (s < (num_face_verts - 1)) ? s + 1 : 0;
121 const auto& v0 = vertices_.at(face.vertex_ids[s]);
122 const auto& v1 = vertices_.at(face.vertex_ids[fvp1]);
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.");
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";
151 auto& boundary_id_map = mesh_options_.boundary_id_map;
152 if (boundary_id_map.empty())
return 0;
154 for (
const auto& [
id, name] : boundary_id_map)
155 if (boundary_name == name)
return id;
158 for (
const auto& [
id, name] : boundary_id_map)
159 max_id = std::max(
id, max_id);
166 std::array<size_t, 3> ortho_Nis)
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];
#define ChiLogicalErrorIf(condition, message)
LogStream Log(LOG_LVL level=LOG_0)
LogStream LogAllWarning()
void ComputeCentroidsAndCheckQuality()
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)
Vector3 Cross(const Vector3 &that) const
Vector3 Normalized() const