-
Notifications
You must be signed in to change notification settings - Fork 238
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'trm-model-auto-eval' into 'master'
[TRM] More automation in constitutive setting evaluation. See merge request ogs/ogs!5001
- Loading branch information
Showing
25 changed files
with
680 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/** | ||
* \file | ||
* \copyright | ||
* Copyright (c) 2012-2024, OpenGeoSys Community (http://www.opengeosys.org) | ||
* Distributed under a Modified BSD License. | ||
* See accompanying file LICENSE.txt or | ||
* http://www.opengeosys.org/project/license | ||
* | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <boost/mp11.hpp> | ||
#include <typeindex> | ||
#include <unordered_set> | ||
|
||
#include "Apply.h" | ||
#include "BaseLib/Logging.h" | ||
|
||
namespace ProcessLib::Graph | ||
{ | ||
namespace detail | ||
{ | ||
template <typename T> | ||
struct IsInputArgument | ||
: boost::mp11::mp_bool<std::is_lvalue_reference_v<T> && | ||
std::is_const_v<std::remove_reference_t<T>>> | ||
{ | ||
static_assert(std::is_lvalue_reference_v<T>, | ||
"The current implementation only deals with l-value " | ||
"references as function arguments. If you want to extend it, " | ||
"test thoroughly in order to not introduce bugs."); | ||
}; | ||
|
||
template <typename T> | ||
struct IsOutputArgument : boost::mp11::mp_bool<!IsInputArgument<T>::value> | ||
{ | ||
static_assert(std::is_lvalue_reference_v<T>, | ||
"The current implementation only deals with l-value " | ||
"references as function arguments. If you want to extend it, " | ||
"test thoroughly in order to not introduce bugs."); | ||
}; | ||
|
||
template <typename Model> | ||
bool isEvalOrderCorrectRT(std::unordered_set<std::type_index>& computed_data) | ||
{ | ||
using namespace boost::mp11; | ||
|
||
using ModelArgs = | ||
typename GetFunctionArgumentTypes<decltype(&Model::eval)>::type; | ||
using ModelInputs = mp_filter<IsInputArgument, ModelArgs>; | ||
using ModelOutputs = mp_filter<IsOutputArgument, ModelArgs>; | ||
|
||
using ModelInputsWrapped = mp_transform<mp_identity, ModelInputs>; | ||
|
||
// Check that all inputs have already been computed before. | ||
bool all_inputs_computed = true; | ||
mp_for_each<ModelInputsWrapped>( | ||
[&computed_data, | ||
&all_inputs_computed]<typename Input>(mp_identity<Input>) | ||
{ | ||
if (!computed_data.contains(std::type_index{typeid(Input)})) | ||
{ | ||
ERR("Input {} of model {} has not been computed/set before the " | ||
"model evaluation.", | ||
typeid(Input).name(), typeid(Model).name()); | ||
all_inputs_computed = false; | ||
} | ||
}); | ||
if (!all_inputs_computed) | ||
{ | ||
return false; | ||
} | ||
|
||
using ModelOutputsWrapped = mp_transform<mp_identity, ModelOutputs>; | ||
|
||
// All outputs are "computed data", now. | ||
bool no_output_precomputed = true; | ||
mp_for_each<ModelOutputsWrapped>( | ||
[&computed_data, | ||
&no_output_precomputed]<typename Output>(mp_identity<Output>) | ||
{ | ||
auto const [it, emplaced] = computed_data.emplace(typeid(Output)); | ||
|
||
if (!emplaced) | ||
{ | ||
ERR("Output {} of model {} is computed more than once.", | ||
typeid(Output).name(), | ||
typeid(Model).name()); | ||
no_output_precomputed = false; | ||
} | ||
}); | ||
|
||
return no_output_precomputed; | ||
} | ||
|
||
template <typename... Models> | ||
bool isEvalOrderCorrectRT(boost::mp11::mp_list<Models...>, | ||
std::unordered_set<std::type_index>&& computed_data) | ||
{ | ||
return (isEvalOrderCorrectRT<Models>(computed_data) && ...); | ||
} | ||
} // namespace detail | ||
|
||
/// Checks at runtime if the given \c Models are evaluated in the right order if | ||
/// evaluated in the order in which they appear in the list of \c Models. | ||
/// | ||
/// I.e., all input data of a model must have been computed before that model | ||
/// will be evaluated and no two models must compute the same data. | ||
/// | ||
/// The passed \c Inputs are data that already have been computed before the | ||
/// first model is evaluated. | ||
template <typename Models, typename Inputs> | ||
bool isEvalOrderCorrectRT() // RT for runtime | ||
{ | ||
using namespace boost::mp11; | ||
|
||
static_assert(mp_is_list<Models>::value); | ||
static_assert(mp_is_list<Inputs>::value); | ||
|
||
// Wrap inputs. The elements of InputsWrapped are default constructible. | ||
using InputsWrapped = mp_transform<mp_identity, Inputs>; | ||
|
||
// "Holds" all data that has been computed successively by the invoked | ||
// models. | ||
std::unordered_set<std::type_index> computed_data; | ||
|
||
// All inputs are considered "computed data". | ||
mp_for_each<InputsWrapped>( | ||
[&computed_data]<typename Input>(mp_identity<Input>) | ||
{ computed_data.emplace(typeid(Input)); }); | ||
|
||
return detail::isEvalOrderCorrectRT(mp_rename<Models, mp_list>{}, | ||
std::move(computed_data)); | ||
} | ||
} // namespace ProcessLib::Graph |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* \file | ||
* \copyright | ||
* Copyright (c) 2012-2024, OpenGeoSys Community (http://www.opengeosys.org) | ||
* Distributed under a Modified BSD License. | ||
* See accompanying file LICENSE.txt or | ||
* http://www.opengeosys.org/project/license | ||
* | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <tuple> | ||
#include <utility> | ||
|
||
#include "Apply.h" | ||
|
||
namespace ProcessLib::Graph | ||
{ | ||
namespace detail | ||
{ | ||
template <typename T> | ||
concept HasCreate = requires | ||
{ | ||
T::create; | ||
}; | ||
|
||
template <typename Model, typename TupleOfArgs> | ||
Model constructModel(TupleOfArgs& args) | ||
{ | ||
if constexpr (HasCreate<Model>) | ||
{ | ||
return applyImpl(&Model::create, args); | ||
} | ||
else if constexpr (std::is_default_constructible_v<Model>) | ||
{ | ||
return Model{}; | ||
} | ||
else | ||
{ | ||
static_assert(std::is_default_constructible_v< | ||
Model> /* This is definitely false, here. */, | ||
"The model to be constructed has neither a static " | ||
"create() function nor is it default constructible."); | ||
} | ||
} | ||
template <template <typename...> typename Tuple, | ||
typename... Models, | ||
typename TupleOfArgs> | ||
Tuple<Models...> constructModels(std::type_identity<Tuple<Models...>>, | ||
TupleOfArgs&& args) | ||
{ | ||
return Tuple{constructModel<Models>(args)...}; | ||
} | ||
} // namespace detail | ||
|
||
/** | ||
* Constructs a tuple of models. | ||
* | ||
* Each model in the tuple is either | ||
* | ||
* 1. constructed by calling a static create() method of the model's class, | ||
* 2. or by default construction if the former does not exist. | ||
* | ||
* In case (1.) the arguments are passed via their data types from the passed | ||
* \c args to the create() method. | ||
*/ | ||
template <typename TupleOfModels, typename... Args> | ||
TupleOfModels constructModels(Args&&... args) | ||
{ | ||
return detail::constructModels( | ||
std::type_identity<TupleOfModels>{}, | ||
std::forward_as_tuple(std::forward<Args>(args)...)); | ||
} | ||
} // namespace ProcessLib::Graph |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
ProcessLib/ThermoRichardsMechanics/ConstitutiveCommon/SpecificBodyForceData.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* \file | ||
* \copyright | ||
* Copyright (c) 2012-2024, OpenGeoSys Community (http://www.opengeosys.org) | ||
* Distributed under a Modified BSD License. | ||
* See accompanying file LICENSE.txt or | ||
* http://www.opengeosys.org/project/license | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <Eigen/Core> | ||
|
||
namespace ProcessLib::ThermoRichardsMechanics | ||
{ | ||
template <int DisplacementDim> | ||
struct SpecificBodyForceData | ||
{ | ||
Eigen::Vector<double, DisplacementDim> specific_body_force; | ||
}; | ||
} // namespace ProcessLib::ThermoRichardsMechanics |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.