67    const std::string& bhe_type, 
const std::vector<int>& bhe_ids_of_this_bhe,
 
   70             std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> 
const&
 
   72    std::map<int, BHE::BHETypes>& bhes_map)
 
   77        OGS_FATAL(
"Unknown BHE type: {:s}", bhe_type);
 
   79    for (
auto const& 
id : bhe_ids_of_this_bhe)
 
   81        std::pair<std::map<int, BHE::BHETypes>::iterator, 
bool> result;
 
   82        if (
id == bhe_ids_of_this_bhe[0])
 
   84            result = bhes_map.try_emplace(
 
   85                id, bhe_creator_it->second(bhe_config, curves));
 
   89            result = bhes_map.try_emplace(
 
   90                id, bhes_map.find(bhe_ids_of_this_bhe[0])->second);
 
   95                "BHE with id '{:d}' is already present in the list! Check for " 
   96                "duplicate definitions of BHE ids.",
 
 
  103    std::string 
const& name,
 
  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,
 
  110    std::map<std::string,
 
  111             std::unique_ptr<MathLib::PiecewiseLinearInterpolation>> 
const&
 
  113    std::map<
int, std::shared_ptr<MaterialPropertyLib::Medium>> 
const& media)
 
  118    DBUG(
"Create HeatTransportBHE Process.");
 
  124    std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
 
  133    std::vector<std::reference_wrapper<ProcessVariable>> per_process_variables;
 
  135    for (std::string 
const& pv_name : range)
 
  137        if (pv_name != 
"temperature_soil" &&
 
  138            pv_name.find(
"temperature_BHE") == std::string::npos)
 
  141                "Found a process variable name '{}'. It should be " 
  142                "'temperature_soil' or 'temperature_BHE_X'",
 
  145        auto variable = std::find_if(variables.cbegin(), variables.cend(),
 
  147                                     { return v.getName() == pv_name; });
 
  149        if (variable == variables.end())
 
  152                "Could not find process variable '{:s}' in the provided " 
  153                "variables list for config tag <{:s}>.",
 
  154                pv_name, 
"process_variable");
 
  156        DBUG(
"Found process variable '{:s}' for config tag <{:s}>.",
 
  157             variable->getName(), 
"process_variable");
 
  159        per_process_variables.emplace_back(
 
  162    process_variables.push_back(std::move(per_process_variables));
 
  171    auto const& bhe_configs =
 
  175    auto const using_server_communication =
 
  179    auto const mass_lumping =
 
  183    auto const using_algebraic_bc =
 
  187    auto const weighting_factor =
 
  191    auto const is_linear =
 
  196        if (!using_algebraic_bc)
 
  199                "You specified that the process simulated by OGS is linear. " 
  200                "With that optimization the process will be assembled only " 
  201                "once and the non-linear solver will only do iterations per " 
  202                "time step to fulfill the BHE boundary conditions. No other " 
  203                "non-linearities will be resolved and OGS will not detect if " 
  204                "there are any non-linearities. It is your responsibility to " 
  205                "ensure that the assembled equation systems are linear, " 
  206                "indeed! There is no safety net!");
 
  211                "You specified that the process simulated by OGS is linear. " 
  212                "With that optimization the process will be assembled only " 
  213                "once and the non-linear solver will do only one iteration per " 
  214                "time step. No non-linearities will be resolved and OGS will " 
  215                "not detect if there are any non-linearities. It is your " 
  216                "responsibility to ensure that the assembled equation systems " 
  217                "are linear, indeed! There is no safety net!");
 
  221    std::map<int, BHE::BHETypes> bhes_map;
 
  223    int bhe_iterator = 0;
 
  226        auto const& bhe_config :
 
  228        bhe_configs.getConfigSubtreeList(
"borehole_heat_exchanger"))
 
  232            bhe_config.getConfigAttribute<std::string>(
 
  233                "id", std::to_string(bhe_iterator));
 
  235        std::vector<int> bhe_ids_of_this_bhe;
 
  237        if (bhe_id_string == 
"*")
 
  239            int size = 
static_cast<int>(bhe_mesh_data.BHE_mat_IDs.size());
 
  240            bhe_ids_of_this_bhe.resize(size);
 
  241            std::iota(bhe_ids_of_this_bhe.begin(), bhe_ids_of_this_bhe.end(),
 
  246            bhe_ids_of_this_bhe =
 
  251        const std::string bhe_type =
 
  253            bhe_config.getConfigParameter<std::string>(
"type");
 
  260    if (
static_cast<int>(bhes_map.size()) - 1 != bhes_map.rbegin()->first)
 
  263            "The maximum given BHE id '{:d}' did not match the number of given " 
  264            "BHE definitions '{:d}'. The BHE ids needs to be defined starting " 
  265            "from 0, so the maximum BHE id needs to be number of BHE " 
  266            "definitions minus 1. After all definitions there are no gaps " 
  267            "allowed between the given ids.",
 
  268            bhes_map.rbegin()->first, bhes_map.size());
 
  271    std::vector<BHE::BHETypes> bhes;
 
  272    bhes.reserve(bhes_map.size());
 
  273    std::ranges::copy(bhes_map | std::views::values, std::back_inserter(bhes));
 
  281    auto const using_tespy =
 
  282        visit([](
auto const& bhe) { 
return bhe.use_python_bcs; }, bhes[0]);
 
  287    if (using_tespy || using_server_communication)
 
  290        pybind11::object scope =
 
  291            pybind11::module::import(
"__main__").attr(
"__dict__");
 
  293        if (!scope.contains(
"bc_bhe"))
 
  295                "Function 'bc_bhe' is not defined in the python script file, " 
  296                "or there was no python script file specified.");
 
  302        if (py_object == 
nullptr)
 
  304                "Not able to access the correct bc pointer from python script " 
  308        py_object->dataframe_network = py_object->initializeDataContainer();
 
  309        if (!py_object->isOverriddenEssential())
 
  312                "Method `initializeDataContainer' not overridden in Python " 
  316        std::get<3>(py_object->dataframe_network).clear();  
 
  342        std::move(media_map), std::move(bhes), py_object, using_tespy,
 
  343        using_server_communication, mass_lumping,
 
  344        {using_algebraic_bc, weighting_factor}, is_linear);
 
  350    return std::make_unique<HeatTransportBHEProcess>(
 
  351        std::move(name), mesh, std::move(jacobian_assembler), parameters,
 
  352        integration_order, std::move(process_variables),
 
  353        std::move(process_data), std::move(secondary_variables),
 
  354        std::move(bhe_mesh_data));
 
 
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 ¶meters, 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)