diff --git a/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h b/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..d1dff264edada8aaeb8b8e6d3dc52c5587832b6b --- /dev/null +++ b/ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h @@ -0,0 +1,84 @@ +/** + * \file + * + * \copyright + * Copyright (c) 2012-2019, 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 <map> +#include <memory> + +#include "MathLib/LinAlg/Eigen/EigenMapTools.h" + +namespace ProcessLib::Deformation +{ +template <typename LocalAssemblerInterface, + typename AddSecondaryVariableCallback, int DisplacementDim> +void solidMaterialInternalToSecondaryVariables( + std::map<int, std::unique_ptr<MaterialLib::Solids::MechanicsBase< + DisplacementDim>>> const& solid_materials, + AddSecondaryVariableCallback const& add_secondary_variable) +{ + // Collect the internal variables for all solid materials. + std::vector<typename MaterialLib::Solids::MechanicsBase< + DisplacementDim>::InternalVariable> + internal_variables; + for (auto const& material_id__solid_material : solid_materials) + { + auto const variables = + material_id__solid_material.second->getInternalVariables(); + copy(begin(variables), end(variables), + back_inserter(internal_variables)); + } + + // Register the internal variables. + for (auto const& internal_variable : internal_variables) + { + auto const& name = internal_variable.name; + auto const& fct = internal_variable.getter; + auto const num_components = internal_variable.num_components; + DBUG("Registering internal variable %s.", name.c_str()); + + auto getIntPtValues = + [fct, num_components]( + LocalAssemblerInterface const& loc_asm, + const double /*t*/, + std::vector<GlobalVector*> const& /*x*/, + std::vector< + NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/, + std::vector<double>& cache) -> std::vector<double> const& { + const unsigned num_int_pts = loc_asm.getNumberOfIntegrationPoints(); + + cache.clear(); + auto cache_mat = MathLib::createZeroedMatrix<Eigen::Matrix< + double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>( + cache, num_components, num_int_pts); + + // TODO avoid the heap allocation (one per finite element) + std::vector<double> cache_column(num_int_pts); + + for (unsigned i = 0; i < num_int_pts; ++i) + { + auto const& state = loc_asm.getMaterialStateVariablesAt(i); + + auto const& int_pt_values = fct(state, cache_column); + assert(int_pt_values.size() == num_components); + auto const int_pt_values_vec = MathLib::toVector(int_pt_values); + + cache_mat.col(i).noalias() = int_pt_values_vec; + } + + return cache; + }; + + add_secondary_variable(name, num_components, std::move(getIntPtValues)); + } + +} + +} // namespace ProcessLib::Deformation diff --git a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp index 6d58551a2946a91905153bd290864d769f1a444e..d12ecc5bd5a8e1601c4625be7bc9c677f126193e 100644 --- a/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp +++ b/ProcessLib/SmallDeformation/SmallDeformationProcess.cpp @@ -13,10 +13,10 @@ #include <cassert> #include <nlohmann/json.hpp> +#include "ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h" #include "ProcessLib/Output/IntegrationPointWriter.h" #include "ProcessLib/Process.h" #include "ProcessLib/SmallDeformation/CreateLocalAssemblers.h" - #include "SmallDeformationFEM.h" namespace ProcessLib @@ -120,65 +120,19 @@ void SmallDeformationProcess<DisplacementDim>::initializeConcreteProcess( // // enable output of internal variables defined by material models // - - // Collect the internal variables for all solid materials. - std::vector<typename MaterialLib::Solids::MechanicsBase< - DisplacementDim>::InternalVariable> - internal_variables; - for (auto const& material_id__solid_material : - _process_data.solid_materials) - { - auto const variables = - material_id__solid_material.second->getInternalVariables(); - copy(begin(variables), end(variables), - back_inserter(internal_variables)); - } - - // Register the internal variables. - for (auto const& internal_variable : internal_variables) - { - auto const& name = internal_variable.name; - auto const& fct = internal_variable.getter; - auto const num_components = internal_variable.num_components; - DBUG("Registering internal variable %s.", name.c_str()); - - auto getIntPtValues = - [fct, num_components]( - LocalAssemblerInterface const& loc_asm, - const double /*t*/, - std::vector<GlobalVector*> const& /*x*/, - std::vector< - NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/, - std::vector<double>& cache) -> std::vector<double> const& { - const unsigned num_int_pts = loc_asm.getNumberOfIntegrationPoints(); - - cache.clear(); - auto cache_mat = MathLib::createZeroedMatrix<Eigen::Matrix< - double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>( - cache, num_components, num_int_pts); - - // TODO avoid the heap allocation (one per finite element) - std::vector<double> cache_column(num_int_pts); - - for (unsigned i = 0; i < num_int_pts; ++i) - { - auto const& state = loc_asm.getMaterialStateVariablesAt(i); - - auto const& int_pt_values = fct(state, cache_column); - assert(int_pt_values.size() == num_components); - auto const int_pt_values_vec = MathLib::toVector(int_pt_values); - - cache_mat.col(i).noalias() = int_pt_values_vec; - } - - return cache; - }; - + auto add_secondary_variable = [&](std::string const& name, + int const num_components, + auto get_ip_values_function) { _secondary_variables.addSecondaryVariable( name, makeExtrapolator(num_components, getExtrapolator(), - _local_assemblers, std::move(getIntPtValues))); - } + _local_assemblers, + std::move(get_ip_values_function))); + }; + + ProcessLib::Deformation::solidMaterialInternalToSecondaryVariables< + LocalAssemblerInterface>(_process_data.solid_materials, + add_secondary_variable); // Set initial conditions for integration point data. for (auto const& ip_writer : _integration_point_writer)