OGS
anonymous_namespace{SubmeshResiduumOutputConfig.cpp} Namespace Reference

Functions

std::vector< std::reference_wrapper< MeshLib::Mesh > > filterMeshesForResiduumOutput (std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes, std::vector< std::string > const &mesh_names_for_output)
void checkBulkIDMappingsPresent (MeshLib::Mesh const &mesh)
void checkMatchingElementCounts (MeshLib::Mesh const &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submesh_refs)
std::vector< bool > computeNonOverlappingBulkMeshCoverBySubmeshes (MeshLib::Mesh const &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submesh_refs)
void checkNonOverlappingCover (MeshLib::Mesh const &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submesh_refs)

Function Documentation

◆ checkBulkIDMappingsPresent()

void anonymous_namespace{SubmeshResiduumOutputConfig.cpp}::checkBulkIDMappingsPresent ( MeshLib::Mesh const & mesh)

Definition at line 48 of file SubmeshResiduumOutputConfig.cpp.

49{
50 auto const& properties = mesh.getProperties();
51
52 if (!properties.existsPropertyVector<std::size_t>(
55 {
57 "The required nodal property '{}' is missing in mesh '{}' or has "
58 "the wrong data type or the wrong number of components",
60 mesh.getName());
61 }
62
63 if (!properties.existsPropertyVector<std::size_t>(
66 {
68 "The required cell property '{}' is missing in mesh '{}' or has "
69 "the wrong data type or the wrong number of components",
71 mesh.getName());
72 }
73}
#define OGS_FATAL(...)
Definition Error.h:10
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)

References MeshLib::Cell, MeshLib::getBulkIDString(), MeshLib::Mesh::getName(), MeshLib::Mesh::getProperties(), MeshLib::Node, and OGS_FATAL.

◆ checkMatchingElementCounts()

void anonymous_namespace{SubmeshResiduumOutputConfig.cpp}::checkMatchingElementCounts ( MeshLib::Mesh const & bulk_mesh,
std::vector< std::reference_wrapper< MeshLib::Mesh > > const & submesh_refs )

Definition at line 75 of file SubmeshResiduumOutputConfig.cpp.

78{
79 auto const n_elements_bulk = bulk_mesh.getNumberOfElements();
80 auto const sum_elements_submeshes = [&submesh_refs]()
81 {
82 std::size_t n = 0;
83 for (auto const& submesh_ref : submesh_refs)
84 {
85 n += submesh_ref.get().getNumberOfElements();
86 }
87 return n;
88 }();
89
90 if (n_elements_bulk != sum_elements_submeshes)
91 {
93 "The number of bulk mesh elements does not match the sum of all "
94 "submesh elements: {} != {}. Hence, the set of all submeshes "
95 "cannot be a non-overlapping cover of the bulk mesh.",
96 n_elements_bulk, sum_elements_submeshes);
97 }
98}

References MeshLib::Mesh::getNumberOfElements(), and OGS_FATAL.

Referenced by checkNonOverlappingCover().

◆ checkNonOverlappingCover()

void anonymous_namespace{SubmeshResiduumOutputConfig.cpp}::checkNonOverlappingCover ( MeshLib::Mesh const & bulk_mesh,
std::vector< std::reference_wrapper< MeshLib::Mesh > > const & submesh_refs )

Definition at line 160 of file SubmeshResiduumOutputConfig.cpp.

163{
164 checkMatchingElementCounts(bulk_mesh, submesh_refs);
165
166 auto const n_elements_bulk = bulk_mesh.getNumberOfElements();
167
168 std::vector<bool> const bulk_element_covered =
169 computeNonOverlappingBulkMeshCoverBySubmeshes(bulk_mesh, submesh_refs);
170
171 auto const n_elements_covered =
172 std::accumulate(bulk_element_covered.begin(),
173 bulk_element_covered.end(), std::size_t{0});
174
175 if (n_elements_covered == n_elements_bulk)
176 {
177 return;
178 }
179
180 // search first bulk element that has not been covered
181 auto const non_covered_it = std::find(bulk_element_covered.begin(),
182 bulk_element_covered.end(), false);
183 auto const non_covered_index =
184 std::distance(bulk_element_covered.begin(), non_covered_it);
185
186 OGS_FATAL(
187 "The bulk mesh ('{}') is not covered completely by the given "
188 "submeshes. Only {} out of {} elements are covered. The first element "
189 "that is not covered is #{}.",
190 bulk_mesh.getName(), n_elements_covered, n_elements_bulk,
191 non_covered_index);
192}
void checkMatchingElementCounts(MeshLib::Mesh const &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submesh_refs)
std::vector< bool > computeNonOverlappingBulkMeshCoverBySubmeshes(MeshLib::Mesh const &bulk_mesh, std::vector< std::reference_wrapper< MeshLib::Mesh > > const &submesh_refs)

