Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include "Conversion.h" 13 : #include "InputParameters.h" 14 : #include "Material.h" 15 : 16 : /** 17 : * TangentCalculationMethod is an enum that determines the calculation method for the tangent 18 : * operator. ELASTIC uses the elasticity tensor as the tangent operator: J = C. The elasticity 19 : * tensor does not need to be provided by the StressUpdateBase models in this case. FULL calculates 20 : * the full tangent operator tensor in each inherited class. The full tangent operator is then 21 : * combined in ComputeMultipleInelasicStress by J = J_1 * C^-1 * J_2 * C^-1 * ... J_N. PARTIAL 22 : * calculates the contribution to the tangent operator if the terms need to be combined before being 23 : * inverted by J = (J_1 + J_2 + ... J_N)^-1 * C. 24 : */ 25 : enum class TangentCalculationMethod 26 : { 27 : ELASTIC, 28 : FULL, 29 : PARTIAL 30 : }; 31 : 32 : /** 33 : * StressUpdateBase is a material that is not called by MOOSE because 34 : * of the compute=false flag set in the parameter list. This class is a base class 35 : * for materials that perform some internal computational 36 : * procedure (such as an iterative return-mapping procedure) to compute an 37 : * admissible state (which is usually an admissible stress that lies on or 38 : * within the yield surface, as well as a set of internal parameters such as 39 : * plastic strains). The computational procedure must return the admissible stress 40 : * and a decomposition of the applied strain into elastic and inelastic components. 41 : * All materials inheriting from this class must be called by a separate material, 42 : * such as ComputeMultipleInelasticStress 43 : */ 44 : template <bool is_ad, typename R2 = RankTwoTensor, typename R4 = RankFourTensor> 45 : class StressUpdateBaseTempl : public Material 46 : { 47 : public: 48 : static InputParameters validParams(); 49 : 50 : StressUpdateBaseTempl(const InputParameters & parameters); 51 : 52 : using Material::_current_elem; 53 : using Material::_dt; 54 : using Material::_q_point; 55 : using Material::_qp; 56 : 57 : using GR2 = GenericRankTwoTensor<is_ad>; 58 : using GSR2 = Moose::GenericType<R2, is_ad>; 59 : using GR4 = GenericRankFourTensor<is_ad>; 60 : using GSR4 = Moose::GenericType<R4, is_ad>; 61 : 62 : /** 63 : * Given a strain increment that results in a trial stress, perform some 64 : * procedure (such as an iterative return-mapping process) to produce 65 : * an admissible stress, an elastic strain increment and an inelastic 66 : * strain increment. 67 : * If _fe_problem.currentlyComputingJacobian() = true, then updateState also computes 68 : * d(stress)/d(strain) (or some approximation to it). 69 : * 70 : * This method is called by ComputeMultipleInelasticStress. 71 : * This method is pure virutal: all inheriting classes must overwrite this method. 72 : * 73 : * @param strain_increment Upon input: the strain increment. Upon output: the elastic strain 74 : * increment 75 : * @param inelastic_strain_increment The inelastic_strain resulting from the interative procedure 76 : * @param rotation_increment The finite-strain rotation increment 77 : * @param stress_new Upon input: the trial stress that results from applying strain_increment as 78 : * an elastic strain. Upon output: the admissible stress 79 : * @param stress_old The old value of stress 80 : * @param elasticity_tensor The elasticity tensor 81 : * @param compute_full_tangent_operator The calling routine would like the full consistent tangent 82 : * operator to be placed in tangent_operator, if possible. This is irrelevant if 83 : * _fe_problem.currentlyComputingJacobian() = false 84 : * @param tangent_operator d(stress)/d(strain), or some approximation to it If 85 : * compute_full_tangent_operator=false, then tangent_operator=elasticity_tensor is an appropriate 86 : * choice. tangent_operator is only computed if _fe_problem.currentlyComputingJacobian() = true 87 : */ 88 : virtual void 89 : updateState(GR2 & strain_increment, 90 : GR2 & inelastic_strain_increment, 91 : const GR2 & rotation_increment, 92 : GR2 & stress_new, 93 : const RankTwoTensor & stress_old, 94 : const GR4 & elasticity_tensor, 95 : const RankTwoTensor & elastic_strain_old, 96 : bool compute_full_tangent_operator = false, 97 : RankFourTensor & tangent_operator = StressUpdateBaseTempl<is_ad>::_identityTensor); 98 : 99 : /** 100 : * Similar to the updateState function, this method updates the strain and stress for one substep 101 : */ 102 : virtual void updateStateSubstep( 103 : GR2 & /*strain_increment*/, 104 : GR2 & /*inelastic_strain_increment*/, 105 : const GR2 & /*rotation_increment*/, 106 : GR2 & /*stress_new*/, 107 : const RankTwoTensor & /*stress_old*/, 108 : const GR4 & /*elasticity_tensor*/, 109 : const RankTwoTensor & /*elastic_strain_old*/, 110 : bool compute_full_tangent_operator = false, 111 : RankFourTensor & tangent_operator = StressUpdateBaseTempl<is_ad>::_identityTensor); 112 : 113 : /// Sets the value of the global variable _qp for inheriting classes 114 : void setQp(unsigned int qp); 115 : 116 : /** 117 : * If updateState is not called during a timestep, this will be. This method allows derived 118 : * classes to set internal parameters from their Old values, for instance 119 : */ 120 : virtual void propagateQpStatefulProperties(); 121 : 122 : /** 123 : * Does the model require the elasticity tensor to be isotropic? 124 : */ 125 : virtual bool requiresIsotropicTensor() = 0; 126 : 127 : /** 128 : * Is the implmented model isotropic? The safe default is 'false'. 129 : */ 130 1230 : virtual bool isIsotropic() { return false; }; 131 : 132 : virtual Real computeTimeStepLimit(); 133 : 134 : virtual TangentCalculationMethod getTangentCalculationMethod(); 135 : 136 : ///@{ Retained as empty methods to avoid a warning from Material.C in framework. These methods are unused in all inheriting classes and should not be overwritten. 137 0 : void resetQpProperties() final {} 138 5449362 : void resetProperties() final {} 139 : ///@} 140 : 141 : /** 142 : * Does the model include the infrastructure for substep decomposition of the 143 : * elastic strain initially used to calculate the trial stress guess 144 : * Inheriting classes which wish to use the substepping capability should 145 : * overwrite this method and set it to return true. 146 : */ 147 11686060 : virtual bool substeppingCapabilityEnabled() { return false; } 148 : 149 : /** 150 : * Has the user requested usage of (possibly) implemented substepping capability for inelastic 151 : * models. 152 : */ 153 2742 : virtual bool substeppingCapabilityRequested() { return false; } 154 : 155 : /** 156 : * Given the elastic strain increment compute the number of substeps required 157 : * to bring a substepped trial stress guess distance from the yield surface 158 : * into the tolerance specified in the individual child class. 159 : */ 160 0 : virtual int calculateNumberSubsteps(const GR2 & /*strain_increment*/) { return 1; } 161 : 162 : /** 163 : * Properly set up the incremental calculation storage of the stateful material 164 : * properties in the inheriting classes 165 : */ 166 : virtual void 167 588976 : storeIncrementalMaterialProperties(const unsigned int /*total_number_of_substeps*/){}; 168 : 169 : /** 170 : * Reset material properties. Useful for substepping with inelastic models. 171 : */ 172 16184642 : virtual void resetIncrementalMaterialProperties(){}; 173 : 174 : /** 175 : * Compute the strain energy rate density for this inelastic model for the current step. 176 : * @param stress The stress tensor at the end of the step 177 : * @param strain_rate The strain rate at the end of the step 178 : * @return The computed strain energy rate density 179 : */ 180 0 : virtual Real computeStrainEnergyRateDensity( 181 : const GenericMaterialProperty<RankTwoTensor, is_ad> & /*stress*/, 182 : const GenericMaterialProperty<RankTwoTensor, is_ad> & /*strain_rate*/) 183 : { 184 0 : mooseError( 185 : "The computation of strain energy rate density needs to be implemented by a child class"); 186 : return 0.0; 187 : } 188 : 189 : protected: 190 : /// Name used as a prefix for all material properties related to the stress update model. 191 : const std::string _base_name; 192 : 193 : static RankFourTensor _identityTensor; 194 : }; 195 : typedef StressUpdateBaseTempl<false> StressUpdateBase; 196 : typedef StressUpdateBaseTempl<true> ADStressUpdateBase; 197 : 198 : template <bool is_ad, typename R2, typename R4> 199 : RankFourTensor StressUpdateBaseTempl<is_ad, R2, R4>::_identityTensor = 200 : RankFourTensor(RankFourTensor::initIdentityFour);