diff --git a/ProcessLib/ComponentTransport/CreateComponentTransportProcess.cpp b/ProcessLib/ComponentTransport/CreateComponentTransportProcess.cpp index 74ce5045f201f31a88622ba82b4e212f1ca7ccd3..8e8741531ac811172dbaf4a2b929065152b4b082 100644 --- a/ProcessLib/ComponentTransport/CreateComponentTransportProcess.cpp +++ b/ProcessLib/ComponentTransport/CreateComponentTransportProcess.cpp @@ -53,28 +53,45 @@ std::unique_ptr<Process> createComponentTransportProcess( std::vector<std::vector<std::reference_wrapper<ProcessVariable>>> process_variables; + + // get all process variables stored in a vector before allocation + // pressure first, concentration then + auto const unalloc_process_variables = findProcessVariables( + variables, pv_config, + {//! \ogs_file_param_special{prj__processes__process__ComponentTransport__process_variables__pressure} + "pressure", + //! \ogs_file_param_special{prj__processes__process__ComponentTransport__process_variables__concentration} + "concentration"}); + + // check number of components for each process variable + auto it = std::find_if( + unalloc_process_variables.cbegin(), unalloc_process_variables.cend(), + [](std::reference_wrapper<ProcessLib::ProcessVariable> const& pv) { + return pv.get().getNumberOfComponents() != 1; + }); + + if (it != unalloc_process_variables.end()) + OGS_FATAL( + "Number of components for process variable \"%s\" should be 1 " + "rather than %d.", + it->get().getName().c_str(), + it->get().getNumberOfComponents()); + + // allocated into a two-dimensional vector, depending on what scheme is + // adopted if (use_monolithic_scheme) // monolithic scheme. { - auto per_process_variables = findProcessVariables( - variables, pv_config, - { - //! \ogs_file_param_special{prj__processes__process__ComponentTransport__process_variables__concentration} - "concentration", - //! \ogs_file_param_special{prj__processes__process__ComponentTransport__process_variables__pressure} - "pressure"}); - process_variables.push_back(std::move(per_process_variables)); + process_variables.push_back(std::move(unalloc_process_variables)); } else // staggered scheme. { - std::array<std::string, 2> variable_names = { - {"concentration", - "pressure"}}; // double-braces required in C++11 (not in C++14) + std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>> + per_process_variable; - for (int i = 0; i < 2; i++) + for (auto& pv : unalloc_process_variables) { - auto per_process_variables = - findProcessVariables(variables, pv_config, {variable_names[i]}); - process_variables.push_back(std::move(per_process_variables)); + per_process_variable.emplace_back(pv); + process_variables.push_back(std::move(per_process_variable)); } } diff --git a/ProcessLib/Utils/ProcessUtils.cpp b/ProcessLib/Utils/ProcessUtils.cpp index ce4f3f8188a1ee84b4e9fb63f4ec9db634309e37..8e7dfcf2804083af467786e46dce78a3b6288763 100644 --- a/ProcessLib/Utils/ProcessUtils.cpp +++ b/ProcessLib/Utils/ProcessUtils.cpp @@ -8,6 +8,7 @@ */ #include "ProcessUtils.h" +#include <iterator> #include "ProcessLib/ProcessVariable.h" namespace ProcessLib @@ -43,17 +44,64 @@ std::vector<std::reference_wrapper<ProcessVariable>> findProcessVariables( std::vector<ProcessVariable> const& variables, BaseLib::ConfigTree const& pv_config, std::initializer_list<std::string> - tag_names) + tags) { std::vector<std::reference_wrapper<ProcessVariable>> vars; - vars.reserve(tag_names.size()); + vars.reserve(variables.size()); - for (auto const& tag : tag_names) + if (variables.size() > tags.size()) + DBUG("Found multiple process variables with a same tag."); + + for (auto& tag : tags) { - vars.emplace_back(findProcessVariable(variables, pv_config, tag)); + auto vars_per_tag = findProcessVariables(variables, pv_config, tag); + vars.insert(vars.end(), vars_per_tag.begin(), vars_per_tag.end()); } return vars; } +std::vector<std::reference_wrapper<ProcessVariable>> findProcessVariables( + std::vector<ProcessVariable> const& variables, + BaseLib::ConfigTree const& pv_config, + std::string const& tag) +{ + std::vector<std::reference_wrapper<ProcessVariable>> vars; + + auto var_names = pv_config.getConfigParameterList<std::string>(tag); + + if (var_names.size() == 0) + OGS_FATAL("Config tag <%s> is not found.", tag.c_str()); + + // collect variable names to check if there are duplicates + std::set<std::string> cached_var_names; + + for (std::string const& var_name : var_names) + { + auto variable = std::find_if(variables.cbegin(), variables.cend(), + [&var_name](ProcessVariable const& v) { + return v.getName() == var_name; + }); + + if (variable == variables.end()) + { + OGS_FATAL( + "Could not find process variable '%s' in the provided " + "variables " + "list for config tag <%s>.", + var_name.c_str(), tag.c_str()); + } + DBUG("Found process variable \'%s\' for config tag <%s>.", + variable->getName().c_str(), tag.c_str()); + + vars.emplace_back(const_cast<ProcessVariable&>(*variable)); + + cached_var_names.insert(var_name); + } + + if (cached_var_names.size() != var_names.size()) + OGS_FATAL("Found duplicates with config tag <%s>.", tag.c_str()); + + return vars; +} } // ProcessLib diff --git a/ProcessLib/Utils/ProcessUtils.h b/ProcessLib/Utils/ProcessUtils.h index 4c38569e5395f1be33e333475183d57a8f5ad058..11199ccc7e66cc91a602a4ad755d2fa32c8bd724 100644 --- a/ProcessLib/Utils/ProcessUtils.h +++ b/ProcessLib/Utils/ProcessUtils.h @@ -40,7 +40,12 @@ std::vector<std::reference_wrapper<ProcessVariable>> findProcessVariables( std::vector<ProcessVariable> const& variables, BaseLib::ConfigTree const& process_config, std::initializer_list<std::string> - tag_names); + tags); + +std::vector<std::reference_wrapper<ProcessVariable>> findProcessVariables( + std::vector<ProcessVariable> const& variables, + BaseLib::ConfigTree const& pv_config, + std::string const& tag); /// Find a parameter of specific type for a given name. ///