References checkMatchingElementCounts(), computeNonOverlappingBulkMeshCoverBySubmeshes(), MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfElements(), and OGS_FATAL.

◆ computeNonOverlappingBulkMeshCoverBySubmeshes()

std::vector< bool > anonymous_namespace{SubmeshResiduumOutputConfig.cpp}::computeNonOverlappingBulkMeshCoverBySubmeshes ( MeshLib::Mesh const & bulk_mesh,
std::vector< std::reference_wrapper< MeshLib::Mesh > > const & submesh_refs )

Definition at line 100 of file SubmeshResiduumOutputConfig.cpp.

103{
104 auto const n_elements_bulk = bulk_mesh.getNumberOfElements();
105
106 std::vector<bool> bulk_element_covered(n_elements_bulk);
107
108 for (auto const& submesh_ref : submesh_refs)
109 {
110 auto const& submesh = submesh_ref.get();
111 auto const& bulk_element_ids = bulkElementIDs(submesh);
112 if (bulk_element_ids == nullptr)
113 {
114 OGS_FATAL(
115 "The 'bulk_element_ids' property does not exist on the submesh "
116 "{:s}.",
117 submesh.getName());
118 }
119
120 if (bulk_element_ids->size() != submesh.getNumberOfElements())
121 {
122 OGS_FATAL(
123 "There is something terribly wrong with the mesh '{}'. The "
124 "size of 'bulk_element_ids' does not equal the number of "
125 "elements in the mesh: {} != {}",
126 submesh.getName(), bulk_element_ids->size(),
127 submesh.getNumberOfElements());
128 }
129
130 for (auto const bulk_element_id : *bulk_element_ids)
131 {
132 // meshes are provided as user input, so we better check the bounds
133 // of the contained data
134 [[unlikely]] if (bulk_element_id >= n_elements_bulk)
135 {
136 OGS_FATAL(
137 "Saw bulk element id {} in submesh '{}', but the bulk mesh "
138 "('{}') has only {} elements, i.e., the maximum allowed "
139 "bulk element id is {}.",
140 bulk_element_id, submesh.getName(), bulk_mesh.getName(),
141 n_elements_bulk, n_elements_bulk - 1);
142 }
143
144 [[unlikely]] if (bulk_element_covered[bulk_element_id])
145 {
146 OGS_FATAL(
147 "The bulk element id {} has already been covered by "
148 "another submesh. The second submesh covering this bulk "
149 "element is '{}'.",
150 bulk_element_id, submesh.getName());
151 }
152
153 bulk_element_covered[bulk_element_id] = true;
154 }
155 }
156
157 return bulk_element_covered;
158}

References MeshLib::Mesh::getName(), MeshLib::Mesh::getNumberOfElements(), and OGS_FATAL.

Referenced by checkNonOverlappingCover().

◆ filterMeshesForResiduumOutput()

std::vector< std::reference_wrapper< MeshLib::Mesh > > anonymous_namespace{SubmeshResiduumOutputConfig.cpp}::filterMeshesForResiduumOutput ( std::vector< std::unique_ptr< MeshLib::Mesh > > const & meshes,
std::vector< std::string > const & mesh_names_for_output )

Definition at line 17 of file SubmeshResiduumOutputConfig.cpp.

20{
21 std::map<std::string, std::reference_wrapper<MeshLib::Mesh>>
22 map_mesh_name_to_mesh;
23 for (auto const& mesh : meshes)
24 {
25 auto const [it, inserted] =
26 map_mesh_name_to_mesh.emplace(mesh->getName(), *mesh);
27
28 if (!inserted)
29 {
30 OGS_FATAL("Duplicate mesh name '{}' detected.", mesh->getName());
31 }
32 }
33
34 std::vector<std::reference_wrapper<MeshLib::Mesh>> meshes_filtered;
35
36 for (auto const& mesh_name : mesh_names_for_output)
37 {
38 auto const& mesh = BaseLib::getOrError(
39 map_mesh_name_to_mesh, mesh_name,
40 "A mesh that has been requested for output is not known to OGS.");
41
42 meshes_filtered.push_back(mesh);
43 }
44
45 return meshes_filtered;
46}
OGS_NO_DANGLING Map::mapped_type & getOrError(Map &map, Key const &key, std::string const &error_message)
Definition Algorithm.h:112

References BaseLib::getOrError(), and OGS_FATAL.