diff --git a/MaterialLib/SolidModels/LinearElasticIsotropic.h b/MaterialLib/SolidModels/LinearElasticIsotropic.h index 2bd88582428d34a70668280d0816076ccb72ea17..5e9271dc0192cb4a000497de952495ebbd183ad6 100644 --- a/MaterialLib/SolidModels/LinearElasticIsotropic.h +++ b/MaterialLib/SolidModels/LinearElasticIsotropic.h @@ -124,8 +124,8 @@ public: ProcessLib::SpatialPosition const& x, double const T) const; + MaterialProperties getMaterialProperties() const { return _mp; } - MaterialProperties getMaterialProperties() { return _mp; } protected: MaterialProperties _mp; }; diff --git a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp deleted file mode 100644 index 2cfed161f5dfe6b4d610b81eb6a3b19358afa4a8..0000000000000000000000000000000000000000 --- a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/** - * \copyright - * Copyright (c) 2012-2018, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#include "LinearElasticIsotropicPhaseField.h" - -namespace MaterialLib -{ -namespace Solids -{ - -template class LinearElasticIsotropicPhaseField<2>; -template class LinearElasticIsotropicPhaseField<3>; - -} // namespace Solids -} // namespace MaterialLib diff --git a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h index 003c68e70ffafcbb3a7413cf94d727e95ad5e825..ae497050da9dd8e685e08df0381f82d4ef214ee2 100644 --- a/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h +++ b/MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h @@ -11,135 +11,84 @@ #include "MathLib/KelvinVector.h" -#include "LinearElasticIsotropic.h" -#include "PhaseFieldExtension.h" - namespace MaterialLib { namespace Solids { +namespace Phasefield +{ +/** Decompose the stiffness into tensile and compressive part. + * Judging by the physical observations, compression perpendicular + * to a crack does not cause crack propagation. Thus, + * the phase-field parameter is only involved into the tensile part + * to degrade the elastic strain energy. + */ template <int DisplacementDim> -class LinearElasticIsotropicPhaseField final - : public LinearElasticIsotropic<DisplacementDim>, - public PhaseFieldExtension<DisplacementDim> +std::tuple<MathLib::KelvinVector::KelvinVectorType< + DisplacementDim> /* sigma_real */, + MathLib::KelvinVector::KelvinVectorType< + DisplacementDim> /* sigma_tensile */, + MathLib::KelvinVector::KelvinMatrixType< + DisplacementDim> /* C_tensile */, + MathLib::KelvinVector::KelvinMatrixType< + DisplacementDim> /* C_compressive */, + double /* strain_energy_tensile */, + double /* elastic_energy */ + > +calculateDegradedStress( + double const degradation, + double const bulk_modulus, + double const mu, + MathLib::KelvinVector::KelvinVectorType<DisplacementDim> const& eps) { -public: static int const KelvinVectorSize = MathLib::KelvinVector::KelvinVectorDimensions<DisplacementDim>::value; using KelvinVector = MathLib::KelvinVector::KelvinVectorType<DisplacementDim>; using KelvinMatrix = MathLib::KelvinVector::KelvinMatrixType<DisplacementDim>; + using Invariants = MathLib::KelvinVector::Invariants<KelvinVectorSize>; + // calculation of deviatoric parts + auto const& P_dev = Invariants::deviatoric_projection; + KelvinVector const epsd_curr = P_dev * eps; - explicit LinearElasticIsotropicPhaseField( - typename LinearElasticIsotropic<DisplacementDim>::MaterialProperties&& - material_properties) - : LinearElasticIsotropic<DisplacementDim>( - std::move(material_properties)) - { - } - - std::unique_ptr< - typename MechanicsBase<DisplacementDim>::MaterialStateVariables> - createMaterialStateVariables() const override - { - return LinearElasticIsotropic< - DisplacementDim>::createMaterialStateVariables(); - } - - boost::optional<std::tuple<KelvinVector, - std::unique_ptr<typename MechanicsBase< - DisplacementDim>::MaterialStateVariables>, - KelvinMatrix>> - integrateStress( - double const t, ProcessLib::SpatialPosition const& x, double const dt, - KelvinVector const& eps_prev, KelvinVector const& eps, - KelvinVector const& sigma_prev, - typename MechanicsBase<DisplacementDim>::MaterialStateVariables const& - material_state_variables, - double const T) const override - { - return LinearElasticIsotropic<DisplacementDim>::integrateStress( - t, x, dt, eps_prev, eps, sigma_prev, material_state_variables, T); - } + // Hydrostatic part for the stress and the tangent. + double const eps_curr_trace = Invariants::trace(eps); - double computeFreeEnergyDensity( - double const t, - ProcessLib::SpatialPosition const& x, - double const dt, - KelvinVector const& eps, - KelvinVector const& sigma, - typename MechanicsBase<DisplacementDim>::MaterialStateVariables const& - material_state_variables) const override - { - return LinearElasticIsotropic<DisplacementDim>:: - computeFreeEnergyDensity( - t, x, dt, eps, sigma, material_state_variables); - } + KelvinMatrix C_tensile = KelvinMatrix::Zero(); + KelvinMatrix C_compressive = KelvinMatrix::Zero(); - /** Decompose the stiffness into tensile and compressive part. - * Judging by the physical observations, compression perpendicular - * to a crack does not cause crack propagation. Thus, - * the phase-field parameter is only involved into the tensile part - * to degrade the elastic strain energy. - */ - bool calculateDegradedStress(double const t, - ProcessLib::SpatialPosition const& x, - KelvinVector const& eps, - double& strain_energy_tensile, - KelvinVector& sigma_tensile, - KelvinVector& sigma_compressive, - KelvinMatrix& C_tensile, - KelvinMatrix& C_compressive, - KelvinVector& sigma_real, - double const degradation, - double& elastic_energy) const override + if (eps_curr_trace >= 0) { - using Invariants = MathLib::KelvinVector::Invariants<KelvinVectorSize>; - // calculation of deviatoric parts - auto const& P_dev = Invariants::deviatoric_projection; - KelvinVector const epsd_curr = P_dev * eps; - - // Hydrostatic part for the stress and the tangent. - double const eps_curr_trace = Invariants::trace(eps); - - auto const& K = - LinearElasticIsotropic<DisplacementDim>::_mp.bulk_modulus(t, x); - auto const& mu = LinearElasticIsotropic<DisplacementDim>::_mp.mu(t, x); - - C_tensile = KelvinMatrix::Zero(); - C_compressive = KelvinMatrix::Zero(); - - if (eps_curr_trace >= 0) - { - strain_energy_tensile = K / 2 * eps_curr_trace * eps_curr_trace + - mu * epsd_curr.transpose() * epsd_curr; - sigma_tensile.noalias() = - K * eps_curr_trace * Invariants::identity2 + 2 * mu * epsd_curr; - sigma_compressive.noalias() = KelvinVector::Zero(); - C_tensile.template topLeftCorner<3, 3>().setConstant(K); - C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity(); - elastic_energy = degradation * strain_energy_tensile; - } - else - { - strain_energy_tensile = mu * epsd_curr.transpose() * epsd_curr; - sigma_tensile.noalias() = 2 * mu * epsd_curr; - sigma_compressive.noalias() = - K * eps_curr_trace * Invariants::identity2; - C_tensile.noalias() = 2 * mu * P_dev * KelvinMatrix::Identity(); - C_compressive.template topLeftCorner<3, 3>().setConstant(K); - elastic_energy = K / 2 * eps_curr_trace * eps_curr_trace + - mu * epsd_curr.transpose() * epsd_curr; - } - - sigma_real.noalias() = degradation * sigma_tensile + sigma_compressive; - return true; + double const strain_energy_tensile = + bulk_modulus / 2 * eps_curr_trace * eps_curr_trace + + mu * epsd_curr.transpose() * epsd_curr; + KelvinVector const sigma_tensile = + bulk_modulus * eps_curr_trace * Invariants::identity2 + + 2 * mu * epsd_curr; + C_tensile.template topLeftCorner<3, 3>().setConstant(bulk_modulus); + C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity(); + double const elastic_energy = degradation * strain_energy_tensile; + KelvinVector const sigma_real = + degradation * sigma_tensile; // + sigma_compressive, which is zero; + return std::make_tuple(sigma_real, sigma_tensile, C_tensile, + C_compressive, strain_energy_tensile, + elastic_energy); } -}; - -extern template class LinearElasticIsotropicPhaseField<2>; -extern template class LinearElasticIsotropicPhaseField<3>; - + double const strain_energy_tensile = mu * epsd_curr.transpose() * epsd_curr; + KelvinVector const sigma_tensile = 2 * mu * epsd_curr; + KelvinVector const sigma_compressive = + bulk_modulus * eps_curr_trace * Invariants::identity2; + C_tensile.noalias() = 2 * mu * P_dev * KelvinMatrix::Identity(); + C_compressive.template topLeftCorner<3, 3>().setConstant(bulk_modulus); + double const elastic_energy = + bulk_modulus / 2 * eps_curr_trace * eps_curr_trace + + mu * epsd_curr.transpose() * epsd_curr; + KelvinVector const sigma_real = + degradation * sigma_tensile + sigma_compressive; + return std::make_tuple(sigma_real, sigma_tensile, C_tensile, C_compressive, + strain_energy_tensile, elastic_energy); +} +} // namespace Phasefield } // namespace Solids } // namespace MaterialLib diff --git a/MaterialLib/SolidModels/PhaseFieldExtension.h b/MaterialLib/SolidModels/PhaseFieldExtension.h deleted file mode 100644 index 425da16cf2b6ad27b77d878dd100da01705007d6..0000000000000000000000000000000000000000 --- a/MaterialLib/SolidModels/PhaseFieldExtension.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * \file - * \copyright - * Copyright (c) 2012-2018, 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 "MechanicsBase.h" - -namespace MaterialLib -{ -namespace Solids -{ -template <int DisplacementDim> -struct PhaseFieldExtension : public MechanicsBase<DisplacementDim> -{ - using KelvinVector = - MathLib::KelvinVector::KelvinVectorType<DisplacementDim>; - using KelvinMatrix = - MathLib::KelvinVector::KelvinMatrixType<DisplacementDim>; - virtual bool calculateDegradedStress(double const t, - ProcessLib::SpatialPosition const& x, - KelvinVector const& eps, - double& strain_energy_tensile, - KelvinVector& sigma_tensile, - KelvinVector& sigma_compressive, - KelvinMatrix& C_tensile, - KelvinMatrix& C_compressive, - KelvinVector& sigma_real, - double const degradation, - double& elastic_energy) const = 0; - - /// Dynamic size Kelvin vector and matrix wrapper for the polymorphic - /// constitutive relation compute function. - bool calculateDegradedStress( - double const t, - ProcessLib::SpatialPosition const& x, - Eigen::Matrix<double, Eigen::Dynamic, 1> const& eps, - double& strain_energy_tensile, - Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_tensile, - Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_compressive, - Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>& - C_tensile, - Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>& - C_compressive, - Eigen::Matrix<double, Eigen::Dynamic, 1>& sigma_real, - double const degradation, - double& elastic_energy) const - { - // TODO Avoid copies of data: - // Using MatrixBase<Derived> not possible because template functions - // cannot be virtual. Maybe there is a workaround for this. Using - // Map<Matrix<double, ...>> makes the interface (for the material model - // implementation) unnecessary difficult. - KelvinVector const eps_{eps}; - KelvinVector sigma_tensile_{sigma_tensile}; - KelvinVector sigma_compressive_{sigma_compressive}; - KelvinMatrix C_tensile_{C_tensile}; - KelvinMatrix C_compressive_{C_compressive}; - KelvinVector sigma_real_{sigma_real}; - - bool const result = calculateDegradedStress(t, - x, - eps_, - strain_energy_tensile, - sigma_tensile_, - sigma_compressive_, - C_tensile_, - C_compressive_, - sigma_real_, - degradation, - elastic_energy); - - sigma_tensile = sigma_tensile_; - sigma_compressive = sigma_compressive_; - C_tensile = C_tensile_; - C_compressive = C_compressive_; - sigma_real = sigma_real_; - return result; - } -}; - -} // namespace Solids -} // namespace MaterialLib diff --git a/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp b/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp index 1d0195881275ddbd8724db66b7b14b7e06906249..63dad638ad686b30a365c4ba8e0fac62bfbd3846 100644 --- a/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp +++ b/ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp @@ -11,9 +11,10 @@ #include <cassert> -#include "MaterialLib/SolidModels/CreateLinearElasticIsotropic.h" -#include "MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h" +#include "MaterialLib/SolidModels/CreateConstitutiveRelation.h" +#include "MaterialLib/SolidModels/MechanicsBase.h" #include "ProcessLib/Output/CreateSecondaryVariables.h" +#include "ProcessLib/Utils/ProcessUtils.h" #include "PhaseFieldProcess.h" #include "PhaseFieldProcessData.h" @@ -99,40 +100,14 @@ std::unique_ptr<Process> createPhaseFieldProcess( variable_ph->getNumberOfComponents()); } - // Constitutive relation. - // read type; - auto const constitutive_relation_config = - //! \ogs_file_param{prj__processes__process__PHASE_FIELD__constitutive_relation} - config.getConfigSubtree("constitutive_relation"); + auto solid_constitutive_relations = + MaterialLib::Solids::createConstitutiveRelations<DisplacementDim>( + parameters, config); auto const phasefield_parameters_config = //! \ogs_file_param{prj__processes__process__PHASE_FIELD__phasefield_parameters} config.getConfigSubtree("phasefield_parameters"); - auto const type = - //! \ogs_file_param{prj__processes__process__PHASE_FIELD__constitutive_relation__type} - constitutive_relation_config.peekConfigParameter<std::string>("type"); - - std::unique_ptr<MaterialLib::Solids::PhaseFieldExtension<DisplacementDim>> - material = nullptr; - if (type == "LinearElasticIsotropic") - { - const bool skip_type_checking = false; - auto elastic_model = - MaterialLib::Solids::createLinearElasticIsotropic<DisplacementDim>( - parameters, constitutive_relation_config, skip_type_checking); - material = std::make_unique< - MaterialLib::Solids::LinearElasticIsotropicPhaseField< - DisplacementDim>>( - std::move(elastic_model->getMaterialProperties())); - } - else - { - OGS_FATAL( - "Cannot construct constitutive relation of given type \'%s\'.", - type.c_str()); - } - // Residual stiffness auto& residual_stiffness = findParameter<double>( phasefield_parameters_config, @@ -212,9 +187,11 @@ std::unique_ptr<Process> createPhaseFieldProcess( ((*crack_scheme == "propagating") || (*crack_scheme == "static"))); PhaseFieldProcessData<DisplacementDim> process_data{ - std::move(material), residual_stiffness, crack_resistance, - crack_length_scale, kinetic_coefficient, solid_density, - history_field, specific_body_force, propagating_crack, + materialIDs(mesh), std::move(solid_constitutive_relations), + residual_stiffness, crack_resistance, + crack_length_scale, kinetic_coefficient, + solid_density, history_field, + specific_body_force, propagating_crack, crack_pressure}; SecondaryVariableCollection secondary_variables; diff --git a/ProcessLib/PhaseField/PhaseFieldFEM.h b/ProcessLib/PhaseField/PhaseFieldFEM.h index d8baae9231332189f29424d86ceb330afc52385d..32466594ff33e7be0aa24aeb0e7597186bfd45b5 100644 --- a/ProcessLib/PhaseField/PhaseFieldFEM.h +++ b/ProcessLib/PhaseField/PhaseFieldFEM.h @@ -12,7 +12,9 @@ #include <memory> #include <vector> -#include "MaterialLib/SolidModels/PhaseFieldExtension.h" +#include "MaterialLib/SolidModels/LinearElasticIsotropic.h" +#include "MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h" +#include "MaterialLib/SolidModels/SelectSolidConstitutiveRelation.h" #include "MathLib/LinAlg/Eigen/EigenMapTools.h" #include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h" #include "NumLib/Fem/ShapeMatrixPolicy.h" @@ -68,20 +70,28 @@ struct IntegrationPointData final template <typename DisplacementVectorType> void updateConstitutiveRelation(double const t, - SpatialPosition const& x_position, + SpatialPosition const& x, double const /*dt*/, DisplacementVectorType const& /*u*/, double const degradation) { - static_cast< - MaterialLib::Solids::PhaseFieldExtension<DisplacementDim> const&>( - solid_material) - .calculateDegradedStress(t, x_position, eps, strain_energy_tensile, - sigma_tensile, sigma_compressive, - C_tensile, C_compressive, sigma, - degradation, elastic_energy); + auto linear_elastic_mp = + static_cast<MaterialLib::Solids::LinearElasticIsotropic< + DisplacementDim> const&>(solid_material) + .getMaterialProperties(); + + auto const bulk_modulus = linear_elastic_mp.bulk_modulus(t, x); + auto const mu = linear_elastic_mp.mu(t, x); + + std::tie(sigma, sigma_tensile, C_tensile, C_compressive, + strain_energy_tensile, elastic_energy) = + MaterialLib::Solids::Phasefield::calculateDegradedStress< + DisplacementDim>(degradation, bulk_modulus, mu, eps); } EIGEN_MAKE_ALIGNED_OPERATOR_NEW; + + static constexpr int kelvin_vector_size = + MathLib::KelvinVector::KelvinVectorDimensions<DisplacementDim>::value; }; /// Used by for extrapolation of the integration point values. It is ordered @@ -126,6 +136,19 @@ public: _ip_data.reserve(n_integration_points); _secondary_data.N.resize(n_integration_points); + auto& solid_material = + MaterialLib::Solids::selectSolidConstitutiveRelation( + _process_data.solid_materials, + _process_data.material_ids, + e.getID()); + if (!dynamic_cast<MaterialLib::Solids::LinearElasticIsotropic< + DisplacementDim> const*>(&solid_material)) + { + OGS_FATAL( + "For phasefield process only linear elastic solid material " + "support is implemented."); + } + auto const shape_matrices = initShapeMatrices<ShapeFunction, ShapeMatricesType, IntegrationMethod, DisplacementDim>( @@ -136,8 +159,7 @@ public: for (unsigned ip = 0; ip < n_integration_points; ip++) { - // displacement (subscript u) - _ip_data.emplace_back(*_process_data.material); + _ip_data.emplace_back(solid_material); auto& ip_data = _ip_data[ip]; ip_data.integration_weight = _integration_method.getWeightedPoint(ip).getWeight() * diff --git a/ProcessLib/PhaseField/PhaseFieldProcessData.h b/ProcessLib/PhaseField/PhaseFieldProcessData.h index 75fdace07173ad99b6c67235b9c3a0bae855f470..069c0dc3254b850e690a3eebcc7e197e3bc4c74c 100644 --- a/ProcessLib/PhaseField/PhaseFieldProcessData.h +++ b/ProcessLib/PhaseField/PhaseFieldProcessData.h @@ -33,8 +33,11 @@ template <int DisplacementDim> struct PhaseFieldProcessData { PhaseFieldProcessData( - std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>>&& - material_, + MeshLib::PropertyVector<int> const* const material_ids_, + std::map<int, + std::unique_ptr< + MaterialLib::Solids::MechanicsBase<DisplacementDim>>>&& + solid_materials_, Parameter<double> const& residual_stiffness_, Parameter<double> const& crack_resistance_, Parameter<double> const& crack_length_scale_, @@ -42,8 +45,10 @@ struct PhaseFieldProcessData Parameter<double> const& solid_density_, Parameter<double>& history_field_, Eigen::Matrix<double, DisplacementDim, 1> const& specific_body_force_, - bool propagating_crack_, bool crack_pressure_) - : material{std::move(material_)}, + bool const propagating_crack_, + bool const crack_pressure_) + : material_ids(material_ids_), + solid_materials{std::move(solid_materials_)}, residual_stiffness(residual_stiffness_), crack_resistance(crack_resistance_), crack_length_scale(crack_length_scale_), @@ -56,21 +61,7 @@ struct PhaseFieldProcessData { } - PhaseFieldProcessData(PhaseFieldProcessData&& other) - : material{std::move(other.material)}, - residual_stiffness(other.residual_stiffness), - crack_resistance(other.crack_resistance), - crack_length_scale(other.crack_length_scale), - kinetic_coefficient(other.kinetic_coefficient), - solid_density(other.solid_density), - history_field(other.history_field), - specific_body_force(other.specific_body_force), - dt(other.dt), - t(other.t), - propagating_crack(other.propagating_crack), - crack_pressure(other.crack_pressure) - { - } + PhaseFieldProcessData(PhaseFieldProcessData&& other) = default; //! Copies are forbidden. PhaseFieldProcessData(PhaseFieldProcessData const&) = delete; @@ -81,8 +72,11 @@ struct PhaseFieldProcessData //! Assignments are not needed. void operator=(PhaseFieldProcessData&&) = delete; - std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>> - material; + MeshLib::PropertyVector<int> const* const material_ids; + + std::map<int, std::unique_ptr< + MaterialLib::Solids::MechanicsBase<DisplacementDim>>> + solid_materials; Parameter<double> const& residual_stiffness; Parameter<double> const& crack_resistance; Parameter<double> const& crack_length_scale; diff --git a/ProcessLib/ThermoMechanicalPhaseField/CreateThermoMechanicalPhaseFieldProcess.cpp b/ProcessLib/ThermoMechanicalPhaseField/CreateThermoMechanicalPhaseFieldProcess.cpp index be679ddd19e2982b0d8e3b3161d88f898ae37648..2deccc667b4c8c298298261b3168ba70814161d1 100644 --- a/ProcessLib/ThermoMechanicalPhaseField/CreateThermoMechanicalPhaseFieldProcess.cpp +++ b/ProcessLib/ThermoMechanicalPhaseField/CreateThermoMechanicalPhaseFieldProcess.cpp @@ -9,9 +9,12 @@ #include "CreateThermoMechanicalPhaseFieldProcess.h" -#include "MaterialLib/SolidModels/CreateLinearElasticIsotropic.h" -#include "MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h" +#include <cassert> + +#include "MaterialLib/SolidModels/CreateConstitutiveRelation.h" +#include "MaterialLib/SolidModels/MechanicsBase.h" #include "ProcessLib/Output/CreateSecondaryVariables.h" +#include "ProcessLib/Utils/ProcessUtils.h" #include "ThermoMechanicalPhaseFieldProcess.h" #include "ThermoMechanicalPhaseFieldProcessData.h" @@ -88,8 +91,7 @@ std::unique_ptr<Process> createThermoMechanicalPhaseFieldProcess( if (variable_ph->getNumberOfComponents() != 1) { OGS_FATAL( - "Phase field process variable '%s' is not a scalar variable but " - "has " + "Phasefield process variable '%s' is not a scalar variable but has " "%d components.", variable_ph->getName().c_str(), variable_ph->getNumberOfComponents()); @@ -107,11 +109,9 @@ std::unique_ptr<Process> createThermoMechanicalPhaseFieldProcess( variable_T->getNumberOfComponents()); } - // Constitutive relation. - // read type; - auto const constitutive_relation_config = - //! \ogs_file_param{prj__processes__process__THERMO_MECHANICAL_PHASE_FIELD__constitutive_relation} - config.getConfigSubtree("constitutive_relation"); + auto solid_constitutive_relations = + MaterialLib::Solids::createConstitutiveRelations<DisplacementDim>( + parameters, config); auto const phasefield_parameters_config = //! \ogs_file_param{prj__processes__process__THERMO_MECHANICAL_PHASE_FIELD__phasefield_parameters} @@ -121,30 +121,6 @@ std::unique_ptr<Process> createThermoMechanicalPhaseFieldProcess( //! \ogs_file_param{prj__processes__process__THERMO_MECHANICAL_PHASE_FIELD__thermal_parameters} config.getConfigSubtree("thermal_parameters"); - auto const type = - //! \ogs_file_param{prj__processes__process__THERMO_MECHANICAL_PHASE_FIELD__constitutive_relation__type} - constitutive_relation_config.peekConfigParameter<std::string>("type"); - - std::unique_ptr<MaterialLib::Solids::PhaseFieldExtension<DisplacementDim>> - material = nullptr; - if (type == "LinearElasticIsotropic") - { - const bool skip_type_checking = false; - auto elastic_model = - MaterialLib::Solids::createLinearElasticIsotropic<DisplacementDim>( - parameters, constitutive_relation_config, skip_type_checking); - material = std::make_unique< - MaterialLib::Solids::LinearElasticIsotropicPhaseField< - DisplacementDim>>( - std::move(elastic_model->getMaterialProperties())); - } - else - { - OGS_FATAL( - "Cannot construct constitutive relation of given type \'%s\'.", - type.c_str()); - } - // Residual stiffness auto& residual_stiffness = findParameter<double>( phasefield_parameters_config, @@ -234,7 +210,8 @@ std::unique_ptr<Process> createThermoMechanicalPhaseFieldProcess( } ThermoMechanicalPhaseFieldProcessData<DisplacementDim> process_data{ - std::move(material), + materialIDs(mesh), + std::move(solid_constitutive_relations), residual_stiffness, crack_resistance, crack_length_scale, diff --git a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldFEM.h b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldFEM.h index d7741e0e8abcde82671d2b55392df10fe9cf0ec7..774b7fc7fe79c9856c398de875050b98fcb981e1 100644 --- a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldFEM.h +++ b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldFEM.h @@ -12,7 +12,9 @@ #include <memory> #include <vector> -#include "MaterialLib/SolidModels/PhaseFieldExtension.h" +#include "MaterialLib/SolidModels/LinearElasticIsotropic.h" +#include "MaterialLib/SolidModels/LinearElasticIsotropicPhaseField.h" +#include "MaterialLib/SolidModels/SelectSolidConstitutiveRelation.h" #include "MathLib/LinAlg/Eigen/EigenMapTools.h" #include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h" #include "NumLib/Fem/ShapeMatrixPolicy.h" @@ -70,7 +72,7 @@ struct IntegrationPointData final template <typename DisplacementVectorType> void updateConstitutiveRelation(double const t, - SpatialPosition const& x_position, + SpatialPosition const& x, double const /*dt*/, DisplacementVectorType const& /*u*/, double const alpha, @@ -79,13 +81,18 @@ struct IntegrationPointData final { eps_m.noalias() = eps - alpha * delta_T * Invariants::identity2; - static_cast< - MaterialLib::Solids::PhaseFieldExtension<DisplacementDim> const&>( - solid_material) - .calculateDegradedStress( - t, x_position, eps_m, strain_energy_tensile, sigma_tensile, - sigma_compressive, C_tensile, C_compressive, sigma, degradation, - elastic_energy); + auto linear_elastic_mp = + static_cast<MaterialLib::Solids::LinearElasticIsotropic< + DisplacementDim> const&>(solid_material) + .getMaterialProperties(); + + auto const bulk_modulus = linear_elastic_mp.bulk_modulus(t, x); + auto const mu = linear_elastic_mp.mu(t, x); + + std::tie(sigma, sigma_tensile, C_tensile, C_compressive, + strain_energy_tensile, elastic_energy) = + MaterialLib::Solids::Phasefield::calculateDegradedStress< + DisplacementDim>(degradation, bulk_modulus, mu, eps_m); } EIGEN_MAKE_ALIGNED_OPERATOR_NEW; }; @@ -143,6 +150,20 @@ public: _ip_data.reserve(n_integration_points); _secondary_data.N.resize(n_integration_points); + auto& solid_material = + MaterialLib::Solids::selectSolidConstitutiveRelation( + _process_data.solid_materials, + _process_data.material_ids, + e.getID()); + if (!dynamic_cast<MaterialLib::Solids::LinearElasticIsotropic< + DisplacementDim> const*>(&solid_material)) + { + OGS_FATAL( + "For phasefield process only linear elastic solid material " + "support is implemented."); + } + + auto const shape_matrices = initShapeMatrices<ShapeFunction, ShapeMatricesType, IntegrationMethod, DisplacementDim>( @@ -153,8 +174,7 @@ public: for (unsigned ip = 0; ip < n_integration_points; ip++) { - // displacement (subscript u) - _ip_data.emplace_back(*_process_data.material); + _ip_data.emplace_back(solid_material); auto& ip_data = _ip_data[ip]; ip_data.integration_weight = _integration_method.getWeightedPoint(ip).getWeight() * @@ -336,8 +356,8 @@ private: IntegrationMethod _integration_method; MeshLib::Element const& _element; - bool const _is_axially_symmetric; SecondaryData<typename ShapeMatrices::ShapeType> _secondary_data; + bool const _is_axially_symmetric; static const int temperature_index = 0; static const int temperature_size = ShapeFunction::NPOINTS; diff --git a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcessData.h b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcessData.h index cc667114bb69c59d0bc00f1f91f620077c23aedf..46dbe556f1ddfdee0d165e8fcc37d50f0650a72f 100644 --- a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcessData.h +++ b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcessData.h @@ -33,8 +33,11 @@ template <int DisplacementDim> struct ThermoMechanicalPhaseFieldProcessData { ThermoMechanicalPhaseFieldProcessData( - std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>>&& - material_, + MeshLib::PropertyVector<int> const* const material_ids_, + std::map<int, + std::unique_ptr< + MaterialLib::Solids::MechanicsBase<DisplacementDim>>>&& + solid_materials_, Parameter<double> const& residual_stiffness_, Parameter<double> const& crack_resistance_, Parameter<double> const& crack_length_scale_, @@ -46,7 +49,8 @@ struct ThermoMechanicalPhaseFieldProcessData Parameter<double> const& residual_thermal_conductivity_, double const reference_temperature_, Eigen::Matrix<double, DisplacementDim, 1> const& specific_body_force_) - : material{std::move(material_)}, + : material_ids(material_ids_), + solid_materials{std::move(solid_materials_)}, residual_stiffness(residual_stiffness_), crack_resistance(crack_resistance_), crack_length_scale(crack_length_scale_), @@ -63,24 +67,7 @@ struct ThermoMechanicalPhaseFieldProcessData } ThermoMechanicalPhaseFieldProcessData( - ThermoMechanicalPhaseFieldProcessData&& other) - : material{std::move(other.material)}, - residual_stiffness(other.residual_stiffness), - crack_resistance(other.crack_resistance), - crack_length_scale(other.crack_length_scale), - kinetic_coefficient(other.kinetic_coefficient), - solid_density(other.solid_density), - linear_thermal_expansion_coefficient( - other.linear_thermal_expansion_coefficient), - specific_heat_capacity(other.specific_heat_capacity), - thermal_conductivity(other.thermal_conductivity), - residual_thermal_conductivity(other.residual_thermal_conductivity), - reference_temperature(other.reference_temperature), - specific_body_force(other.specific_body_force), - dt(other.dt), - t(other.t) - { - } + ThermoMechanicalPhaseFieldProcessData&& other) = default; //! Copies are forbidden. ThermoMechanicalPhaseFieldProcessData( @@ -92,8 +79,11 @@ struct ThermoMechanicalPhaseFieldProcessData //! Assignments are not needed. void operator=(ThermoMechanicalPhaseFieldProcessData&&) = delete; - std::unique_ptr<MaterialLib::Solids::MechanicsBase<DisplacementDim>> - material; + MeshLib::PropertyVector<int> const* const material_ids; + + std::map<int, std::unique_ptr< + MaterialLib::Solids::MechanicsBase<DisplacementDim>>> + solid_materials; Parameter<double> const& residual_stiffness; Parameter<double> const& crack_resistance; Parameter<double> const& crack_length_scale;