51 std::vector<MeshLib::Element*>
const all_bhe_elements =
56 DBUG(
"-> found total {:d} soil elements and {:d} BHE elements",
58 all_bhe_elements.size());
62 if (opt_material_ids ==
nullptr)
64 OGS_FATAL(
"Not able to get material IDs! ");
66 auto const& material_ids = *opt_material_ids;
68 auto const& bhe_material_ids =
69 getUniqueMaterialIds(material_ids, all_bhe_elements);
70 DBUG(
"-> found {:d} BHE material groups", bhe_material_ids.size());
73 std::vector<std::vector<MeshLib::Element*>> bhe_elements;
74 bhe_elements.resize(bhe_material_ids.size());
75 for (
unsigned bhe_id = 0; bhe_id < bhe_material_ids.size(); bhe_id++)
77 const auto bhe_mat_id = bhe_material_ids[bhe_id];
78 std::vector<MeshLib::Element*>& vec_elements = bhe_elements[bhe_id];
79 copy_if(begin(all_bhe_elements), end(all_bhe_elements),
80 back_inserter(vec_elements),
82 {
return material_ids[e->
getID()] == bhe_mat_id; });
83 DBUG(
"-> found {:d} elements on the BHE_{:d}", vec_elements.size(),
88 std::vector<std::vector<MeshLib::Node*>> bhe_nodes;
89 bhe_nodes.resize(bhe_material_ids.size());
90 for (
unsigned bhe_id = 0; bhe_id < bhe_material_ids.size(); bhe_id++)
92 std::vector<MeshLib::Node*>& vec_nodes = bhe_nodes[bhe_id];
95 for (
unsigned i = 0; i < e->getNumberOfNodes(); i++)
97 vec_nodes.push_back(
const_cast<MeshLib::Node*
>(e->getNode(i)));
103 DBUG(
"-> found {:d} nodes on the BHE_{:d}", vec_nodes.size(), bhe_id);
106 return {bhe_material_ids, bhe_elements, bhe_nodes};
110 std::vector<MeshLib::Element*>
const& bhe_elements)
112 if (bhe_elements.empty())
115 "findBHEEndpointsFromElementOrdering called with an empty BHE "
122 std::unordered_map<std::size_t, std::vector<std::pair<std::size_t, int>>>
124 for (std::size_t ei = 0; ei < bhe_elements.size(); ++ei)
126 auto const* e = bhe_elements[ei];
127 if (e->getNumberOfNodes() != 2)
130 "BHE element {:d} has {:d} nodes; expected a 2-node line "
132 e->getID(), e->getNumberOfNodes());
134 for (
int local = 0; local < 2; ++local)
136 adjacency[e->getNode(local)->getID()].emplace_back(ei, local);
143 std::vector<std::size_t> endpoint_node_ids;
144 for (
auto const& [nid, refs] : adjacency)
146 if (refs.size() == 1)
148 endpoint_node_ids.push_back(nid);
150 else if (refs.size() > 2)
153 "BHE element chain has a branching junction at node {:d} "
154 "(connected to {:d} elements). Expected a simple line chain.",
159 if (endpoint_node_ids.size() != 2)
162 "BHE elements do not form a single connected line chain (found "
163 "{:d} endpoints; expected 2). Check that all line elements with "
164 "the same BHE material ID share endpoints node-to-node.",
165 endpoint_node_ids.size());
174 for (std::size_t
const nid : endpoint_node_ids)
176 auto const& [ei, local] = adjacency[nid].front();
179 if (inlet !=
nullptr)
182 "Both BHE chain endpoints (nodes {:d} and {:d}) appear "
183 "as local node 0 of their connected element; chain "
184 "orientation is ambiguous. Reorder element nodes so the "
185 "chain runs node 0 -> node 1 from inlet to outlet.",
186 inlet->
getID(), nid);
188 inlet = bhe_elements[ei]->getNode(0);
192 outlet = bhe_elements[ei]->getNode(1);
196 if (inlet ==
nullptr || outlet ==
nullptr)
199 "BHE chain endpoints are not consistent with the elements' "
200 "node-0 -> node-1 ordering. Reorder element nodes so that the "
201 "intended inlet endpoint is node 0 of the chain-start element "
202 "and the intended outlet endpoint is node 1 of the chain-end "
209 std::vector<bool> used(bhe_elements.size(),
false);
211 for (std::size_t step = 0; step < bhe_elements.size(); ++step)
213 auto const& refs = adjacency[cur->
getID()];
214 bool advanced =
false;
215 for (
auto const& [ei, local] : refs)
217 if (!used[ei] && local == 0)
220 cur = bhe_elements[ei]->getNode(1);
228 "BHE element chain is inconsistently oriented at node {:d}: "
229 "an interior element does not have this node as its node 0. "
230 "Reorder the element's nodes so the chain runs node 0 -> "
231 "node 1 from inlet to outlet.",
239 "BHE chain walk did not terminate at the expected outlet "
240 "endpoint (expected node {:d}, reached node {:d}).",
244 return {inlet, outlet};