OGS
CreateHeatTransportBHEProcess.cpp
Go to the documentation of this file.
1
12
13#include <pybind11/pybind11.h>
14
15#include <algorithm>
16#include <map>
17#include <ranges>
18#include <vector>
19
20#include "BHE/BHETypes.h"
21#include "BHE/CreateBHE1PType.h"
23#include "BHE/CreateBHEUType.h"
27#include "ParameterLib/Utils.h"
30
31namespace ProcessLib
32{
33namespace HeatTransportBHE
34{
35std::map<std::string_view,
36 std::function<BHE::BHETypes(
38 std::map<std::string,
39 std::unique_ptr<
41 bheCreators = {{"1U",
42 [](auto& config, auto& curves) {
43 return BHE::BHE_1U(
44 BHE::createBHEUType<BHE::BHE_1U>(config, curves));
45 }},
46 {"2U",
47 [](auto& config, auto& curves) {
48 return BHE::BHE_2U(
49 BHE::createBHEUType<BHE::BHE_2U>(config, curves));
50 }},
51 {"CXA",
52 [](auto& config, auto& curves) {
54 config, curves));
55 }},
56 {"CXC",
57 [](auto& config, auto& curves) {
59 config, curves));
60 }},
61 {"1P", [](auto& config, auto& curves) {
62 return BHE::BHE_1P(
63 BHE::createBHE1PType<BHE::BHE_1P>(config, curves));
64 }}};
65
67 const std::string& bhe_type, const std::vector<int>& bhe_ids_of_this_bhe,
68 const BaseLib::ConfigTree& bhe_config,
69 std::map<std::string,
70 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
71 curves,
72 std::map<int, BHE::BHETypes>& bhes_map)
73{
74 auto bhe_creator_it = bheCreators.find(bhe_type);
75 if (bhe_creator_it == bheCreators.end())
76 {
77 OGS_FATAL("Unknown BHE type: {:s}", bhe_type);
78 }
79 for (auto const& id : bhe_ids_of_this_bhe)
80 {
81 std::pair<std::map<int, BHE::BHETypes>::iterator, bool> result;
82 if (id == bhe_ids_of_this_bhe[0])
83 {
84 result = bhes_map.try_emplace(
85 id, bhe_creator_it->second(bhe_config, curves));
86 }
87 else
88 {
89 result = bhes_map.try_emplace(
90 id, bhes_map.find(bhe_ids_of_this_bhe[0])->second);
91 }
92 if (!result.second)
93 {
95 "BHE with id '{:d}' is already present in the list! Check for "
96 "duplicate definitions of BHE ids.",
97 id);
98 }
99 }
100}
101
102std::unique_ptr<Process> createHeatTransportBHEProcess(
103 std::string const& name,
104 MeshLib::Mesh& mesh,
105 std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
106 std::vector<ProcessVariable> const& variables,
107 std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
108 unsigned const integration_order,
109 BaseLib::ConfigTree const& config,
110 std::map<std::string,
111 std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> const&
112 curves,
113 std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
114{
116 config.checkConfigParameter("type", "HEAT_TRANSPORT_BHE");
117
118 DBUG("Create HeatTransportBHE Process.");
119
121
123 auto const pv_config = config.getConfigSubtree("process_variables");
124 std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
125 process_variables;
126
127 // reading primary variables for each
128 // BHE----------------------------------------------------------
130 auto range =
132 pv_config.getConfigParameterList<std::string>("process_variable");
133 std::vector<std::reference_wrapper<ProcessVariable>> per_process_variables;
134
135 for (std::string const& pv_name : range)
136 {
137 if (pv_name != "temperature_soil" &&
138 pv_name.find("temperature_BHE") == std::string::npos)
139 {
140 OGS_FATAL(
141 "Found a process variable name '{}'. It should be "
142 "'temperature_soil' or 'temperature_BHE_X'",
143 pv_name);
144 }
145 auto variable = std::find_if(variables.cbegin(), variables.cend(),
146 [&pv_name](ProcessVariable const& v)
147 { return v.getName() == pv_name; });
148
149 if (variable == variables.end())
150 {
151 OGS_FATAL(
152 "Could not find process variable '{:s}' in the provided "
153 "variables list for config tag <{:s}>.",
154 pv_name, "process_variable");
155 }
156 DBUG("Found process variable '{:s}' for config tag <{:s}>.",
157 variable->getName(), "process_variable");
158
159 per_process_variables.emplace_back(
160 const_cast<ProcessVariable&>(*variable));
161 }
162 process_variables.push_back(std::move(per_process_variables));
163 // end of reading primary variables for each
164 // BHE----------------------------------------------------------
165
167 // reading BHE parameters --------------------------------------------------
168
169 auto bhe_mesh_data = getBHEDataInMesh(mesh);
170
171 auto const& bhe_configs =
173 config.getConfigSubtree("borehole_heat_exchangers");
174
175 auto const using_server_communication =
177 config.getConfigParameter<bool>("use_server_communication", false);
178
179 auto const mass_lumping =
181 config.getConfigParameter<bool>("mass_lumping", false);
182
183 auto const using_algebraic_bc =
185 config.getConfigParameter<bool>("use_algebraic_bc", false);
186
187 auto const weighting_factor =
189 config.getConfigParameter<float>("weighting_factor", 100.0);
190
191 auto const is_linear =
193 config.getConfigParameter<bool>("linear", false);
194 if (is_linear)
195 {
196 if (!using_algebraic_bc)
197 {
198 OGS_FATAL(
199 "You specified that the process simulated by OGS is linear. "
200 "For the Heat-Transport-BHE process this can only be done "
201 "together with setting the use_algebraic_bc option to true.")
202 }
203 else
204 {
205 WARN(
206 "You specified that the process simulated by OGS is linear. "
207 "With that optimization the process will be assembled only "
208 "once and the non-linear solver will do only one iteration per "
209 "time step. No non-linearities will be resolved and OGS will "
210 "not detect if there are any non-linearities. It is your "
211 "responsibility to ensure that the assembled equation systems "
212 "are linear, indeed! There is no safety net!");
213 }
214 }
215
216 std::map<int, BHE::BHETypes> bhes_map;
217
218 int bhe_iterator = 0;
219
220 for (
221 auto const& bhe_config :
223 bhe_configs.getConfigSubtreeList("borehole_heat_exchanger"))
224 {
225 auto bhe_id_string =
227 bhe_config.getConfigAttribute<std::string>(
228 "id", std::to_string(bhe_iterator));
229
230 std::vector<int> bhe_ids_of_this_bhe;
231
232 if (bhe_id_string == "*")
233 {
234 int size = static_cast<int>(bhe_mesh_data.BHE_mat_IDs.size());
235 bhe_ids_of_this_bhe.resize(size);
236 std::iota(bhe_ids_of_this_bhe.begin(), bhe_ids_of_this_bhe.end(),
237 0);
238 }
239 else
240 {
241 bhe_ids_of_this_bhe =
243 }
244
245 // read in the parameters
246 const std::string bhe_type =
248 bhe_config.getConfigParameter<std::string>("type");
249
250 createAndInsertBHE(bhe_type, bhe_ids_of_this_bhe, bhe_config, curves,
251 bhes_map);
252 bhe_iterator++;
253 }
254
255 if (static_cast<int>(bhes_map.size()) - 1 != bhes_map.rbegin()->first)
256 {
257 OGS_FATAL(
258 "The maximum given BHE id '{:d}' did not match the number of given "
259 "BHE definitions '{:d}'. The BHE ids needs to be defined starting "
260 "from 0, so the maximum BHE id needs to be number of BHE "
261 "definitions minus 1. After all definitions there are no gaps "
262 "allowed between the given ids.",
263 bhes_map.rbegin()->first, bhes_map.size());
264 }
265
266 std::vector<BHE::BHETypes> bhes;
267 bhes.reserve(bhes_map.size());
268 std::ranges::copy(bhes_map | std::views::values, std::back_inserter(bhes));
269 // end of reading BHE parameters
270 // -------------------------------------------
271
272 auto media_map =
274
275 // find if bhe uses python boundary condition
276 auto const using_tespy =
277 visit([](auto const& bhe) { return bhe.use_python_bcs; }, bhes[0]);
278
281 // create a pythonBoundaryCondition object
282 if (using_tespy || using_server_communication)
283 {
284 // Evaluate Python code in scope of main module
285 pybind11::object scope =
286 pybind11::module::import("__main__").attr("__dict__");
287
288 if (!scope.contains("bc_bhe"))
289 OGS_FATAL(
290 "Function 'bc_bhe' is not defined in the python script file, "
291 "or there was no python script file specified.");
292
293 py_object =
294 scope["bc_bhe"]
296
297 if (py_object == nullptr)
298 OGS_FATAL(
299 "Not able to access the correct bc pointer from python script "
300 "file specified.");
301
302 // create BHE network dataframe from Python
303 py_object->dataframe_network = py_object->initializeDataContainer();
304 if (!py_object->isOverriddenEssential())
305 {
306 DBUG(
307 "Method `initializeDataContainer' not overridden in Python "
308 "script.");
309 }
310 // clear ogs bc_node_id memory in dataframe
311 std::get<3>(py_object->dataframe_network).clear(); // ogs_bc_node_id
312
313 // here calls the tespyHydroSolver to get the pipe flow velocity in bhe
314 // network
315 /* for 2U type the flowrate initialization process below causes conflict
316 // replace the value in flow velocity Matrix _u
317 auto const tespy_flow_rate = std::get<4>(py_object->dataframe_network);
318 const std::size_t n_bhe = tespy_flow_rate.size();
319 if (bhes.size() != n_bhe)
320 OGS_FATAL(
321 "The number of BHEs defined in OGS and TESPy are not the "
322 "same!");
323
324 for (std::size_t idx_bhe = 0; idx_bhe < n_bhe; idx_bhe++)
325 {
326 // the flow_rate in OGS should be updated from the flow_rate
327 // computed by TESPy.
328 auto update_flow_rate = [&](auto& bhe) {
329 bhe.updateHeatTransferCoefficients(tespy_flow_rate[idx_bhe]);
330 };
331 visit(update_flow_rate, bhes[idx_bhe]);
332 }
333 */
334 }
335
336 HeatTransportBHEProcessData process_data(
337 std::move(media_map), std::move(bhes), py_object, using_tespy,
338 using_server_communication, mass_lumping,
339 {using_algebraic_bc, weighting_factor, is_linear});
340
341 SecondaryVariableCollection secondary_variables;
342
343 ProcessLib::createSecondaryVariables(config, secondary_variables);
344
345 return std::make_unique<HeatTransportBHEProcess>(
346 std::move(name), mesh, std::move(jacobian_assembler), parameters,
347 integration_order, std::move(process_variables),
348 std::move(process_data), std::move(secondary_variables),
349 std::move(bhe_mesh_data));
350}
351} // namespace HeatTransportBHE
352} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
T getConfigParameter(std::string const &param) const
ConfigTree getConfigSubtree(std::string const &root) const
Range< ValueIterator< T > > getConfigParameterList(std::string const &param) const
void checkConfigParameter(std::string const &param, std::string_view const value) const
Handles configuration of several secondary variables from the project file.
std::vector< int > splitMaterialIdString(std::string const &material_id_string)
MaterialSpatialDistributionMap createMaterialSpatialDistributionMap(std::map< int, std::shared_ptr< Medium > > const &media, MeshLib::Mesh const &mesh)
std::variant< BHE_1U, BHE_CXA, BHE_CXC, BHE_2U, BHE_1P > BHETypes
Definition BHETypes.h:26
T_BHE createBHE1PType(BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
T_BHE createBHEUType(BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
T_BHE createBHECoaxial(BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves)
std::unique_ptr< Process > createHeatTransportBHEProcess(std::string const &name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase > > const &parameters, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium > > const &media)
void createAndInsertBHE(const std::string &bhe_type, const std::vector< int > &bhe_ids_of_this_bhe, const BaseLib::ConfigTree &bhe_config, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &curves, std::map< int, BHE::BHETypes > &bhes_map)
std::map< std::string_view, std::function< BHE::BHETypes(BaseLib::ConfigTree const &, std::map< std::string, std::unique_ptr< MathLib::PiecewiseLinearInterpolation > > const &)> > bheCreators
BHEMeshData getBHEDataInMesh(MeshLib::Mesh const &mesh)
Definition MeshUtils.cpp:51
void createSecondaryVariables(BaseLib::ConfigTree const &config, SecondaryVariableCollection &secondary_variables)