From 3c1b7944ae21479f0490565e491d28625d805d3f Mon Sep 17 00:00:00 2001 From: Christoph Lehmann Date: Tue, 11 Jun 2024 12:38:06 +0200 Subject: [PATCH] [PL/RM] Use reflection for IP data input --- .../LocalAssemblerInterface.h | 56 ++++++++- .../RichardsMechanicsFEM-impl.h | 119 ------------------ .../RichardsMechanics/RichardsMechanicsFEM.h | 6 - 3 files changed, 53 insertions(+), 128 deletions(-) diff --git a/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h b/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h index d9463fcc5fc..a9f01c33a63 100644 --- a/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h +++ b/ProcessLib/RichardsMechanics/LocalAssemblerInterface.h @@ -16,7 +16,9 @@ #include "NumLib/Extrapolation/ExtrapolatableElement.h" #include "NumLib/Fem/Integration/GenericIntegrationMethod.h" #include "ProcessLib/LocalAssemblerInterface.h" +#include "ProcessLib/Reflection/ReflectionSetIPData.h" #include "ProcessLib/ThermoRichardsMechanics/ConstitutiveCommon/MaterialState.h" +#include "ProcessLib/Utils/SetOrGetIntegrationPointData.h" #include "RichardsMechanicsProcessData.h" namespace ProcessLib @@ -60,9 +62,57 @@ struct LocalAssemblerInterface : public ProcessLib::LocalAssemblerInterface, } } - virtual std::size_t setIPDataInitialConditions( - std::string_view const name, double const* values, - int const integration_order) = 0; + std::size_t setIPDataInitialConditions(std::string_view name, + double const* values, + int const integration_order) + { + if (integration_order != + static_cast(integration_method_.getIntegrationOrder())) + { + OGS_FATAL( + "Setting integration point initial conditions; The integration " + "order of the local assembler for element {:d} is different " + "from the integration order in the initial condition.", + element_.getID()); + } + + if (name == "sigma" && process_data_.initial_stress != nullptr) + { + OGS_FATAL( + "Setting initial conditions for stress from integration " + "point data and from a parameter '{:s}' is not possible " + "simultaneously.", + process_data_.initial_stress->name); + } + + if (name.starts_with("material_state_variable_")) + { + name.remove_prefix(24); + + auto const& internal_variables = + solid_material_.getInternalVariables(); + if (auto const iv = std::find_if( + begin(internal_variables), end(internal_variables), + [&name](auto const& iv) { return iv.name == name; }); + iv != end(internal_variables)) + { + DBUG("Setting material state variable '{:s}'", name); + return ProcessLib:: + setIntegrationPointDataMaterialStateVariables( + values, material_states_, + &ProcessLib::ThermoRichardsMechanics::MaterialStateData< + DisplacementDim>::material_state_variables, + iv->reference); + } + return 0; + } + + // TODO this logic could be pulled out of the local assembler into the + // process. That might lead to a slightly better performance due to less + // string comparisons. + return ProcessLib::Reflection::reflectSetIPData( + name, values, current_states_); + } virtual std::vector getMaterialStateVariableInternalState( std::function( diff --git a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h index 080271c44a2..fbb5818088c 100644 --- a/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h +++ b/ProcessLib/RichardsMechanics/RichardsMechanicsFEM-impl.h @@ -197,125 +197,6 @@ RichardsMechanicsLocalAssembler -std::size_t RichardsMechanicsLocalAssembler< - ShapeFunctionDisplacement, ShapeFunctionPressure, - DisplacementDim>::setIPDataInitialConditions(std::string_view name, - double const* values, - int const integration_order) -{ - if (integration_order != - static_cast(this->integration_method_.getIntegrationOrder())) - { - OGS_FATAL( - "Setting integration point initial conditions; The integration " - "order of the local assembler for element {:d} is different " - "from the integration order in the initial condition.", - this->element_.getID()); - } - - if (name == "sigma") - { - if (this->process_data_.initial_stress != nullptr) - { - OGS_FATAL( - "Setting initial conditions for stress from integration " - "point data and from a parameter '{:s}' is not possible " - "simultaneously.", - this->process_data_.initial_stress->name); - } - return ProcessLib::setIntegrationPointKelvinVectorData( - values, this->current_states_, [](auto& tuple) -> auto& { - return std::get>( - tuple) - .sigma_eff; - }); - } - - if (name == "saturation") - { - return ProcessLib::setIntegrationPointScalarData( - values, this->current_states_, - [](auto& tuple) -> auto& - { - return std::get< - ProcessLib::ThermoRichardsMechanics::SaturationData>( - tuple) - .S_L; - }); - } - if (name == "porosity") - { - return ProcessLib::setIntegrationPointScalarData( - values, this->current_states_, - [](auto& tuple) -> auto& - { - return std::get< - ProcessLib::ThermoRichardsMechanics::PorosityData>( - tuple) - .phi; - }); - } - if (name == "transport_porosity") - { - return ProcessLib::setIntegrationPointScalarData( - values, this->current_states_, - [](auto& tuple) -> auto& - { - return std::get(tuple) - .phi; - }); - } - if (name == "swelling_stress") - { - return ProcessLib::setIntegrationPointKelvinVectorData( - values, this->current_states_, - [](auto& tuple) -> auto& - { - return std::get>( - tuple) - .sigma_sw; - }); - } - if (name == "epsilon") - { - return ProcessLib::setIntegrationPointKelvinVectorData( - values, this->current_states_, [](auto& tuple) -> auto& { - return std::get>(tuple).eps; - }); - } - if (name.starts_with("material_state_variable_")) - { - name.remove_prefix(24); - - // Using first ip data for solid material. TODO (naumov) move solid - // material into element, store only material state in IPs. - auto const& internal_variables = - _ip_data[0].solid_material.getInternalVariables(); - if (auto const iv = std::find_if( - begin(internal_variables), end(internal_variables), - [&name](auto const& iv) { return iv.name == name; }); - iv != end(internal_variables)) - { - DBUG("Setting material state variable '{:s}'", name); - return ProcessLib::setIntegrationPointDataMaterialStateVariables( - values, _ip_data, &IpData::material_state_variables, - iv->reference); - } - - ERR("Could not find variable {:s} in solid material model's internal " - "variables.", - name); - } - return 0; -} - template void RichardsMechanicsLocalAssembler& process_data); - /// \return the number of read integration points. - std::size_t setIPDataInitialConditions( - std::string_view const name, - double const* values, - int const integration_order) override; - void setInitialConditionsConcrete(Eigen::VectorXd const local_x, double const t, int const process_id) override;