https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
ComputeMultiPlasticityStress Class Reference

ComputeMultiPlasticityStress performs the return-map algorithm and associated stress updates for plastic models defined by a General User Objects. More...

#include <ComputeMultiPlasticityStress.h>

Inheritance diagram for ComputeMultiPlasticityStress:
[legend]

Public Types

typedef DerivativeMaterialPropertyNameInterface::SymbolName SymbolName
 

Public Member Functions

 ComputeMultiPlasticityStress (const InputParameters &parameters)
 
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialProperty (const std::string &name)
 
const GenericMaterialProperty< U, is_ad > & getDefaultMaterialPropertyByName (const std::string &name)
 
void validateDerivativeMaterialPropertyBase (const std::string &base)
 
const MaterialPropertyName derivativePropertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName derivativePropertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName derivativePropertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName derivativePropertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
GenericMaterialProperty< U, is_ad > & declarePropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, unsigned int v2, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, unsigned int v1, unsigned int v2=libMesh::invalid_uint, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, const SymbolName &c1, unsigned int v2, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivative (const std::string &base, unsigned int v1, unsigned int v2=libMesh::invalid_uint, unsigned int v3=libMesh::invalid_uint)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< VariableName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const std::vector< SymbolName > &c)
 
const GenericMaterialProperty< U, is_ad > & getMaterialPropertyDerivativeByName (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2="", const SymbolName &c3="")
 
void validateCoupling (const MaterialPropertyName &base, const std::vector< VariableName > &c, bool validate_aux=true)
 
void validateCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateCoupling (const MaterialPropertyName &base, const std::vector< VariableName > &c, bool validate_aux=true)
 
void validateCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateNonlinearCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
void validateNonlinearCoupling (const MaterialPropertyName &base, const VariableName &c1="", const VariableName &c2="", const VariableName &c3="")
 
const MaterialPropertyName propertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName propertyName (const MaterialPropertyName &base, const std::vector< SymbolName > &c) const
 
const MaterialPropertyName propertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName propertyNameFirst (const MaterialPropertyName &base, const SymbolName &c1) const
 
const MaterialPropertyName propertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName propertyNameSecond (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2) const
 
const MaterialPropertyName propertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 
const MaterialPropertyName propertyNameThird (const MaterialPropertyName &base, const SymbolName &c1, const SymbolName &c2, const SymbolName &c3) const
 
void outputAndCheckDebugParameters ()
 Outputs the debug parameters: _fspb_debug_stress, _fspd_debug_pm, etc and checks that they are sized correctly.
 
void checkDerivatives ()
 Checks the derivatives, eg dyieldFunction_dstress by using finite difference approximations.
 
void checkJacobian (const RankFourTensor &E_inv, const std::vector< Real > &intnl_old)
 Checks the full Jacobian, which is just certain linear combinations of the dyieldFunction_dstress, etc, by using finite difference approximations.
 
void checkSolution (const RankFourTensor &E_inv)
 Checks that Ax does equal b in the NR procedure.
 
UserObjectName getUserObjectName (const std::string &param_name) const
 
const TgetUserObject (const std::string &param_name, bool is_dependency=true) const
 
const TgetUserObjectByName (const UserObjectName &object_name, bool is_dependency=true) const
 
const UserObjectBasegetUserObjectBase (const std::string &param_name, bool is_dependency=true) const
 
const UserObjectBasegetUserObjectBaseByName (const UserObjectName &object_name, bool is_dependency=true) const
 
bool hasUserObject (const std::string &param_name) const
 
bool hasUserObject (const std::string &param_name) const
 
bool hasUserObject (const std::string &param_name) const
 
bool hasUserObject (const std::string &param_name) const
 
bool hasUserObjectByName (const UserObjectName &object_name) const
 
bool hasUserObjectByName (const UserObjectName &object_name) const
 
bool hasUserObjectByName (const UserObjectName &object_name) const
 
bool hasUserObjectByName (const UserObjectName &object_name) const
 

Static Public Member Functions

static InputParameters validParams ()
 

Protected Types

enum  TangentOperatorEnum { elastic , linear , nonlinear }
 The type of tangent operator to return. tangent operator = d(stress_rate)/d(strain_rate). More...
 
enum  DeactivationSchemeEnum {
  optimized , safe , dumb , optimized_to_safe ,
  safe_to_dumb , optimized_to_safe_to_dumb , optimized_to_dumb
}
 
enum  quickStep_called_from_t { computeQpStress_function , returnMap_function }
 The functions from which quickStep can be called. More...
 

Protected Member Functions

virtual void computeQpStress ()
 Compute the stress and store it in the _stress material property for the current quadrature point.
 
virtual void initQpStatefulProperties ()
 
virtual bool reinstateLinearDependentConstraints (std::vector< bool > &deactivated_due_to_ld)
 makes all deactivated_due_to_ld false, and if >0 of them were initially true, returns true
 
virtual unsigned int numberActive (const std::vector< bool > &active)
 counts the number of active constraints
 
virtual Real residual2 (const std::vector< Real > &pm, const std::vector< Real > &f, const RankTwoTensor &epp, const std::vector< Real > &ic, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld)
 The residual-squared.
 
virtual bool returnMap (const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &f, unsigned int &iter, bool can_revert_to_dumb, bool &linesearch_needed, bool &ld_encountered, bool &constraints_added, bool final_step, RankFourTensor &consistent_tangent_operator, std::vector< Real > &cumulative_pm)
 Implements the return map.
 
virtual bool lineSearch (Real &nr_res2, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, const RankFourTensor &E_inv, RankTwoTensor &delta_dp, const RankTwoTensor &dstress, const std::vector< Real > &dpm, const std::vector< Real > &dintnl, std::vector< Real > &f, RankTwoTensor &epp, std::vector< Real > &ic, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld, bool &linesearch_needed)
 Performs a line search.
 
virtual bool singleStep (Real &nr_res2, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, RankTwoTensor &delta_dp, const RankFourTensor &E_inv, std::vector< Real > &f, RankTwoTensor &epp, std::vector< Real > &ic, std::vector< bool > &active, DeactivationSchemeEnum deactivation_scheme, bool &linesearch_needed, bool &ld_encountered)
 Performs a single Newton-Raphson + linesearch step Constraints are deactivated and the step is re-done if deactivation_scheme is set appropriately.
 
virtual bool checkAdmissible (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< Real > &all_f)
 Checks whether the yield functions are in the admissible region.
 
void buildDumbOrder (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< unsigned int > &dumb_order)
 Builds the order which "dumb" activation will take.
 
virtual void incrementDumb (int &dumb_iteration, const std::vector< unsigned int > &dumb_order, std::vector< bool > &act)
 Increments "dumb_iteration" by 1, and sets "act" appropriately (act[alpha] = true iff alpha_th bit of dumb_iteration == 1)
 
virtual bool checkKuhnTucker (const std::vector< Real > &f, const std::vector< Real > &pm, const std::vector< bool > &active)
 Checks Kuhn-Tucker conditions, and alters "active" if appropriate.
 
virtual void applyKuhnTucker (const std::vector< Real > &f, const std::vector< Real > &pm, std::vector< bool > &active)
 Checks Kuhn-Tucker conditions, and alters "active" if appropriate.
 
virtual void preReturnMap ()
 
virtual void postReturnMap ()
 
virtual bool quickStep (const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, std::vector< Real > &cumulative_pm, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &yf, unsigned int &iterations, RankFourTensor &consistent_tangent_operator, const quickStep_called_from_t called_from, bool final_step)
 Attempts to find an admissible (stress, intnl) by using the customized return-map algorithms defined through the SolidMechanicsPlasticXXXX.returnMap functions.
 
virtual bool plasticStep (const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &yf, unsigned int &iterations, bool &linesearch_needed, bool &ld_encountered, bool &constraints_added, RankFourTensor &consistent_tangent_operator)
 performs a plastic step
 
bool canChangeScheme (DeactivationSchemeEnum current_deactivation_scheme, bool can_revert_to_dumb)
 
bool canIncrementDumb (int dumb_iteration)
 
void changeScheme (const std::vector< bool > &initial_act, bool can_revert_to_dumb, const RankTwoTensor &initial_stress, const std::vector< Real > &intnl_old, DeactivationSchemeEnum &current_deactivation_scheme, std::vector< bool > &act, int &dumb_iteration, std::vector< unsigned int > &dumb_order)
 
bool canAddConstraints (const std::vector< bool > &act, const std::vector< Real > &all_f)
 
unsigned int activeCombinationNumber (const std::vector< bool > &act)
 
RankFourTensor consistentTangentOperator (const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &E_ijkl, const std::vector< Real > &pm_this_step, const std::vector< Real > &cumulative_pm)
 Computes the consistent tangent operator (another name for the jacobian = d(stress_rate)/d(strain_rate)
 
virtual void computeQpProperties () override
 
virtual void calculateConstraints (const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, std::vector< Real > &f, std::vector< RankTwoTensor > &r, RankTwoTensor &epp, std::vector< Real > &ic, const std::vector< bool > &active)
 The constraints.
 
virtual void calculateRHS (const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, std::vector< Real > &rhs, const std::vector< bool > &active, bool eliminate_ld, std::vector< bool > &deactivated_due_to_ld)
 Calculate the RHS which is rhs = -(epp(0,0), epp(1,0), epp(1,1), epp(2,0), epp(2,1), epp(2,2), f[0], f[1], ..., f[num_f], ic[0], ic[1], ..., ic[num_ic])
 
virtual void calculateJacobian (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankFourTensor &E_inv, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld, std::vector< std::vector< Real > > &jac)
 d(rhs)/d(dof)
 
virtual void nrStep (const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankFourTensor &E_inv, const RankTwoTensor &delta_dp, RankTwoTensor &dstress, std::vector< Real > &dpm, std::vector< Real > &dintnl, const std::vector< bool > &active, std::vector< bool > &deactivated_due_to_ld)
 Performs one Newton-Raphson step.
 
virtual void yieldFunction (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &f)
 The active yield function(s)
 
virtual void dyieldFunction_dstress (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &df_dstress)
 The derivative of the active yield function(s) with respect to stress.
 
virtual void dyieldFunction_dintnl (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &df_dintnl)
 The derivative of active yield function(s) with respect to their internal parameters (the user objects assume there is exactly one internal param per yield function)
 
virtual void flowPotential (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &r)
 The active flow potential(s) - one for each yield function.
 
virtual void dflowPotential_dstress (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankFourTensor > &dr_dstress)
 The derivative of the active flow potential(s) with respect to stress.
 
virtual void dflowPotential_dintnl (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &dr_dintnl)
 The derivative of the active flow potentials with respect to the active internal parameters The UserObjects explicitly assume that r[alpha] is only dependent on intnl[alpha].
 
virtual void hardPotential (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &h)
 The active hardening potentials (one for each internal parameter and for each yield function) by assumption in the Userobjects, the h[a][alpha] is nonzero only if the surface alpha is part of model a, so we only calculate those here.
 
virtual void dhardPotential_dstress (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &dh_dstress)
 The derivative of the active hardening potentials with respect to stress By assumption in the Userobjects, the h[a][alpha] is nonzero only for a = alpha, so we only calculate those here.
 
virtual void dhardPotential_dintnl (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &dh_dintnl)
 The derivative of the active hardening potentials with respect to the active internal parameters.
 
virtual void buildActiveConstraints (const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
 Constructs a set of active constraints, given the yield functions, f.
 
unsigned int modelNumber (unsigned int surface)
 returns the model number, given the surface number
 
bool anyActiveSurfaces (int model, const std::vector< bool > &active)
 returns true if any internal surfaces of the given model are active according to 'active'
 
void activeModelSurfaces (int model, const std::vector< bool > &active, std::vector< unsigned int > &active_surfaces_of_model)
 Returns the internal surface number(s) of the active surfaces of the given model This may be of size=0 if there are no active surfaces of the given model.
 
void activeSurfaces (int model, const std::vector< bool > &active, std::vector< unsigned int > &active_surfaces)
 Returns the external surface number(s) of the active surfaces of the given model This may be of size=0 if there are no active surfaces of the given model.
 
bool returnMapAll (const RankTwoTensor &trial_stress, const std::vector< Real > &intnl_old, const RankFourTensor &E_ijkl, Real ep_plastic_tolerance, RankTwoTensor &stress, std::vector< Real > &intnl, std::vector< Real > &pm, std::vector< Real > &cumulative_pm, RankTwoTensor &delta_dp, std::vector< Real > &yf, unsigned &num_successful_plastic_returns, unsigned &custom_model)
 Performs a returnMap for each plastic model using their inbuilt returnMap functions.
 
virtual void addUserObjectDependencyHelper (const UserObjectBase &) const
 

Protected Attributes

unsigned int _max_iter
 Maximum number of Newton-Raphson iterations allowed.
 
Real _min_stepsize
 Minimum fraction of applied strain that may be applied during adaptive stepsizing.
 
Real _max_stepsize_for_dumb
 "dumb" deactivation will only be used if the stepsize falls below this quantity
 
bool _ignore_failures
 Even if the returnMap fails, return the best values found for stress and internal parameters.
 
enum ComputeMultiPlasticityStress::TangentOperatorEnum _tangent_operator_type
 
Real _epp_tol
 Tolerance on the plastic strain increment ("direction") constraint.
 
std::vector< Real > _dummy_pm
 dummy "consistency parameters" (plastic multipliers) used in quickStep when called from computeQpStress
 
std::vector< Real > _cumulative_pm
 the sum of the plastic multipliers over all the sub-steps.
 
enum ComputeMultiPlasticityStress::DeactivationSchemeEnum _deactivation_scheme
 
bool _n_supplied
 User supplied the transverse direction vector.
 
RealVectorValue _n_input
 the supplied transverse direction vector
 
RealTensorValue _rot
 rotation matrix that takes _n to (0, 0, 1)
 
bool _perform_finite_strain_rotations
 whether to perform the rotations necessary in finite-strain simulations
 
const std::string _elasticity_tensor_name
 Name of the elasticity tensor material property.
 
const MaterialProperty< RankFourTensor > & _elasticity_tensor
 Elasticity tensor material property.
 
MaterialProperty< RankTwoTensor > & _plastic_strain
 plastic strain
 
const MaterialProperty< RankTwoTensor > & _plastic_strain_old
 Old value of plastic strain.
 
MaterialProperty< std::vector< Real > > & _intnl
 internal parameters
 
const MaterialProperty< std::vector< Real > > & _intnl_old
 old values of internal parameters
 
MaterialProperty< std::vector< Real > > & _yf
 yield functions
 
MaterialProperty< Real > & _iter
 Number of Newton-Raphson iterations used in the return-map.
 
MaterialProperty< Real > & _linesearch_needed
 Whether a line-search was needed in the latest Newton-Raphson process (1 if true, 0 otherwise)
 
MaterialProperty< Real > & _ld_encountered
 Whether linear-dependence was encountered in the latest Newton-Raphson process (1 if true, 0 otherwise)
 
MaterialProperty< Real > & _constraints_added
 Whether constraints were added in during the latest Newton-Raphson process (1 if true, 0 otherwise)
 
MaterialProperty< RealVectorValue > & _n
 current value of transverse direction
 
const MaterialProperty< RealVectorValue > & _n_old
 old value of transverse direction
 
const MaterialProperty< RankTwoTensor > & _strain_increment
 strain increment (coming from ComputeIncrementalStrain, for example)
 
const MaterialProperty< RankTwoTensor > & _total_strain_old
 Old value of total strain (coming from ComputeIncrementalStrain, for example)
 
const MaterialProperty< RankTwoTensor > & _rotation_increment
 Rotation increment (coming from ComputeIncrementalStrain, for example)
 
const MaterialProperty< RankTwoTensor > & _stress_old
 Old value of stress.
 
const MaterialProperty< RankTwoTensor > & _elastic_strain_old
 Old value of elastic strain.
 
bool _cosserat
 whether Cosserat mechanics should be used
 
const MaterialProperty< RankTwoTensor > *const _curvature
 The Cosserat curvature strain.
 
const MaterialProperty< RankFourTensor > *const _elastic_flexural_rigidity_tensor
 The Cosserat elastic flexural rigidity tensor.
 
MaterialProperty< RankTwoTensor > *const _couple_stress
 the Cosserat couple-stress
 
const MaterialProperty< RankTwoTensor > *const _couple_stress_old
 the old value of Cosserat couple-stress
 
MaterialProperty< RankFourTensor > *const _Jacobian_mult_couple
 derivative of couple-stress w.r.t. curvature
 
RankFourTensor _my_elasticity_tensor
 Elasticity tensor that can be rotated by this class (ie, its not const)
 
RankTwoTensor _my_strain_increment
 Strain increment that can be rotated by this class, and split into multiple increments (ie, its not const)
 
RankFourTensor _my_flexural_rigidity_tensor
 Flexual rigidity tensor that can be rotated by this class (ie, its not const)
 
RankTwoTensor _my_curvature
 Curvature that can be rotated by this class, and split into multiple increments (ie, its not const)
 
const std::string _base_name
 Base name prepended to all material property names to allow for multi-material systems.
 
const MaterialProperty< RankTwoTensor > & _mechanical_strain
 Mechanical strain material property.
 
MaterialProperty< RankTwoTensor > & _stress
 Stress material property.
 
MaterialProperty< RankTwoTensor > & _elastic_strain
 Elastic strain material property.
 
const MaterialProperty< RankTwoTensor > & _extra_stress
 Extra stress tensor.
 
std::vector< const Function * > _initial_stress_fcn
 initial stress components
 
MaterialProperty< RankFourTensor > & _Jacobian_mult
 derivative of stress w.r.t. strain (_dstress_dstrain)
 
MooseEnum _fspb_debug
 none - don't do any debugging crash - currently inactive jacobian - check the jacobian entries jacobian_and_linear_system - check entire jacobian and check that Ax=b
 
RankTwoTensor _fspb_debug_stress
 Debug the Jacobian entries at this stress.
 
std::vector< Real > _fspb_debug_pm
 Debug the Jacobian entires at these plastic multipliers.
 
std::vector< Real > _fspb_debug_intnl
 Debug the Jacobian entires at these internal parameters.
 
Real _fspb_debug_stress_change
 Debug finite-differencing parameter for the stress.
 
std::vector< Real > _fspb_debug_pm_change
 Debug finite-differencing parameters for the plastic multipliers.
 
std::vector< Real > _fspb_debug_intnl_change
 Debug finite-differencing parameters for the internal parameters.
 
Real _svd_tol
 Tolerance on the minimum ratio of singular values before flow-directions are deemed linearly dependent.
 
Real _min_f_tol
 Minimum value of the _f_tol parameters for the Yield Function User Objects.
 
const InputParameters_params
 
unsigned int _num_models
 Number of plastic models for this material.
 
unsigned int _num_surfaces
 Number of surfaces within the plastic models.
 
std::vector< std::vector< unsigned int > > _surfaces_given_model
 _surfaces_given_model[model_number] = vector of surface numbers for this model
 
MooseEnum _specialIC
 Allows initial set of active constraints to be chosen optimally.
 
std::vector< const SolidMechanicsPlasticModel * > _f
 User objects that define the yield functions, flow potentials, etc.
 

Private Member Functions

RankTwoTensor rot (const RankTwoTensor &tens)
 
bool haveMaterialProperty (const std::string &prop_name)
 
std::vector< VariableName > buildVariableVector (const VariableName &c1, const VariableName &c2, const VariableName &c3)
 
void validateCouplingHelper (const MaterialPropertyName &base, const std::vector< VariableName > &c, const System &system, std::vector< VariableName > &missing)
 
bool isNotObjectVariable (const VariableName &name)
 
void fddyieldFunction_dstress (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankTwoTensor > &df_dstress)
 The finite-difference derivative of yield function(s) with respect to stress.
 
void fddyieldFunction_dintnl (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< Real > &df_dintnl)
 The finite-difference derivative of yield function(s) with respect to internal parameter(s)
 
virtual void fddflowPotential_dstress (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankFourTensor > &dr_dstress)
 The finite-difference derivative of the flow potential(s) with respect to stress.
 
virtual void fddflowPotential_dintnl (const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankTwoTensor > &dr_dintnl)
 The finite-difference derivative of the flow potentials with respect to internal parameters.
 
virtual void fdJacobian (const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, const RankFourTensor &E_inv, bool eliminate_ld, std::vector< std::vector< Real > > &jac)
 The Jacobian calculated using finite differences.
 
bool dof_included (unsigned int dof, const std::vector< bool > &deactivated_due_to_ld)
 
virtual int singularValuesOfR (const std::vector< RankTwoTensor > &r, std::vector< Real > &s)
 Performs a singular-value decomposition of r and returns the singular values.
 
virtual void eliminateLinearDependence (const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< Real > &f, const std::vector< RankTwoTensor > &r, const std::vector< bool > &active, std::vector< bool > &deactivated_due_to_ld)
 Performs a number of singular-value decompositions to check for linear-dependence of the active directions "r" If linear dependence is found, then deactivated_due_to_ld will contain 'true' entries where surfaces need to be deactivated_due_to_ld.
 
void buildActiveConstraintsRock (const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
 "Rock" version Constructs a set of active constraints, given the yield functions, f.
 
void buildActiveConstraintsJoint (const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
 "Joint" version Constructs a set of active constraints, given the yield functions, f.
 
const UserObjectBasegetUserObjectFromFEProblem (const UserObjectName &object_name, const THREAD_ID tid=0) const
 
const TcastUserObject (const UserObjectBase &uo_base, const std::string &param_name="") const
 
void mooseObjectError (const std::string &param_name, std::stringstream &oss) const
 
const std::string & userObjectType (const UserObjectBase &uo) const
 
const std::string & userObjectName (const UserObjectBase &uo) const
 

Private Attributes

FEProblemBase_dmi_fe_problem
 
std::vector< unsigned int_model_given_surface
 given a surface number, this returns the model number
 
std::vector< unsigned int_model_surface_given_surface
 given a surface number, this returns the corresponding-model's internal surface number
 
const MooseObject_uoi_moose_object
 
const FEProblemBase_uoi_feproblem
 
const THREAD_ID _uoi_tid
 

Detailed Description

ComputeMultiPlasticityStress performs the return-map algorithm and associated stress updates for plastic models defined by a General User Objects.

Note that if run in debug mode you might have to use the –no-trap-fpe flag because PETSc-LAPACK-BLAS explicitly compute 0/0 and 1/0, and this causes Libmesh to trap the floating-point exceptions

Definition at line 25 of file ComputeMultiPlasticityStress.h.

Member Enumeration Documentation

◆ DeactivationSchemeEnum

◆ quickStep_called_from_t

The functions from which quickStep can be called.

Enumerator
computeQpStress_function 
returnMap_function 

Definition at line 440 of file ComputeMultiPlasticityStress.h.

◆ TangentOperatorEnum

The type of tangent operator to return. tangent operator = d(stress_rate)/d(strain_rate).

Enumerator
elastic 
linear 
nonlinear 

Definition at line 49 of file ComputeMultiPlasticityStress.h.

Constructor & Destructor Documentation

◆ ComputeMultiPlasticityStress()

ComputeMultiPlasticityStress::ComputeMultiPlasticityStress ( const InputParameters parameters)

Definition at line 97 of file ComputeMultiPlasticityStress.C.

98 : ComputeStressBase(parameters),
100 _max_iter(getParam<unsigned int>("max_NR_iterations")),
101 _min_stepsize(getParam<Real>("min_stepsize")),
102 _max_stepsize_for_dumb(getParam<Real>("max_stepsize_for_dumb")),
103 _ignore_failures(getParam<bool>("ignore_failures")),
104
105 _tangent_operator_type((TangentOperatorEnum)(int)getParam<MooseEnum>("tangent_operator")),
106
107 _epp_tol(getParam<Real>("ep_plastic_tolerance")),
108
109 _dummy_pm(0),
110
112
113 _deactivation_scheme((DeactivationSchemeEnum)(int)getParam<MooseEnum>("deactivation_scheme")),
114
115 _n_supplied(parameters.isParamValid("transverse_direction")),
116 _n_input(_n_supplied ? getParam<RealVectorValue>("transverse_direction") : RealVectorValue()),
118
119 _perform_finite_strain_rotations(getParam<bool>("perform_finite_strain_rotations")),
120
121 _elasticity_tensor_name(_base_name + "elasticity_tensor"),
122 _elasticity_tensor(getMaterialPropertyByName<RankFourTensor>(_elasticity_tensor_name)),
123 _plastic_strain(declareProperty<RankTwoTensor>("plastic_strain")),
124 _plastic_strain_old(getMaterialPropertyOld<RankTwoTensor>("plastic_strain")),
125 _intnl(declareProperty<std::vector<Real>>("plastic_internal_parameter")),
126 _intnl_old(getMaterialPropertyOld<std::vector<Real>>("plastic_internal_parameter")),
127 _yf(declareProperty<std::vector<Real>>("plastic_yield_function")),
128 _iter(declareProperty<Real>("plastic_NR_iterations")), // this is really an unsigned int, but
129 // for visualisation i convert it to Real
130 _linesearch_needed(declareProperty<Real>("plastic_linesearch_needed")), // this is really a
131 // boolean, but for
132 // visualisation i
133 // convert it to Real
134 _ld_encountered(declareProperty<Real>(
135 "plastic_linear_dependence_encountered")), // this is really a boolean, but for
136 // visualisation i convert it to Real
137 _constraints_added(declareProperty<Real>("plastic_constraints_added")), // this is really a
138 // boolean, but for
139 // visualisation i
140 // convert it to Real
141 _n(declareProperty<RealVectorValue>("plastic_transverse_direction")),
142 _n_old(getMaterialPropertyOld<RealVectorValue>("plastic_transverse_direction")),
143
144 _strain_increment(getMaterialPropertyByName<RankTwoTensor>(_base_name + "strain_increment")),
145 _total_strain_old(getMaterialPropertyOldByName<RankTwoTensor>(_base_name + "total_strain")),
147 getMaterialPropertyByName<RankTwoTensor>(_base_name + "rotation_increment")),
148
149 _stress_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "stress")),
150 _elastic_strain_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "elastic_strain")),
151
152 // TODO: This design does NOT work. It makes these materials construction order dependent and it
153 // disregards block restrictions.
154 _cosserat(hasMaterialProperty<RankTwoTensor>("curvature") &&
155 hasMaterialProperty<RankFourTensor>("elastic_flexural_rigidity_tensor")),
156 _curvature(_cosserat ? &getMaterialPropertyByName<RankTwoTensor>("curvature") : nullptr),
158 _cosserat ? &getMaterialPropertyByName<RankFourTensor>("elastic_flexural_rigidity_tensor")
159 : nullptr),
160 _couple_stress(_cosserat ? &declareProperty<RankTwoTensor>("couple_stress") : nullptr),
161 _couple_stress_old(_cosserat ? &getMaterialPropertyOld<RankTwoTensor>("couple_stress")
162 : nullptr),
163 _Jacobian_mult_couple(_cosserat ? &declareProperty<RankFourTensor>("couple_Jacobian_mult")
164 : nullptr),
165
170{
171 if (_epp_tol <= 0)
172 mooseError("ComputeMultiPlasticityStress: ep_plastic_tolerance must be positive");
173
174 if (_n_supplied)
175 {
176 // normalise the inputted transverse_direction
177 if (_n_input.norm() == 0)
179 "ComputeMultiPlasticityStress: transverse_direction vector must not have zero length");
180 else
181 _n_input /= _n_input.norm();
182 }
183
184 if (_num_surfaces == 1)
186}
void mooseError(Args &&... args)
const std::string _base_name
Base name prepended to all material property names to allow for multi-material systems.
MaterialProperty< RealVectorValue > & _n
current value of transverse direction
Real _epp_tol
Tolerance on the plastic strain increment ("direction") constraint.
MaterialProperty< std::vector< Real > > & _yf
yield functions
RealTensorValue _rot
rotation matrix that takes _n to (0, 0, 1)
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor material property.
Real _max_stepsize_for_dumb
"dumb" deactivation will only be used if the stepsize falls below this quantity
std::vector< Real > _cumulative_pm
the sum of the plastic multipliers over all the sub-steps.
const MaterialProperty< RealVectorValue > & _n_old
old value of transverse direction
const MaterialProperty< RankTwoTensor > *const _curvature
The Cosserat curvature strain.
Real _min_stepsize
Minimum fraction of applied strain that may be applied during adaptive stepsizing.
bool _n_supplied
User supplied the transverse direction vector.
bool _perform_finite_strain_rotations
whether to perform the rotations necessary in finite-strain simulations
const MaterialProperty< RankTwoTensor > & _elastic_strain_old
Old value of elastic strain.
const MaterialProperty< RankTwoTensor > & _total_strain_old
Old value of total strain (coming from ComputeIncrementalStrain, for example)
RankTwoTensor _my_strain_increment
Strain increment that can be rotated by this class, and split into multiple increments (ie,...
MaterialProperty< RankFourTensor > *const _Jacobian_mult_couple
derivative of couple-stress w.r.t. curvature
MaterialProperty< Real > & _ld_encountered
Whether linear-dependence was encountered in the latest Newton-Raphson process (1 if true,...
RankFourTensor _my_elasticity_tensor
Elasticity tensor that can be rotated by this class (ie, its not const)
bool _ignore_failures
Even if the returnMap fails, return the best values found for stress and internal parameters.
const MaterialProperty< std::vector< Real > > & _intnl_old
old values of internal parameters
MaterialProperty< RankTwoTensor > *const _couple_stress
the Cosserat couple-stress
MaterialProperty< Real > & _iter
Number of Newton-Raphson iterations used in the return-map.
MaterialProperty< Real > & _constraints_added
Whether constraints were added in during the latest Newton-Raphson process (1 if true,...
const MaterialProperty< RankTwoTensor > & _strain_increment
strain increment (coming from ComputeIncrementalStrain, for example)
const MaterialProperty< RankTwoTensor > *const _couple_stress_old
the old value of Cosserat couple-stress
unsigned int _max_iter
Maximum number of Newton-Raphson iterations allowed.
RealVectorValue _n_input
the supplied transverse direction vector
std::vector< Real > _dummy_pm
dummy "consistency parameters" (plastic multipliers) used in quickStep when called from computeQpStre...
MaterialProperty< RankTwoTensor > & _plastic_strain
plastic strain
MaterialProperty< Real > & _linesearch_needed
Whether a line-search was needed in the latest Newton-Raphson process (1 if true, 0 otherwise)
const MaterialProperty< RankTwoTensor > & _stress_old
Old value of stress.
const MaterialProperty< RankFourTensor > *const _elastic_flexural_rigidity_tensor
The Cosserat elastic flexural rigidity tensor.
const std::string _elasticity_tensor_name
Name of the elasticity tensor material property.
const MaterialProperty< RankTwoTensor > & _plastic_strain_old
Old value of plastic strain.
TangentOperatorEnum
The type of tangent operator to return. tangent operator = d(stress_rate)/d(strain_rate).
bool _cosserat
whether Cosserat mechanics should be used
RankTwoTensor _my_curvature
Curvature that can be rotated by this class, and split into multiple increments (ie,...
const MaterialProperty< RankTwoTensor > & _rotation_increment
Rotation increment (coming from ComputeIncrementalStrain, for example)
RankFourTensor _my_flexural_rigidity_tensor
Flexual rigidity tensor that can be rotated by this class (ie, its not const)
MaterialProperty< std::vector< Real > > & _intnl
internal parameters
ComputeStressBase is the base class for stress tensors computed from MOOSE's strain calculators.
bool isParamValid(const std::string &name) const
MultiPlasticityDebugger computes various finite-difference things to help developers remove bugs in t...
unsigned int _num_surfaces
Number of surfaces within the plastic models.
TensorValue< Real > RealTensorValue
VectorValue< Real > RealVectorValue
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

Member Function Documentation

◆ activeCombinationNumber()

unsigned int ComputeMultiPlasticityStress::activeCombinationNumber ( const std::vector< bool > &  act)
protected

Definition at line 1572 of file ComputeMultiPlasticityStress.C.

1573{
1574 unsigned num = 0;
1575 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1576 if (act[surface])
1577 num += (1 << surface); // (1 << x) = 2^x
1578
1579 return num;
1580}

Referenced by returnMap().

◆ activeModelSurfaces()

void MultiPlasticityRawComponentAssembler::activeModelSurfaces ( int  model,
const std::vector< bool > &  active,
std::vector< unsigned int > &  active_surfaces_of_model 
)
protectedinherited

Returns the internal surface number(s) of the active surfaces of the given model This may be of size=0 if there are no active surfaces of the given model.

Parameters
modelthe model number
activearray with entries being 'true' if the surface is active
[out]active_surfaces_of_modelthe output

Definition at line 809 of file MultiPlasticityRawComponentAssembler.C.

813{
814 active_surfaces_of_model.resize(0);
815 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
816 if (active[_surfaces_given_model[model][model_surface]])
817 active_surfaces_of_model.push_back(model_surface);
818}
const PertinentGeochemicalSystem model(database, {"H2O", "H+", "HCO3-", "O2(aq)", "Ca++", ">(s)FeOH", "radius_neg1", "radius_neg1.5"}, {"Calcite"}, {}, {"Calcite_asdf"}, {"CH4(aq)"}, {">(s)FeOCa+"}, "O2(aq)", "e-")
std::vector< const SolidMechanicsPlasticModel * > _f
User objects that define the yield functions, flow potentials, etc.
std::vector< std::vector< unsigned int > > _surfaces_given_model
_surfaces_given_model[model_number] = vector of surface numbers for this model

Referenced by MultiPlasticityRawComponentAssembler::dflowPotential_dintnl(), MultiPlasticityRawComponentAssembler::dflowPotential_dstress(), MultiPlasticityRawComponentAssembler::dhardPotential_dintnl(), MultiPlasticityRawComponentAssembler::dhardPotential_dstress(), MultiPlasticityRawComponentAssembler::dyieldFunction_dintnl(), MultiPlasticityRawComponentAssembler::dyieldFunction_dstress(), MultiPlasticityRawComponentAssembler::flowPotential(), MultiPlasticityRawComponentAssembler::hardPotential(), and MultiPlasticityRawComponentAssembler::yieldFunction().

◆ activeSurfaces()

void MultiPlasticityRawComponentAssembler::activeSurfaces ( int  model,
const std::vector< bool > &  active,
std::vector< unsigned int > &  active_surfaces 
)
protectedinherited

Returns the external surface number(s) of the active surfaces of the given model This may be of size=0 if there are no active surfaces of the given model.

Parameters
modelthe model number
activearray with entries being 'true' if the surface is active
[out]active_surfacesthe output

Definition at line 798 of file MultiPlasticityRawComponentAssembler.C.

801{
802 active_surfaces.resize(0);
803 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
804 if (active[_surfaces_given_model[model][model_surface]])
805 active_surfaces.push_back(_surfaces_given_model[model][model_surface]);
806}

Referenced by MultiPlasticityLinearSystem::calculateConstraints().

◆ anyActiveSurfaces()

bool MultiPlasticityRawComponentAssembler::anyActiveSurfaces ( int  model,
const std::vector< bool > &  active 
)
protectedinherited

returns true if any internal surfaces of the given model are active according to 'active'

Definition at line 789 of file MultiPlasticityRawComponentAssembler.C.

790{
791 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
792 if (active[_surfaces_given_model[model][model_surface]])
793 return true;
794 return false;
795}

Referenced by MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityLinearSystem::calculateRHS(), MultiPlasticityDebugger::checkSolution(), MultiPlasticityDebugger::dof_included(), MultiPlasticityLinearSystem::nrStep(), and residual2().

◆ applyKuhnTucker()

void ComputeMultiPlasticityStress::applyKuhnTucker ( const std::vector< Real > &  f,
const std::vector< Real > &  pm,
std::vector< bool > &  active 
)
protectedvirtual

Checks Kuhn-Tucker conditions, and alters "active" if appropriate.

Do not let the simplicity of this routine fool you! Explicitly: (1) checks that pm = 0 for all the f < 0. If not, then active is set to false for that constraint. This may be triggered if upon exit of the NR loops a constraint got deactivated due to linear dependence, and then f<0 and its pm>0. (2) checks that pm = 0 for all inactive constraints. This should always be true unless someone has screwed with the code. (3) if any pm < 0, then active is set to false for that constraint. This may be triggered if _deactivation_scheme!="optimized".

Parameters
fvalues of the active yield functions
pmvalues of all the plastic multipliers
activethe active constraints (true if active)
Returns
return false if any of the Kuhn-Tucker conditions were violated (and hence the set of active constraints was changed)

Definition at line 1311 of file ComputeMultiPlasticityStress.C.

1314{
1315 bool turned_off = false;
1316 unsigned ind = 0;
1317
1318 // turn off all active surfaces that have f<0 and pm!=0
1319 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1320 {
1321 if (active[surface])
1322 {
1323 if (f[ind++] < -_f[modelNumber(surface)]->_f_tol)
1324 if (pm[surface] != 0)
1325 {
1326 turned_off = true;
1327 active[surface] = false;
1328 }
1329 }
1330 else if (pm[surface] != 0)
1331 mooseError("Crash due to plastic multiplier not being zero. This occurred because of poor "
1332 "coding!!");
1333 }
1334
1335 // if didn't turn off anything yet, turn off surface with minimum pm
1336 if (!turned_off)
1337 {
1338 int surface_to_turn_off = -1;
1339 Real min_pm = 0;
1340 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1341 if (pm[surface] < min_pm)
1342 {
1343 min_pm = pm[surface];
1344 surface_to_turn_off = surface;
1345 }
1346 if (surface_to_turn_off >= 0)
1347 active[surface_to_turn_off] = false;
1348 }
1349}
Real f(Real x)
Test function for Brents method.
unsigned int modelNumber(unsigned int surface)
returns the model number, given the surface number

Referenced by returnMap().

◆ buildActiveConstraints()

void MultiPlasticityRawComponentAssembler::buildActiveConstraints ( const std::vector< Real > &  f,
const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const RankFourTensor Eijkl,
std::vector< bool > &  act 
)
protectedvirtualinherited

Constructs a set of active constraints, given the yield functions, f.

This uses SolidMechanicsPlasticModel::activeConstraints to identify the active constraints for each model.

Parameters
fyield functions (should be _num_surfaces of these)
stressstress tensor
intnlinternal parameters
Eijklelasticity tensor (stress = Eijkl*strain)
[out]actthe set of active constraints (will be resized to _num_surfaces)

Definition at line 342 of file MultiPlasticityRawComponentAssembler.C.

347{
348 mooseAssert(f.size() == _num_surfaces,
349 "buildActiveConstraints called with f.size = " << f.size() << " while there are "
350 << _num_surfaces << " surfaces");
351 mooseAssert(intnl.size() == _num_models,
352 "buildActiveConstraints called with intnl.size = "
353 << intnl.size() << " while there are " << _num_models << " models");
354
355 if (_specialIC == "rock")
356 buildActiveConstraintsRock(f, stress, intnl, Eijkl, act);
357 else if (_specialIC == "joint")
358 buildActiveConstraintsJoint(f, stress, intnl, Eijkl, act);
359 else // no specialIC
360 {
361 act.resize(0);
362 unsigned ind = 0;
363 for (unsigned model = 0; model < _num_models; ++model)
364 {
365 std::vector<Real> model_f(0);
366 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
367 model_f.push_back(f[ind++]);
368 std::vector<bool> model_act;
369 RankTwoTensor returned_stress;
370 _f[model]->activeConstraints(
371 model_f, stress, intnl[model], Eijkl, model_act, returned_stress);
372 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
373 act.push_back(model_act[model_surface]);
374 }
375 }
376}
void buildActiveConstraintsRock(const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
"Rock" version Constructs a set of active constraints, given the yield functions, f.
void buildActiveConstraintsJoint(const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
"Joint" version Constructs a set of active constraints, given the yield functions,...
unsigned int _num_models
Number of plastic models for this material.
MooseEnum _specialIC
Allows initial set of active constraints to be chosen optimally.

Referenced by returnMap().

◆ buildActiveConstraintsJoint()

void MultiPlasticityRawComponentAssembler::buildActiveConstraintsJoint ( const std::vector< Real > &  f,
const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const RankFourTensor Eijkl,
std::vector< bool > &  act 
)
privateinherited

"Joint" version Constructs a set of active constraints, given the yield functions, f.

This uses SolidMechanicsPlasticModel::activeConstraints to identify the active constraints for each model.

Parameters
fyield functions (should be _num_surfaces of these)
stressstress tensor
intnlinternal parameters
Eijklelasticity tensor (stress = Eijkl*strain)
[out]actthe set of active constraints (will be resized to _num_surfaces)

Definition at line 379 of file MultiPlasticityRawComponentAssembler.C.

384{
385 act.assign(2, false);
386
387 RankTwoTensor returned_stress;
388 std::vector<bool> active_tensile;
389 std::vector<bool> active_shear;
390 std::vector<Real> f_single;
391
392 // first try tensile alone
393 f_single.assign(1, 0);
394 f_single[0] = f[0];
395 _f[0]->activeConstraints(f_single, stress, intnl[0], Eijkl, active_tensile, returned_stress);
396 _f[1]->yieldFunctionV(returned_stress, intnl[1], f_single);
397 if (f_single[0] <= _f[1]->_f_tol)
398 {
399 act[0] = active_tensile[0];
400 return;
401 }
402
403 // next try shear alone
404 f_single.assign(1, 0);
405 f_single[0] = f[1];
406 _f[1]->activeConstraints(f_single, stress, intnl[1], Eijkl, active_shear, returned_stress);
407 _f[0]->yieldFunctionV(returned_stress, intnl[0], f_single);
408 if (f_single[0] <= _f[0]->_f_tol)
409 {
410 act[1] = active_shear[0];
411 return;
412 }
413
414 // must be mixed
415 act[0] = act[1] = true;
416 return;
417}

Referenced by MultiPlasticityRawComponentAssembler::buildActiveConstraints().

◆ buildActiveConstraintsRock()

void MultiPlasticityRawComponentAssembler::buildActiveConstraintsRock ( const std::vector< Real > &  f,
const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const RankFourTensor Eijkl,
std::vector< bool > &  act 
)
privateinherited

"Rock" version Constructs a set of active constraints, given the yield functions, f.

This uses SolidMechanicsPlasticModel::activeConstraints to identify the active constraints for each model.

Parameters
fyield functions (should be _num_surfaces of these)
stressstress tensor
intnlinternal parameters
Eijklelasticity tensor (stress = Eijkl*strain)
[out]actthe set of active constraints (will be resized to _num_surfaces)

Definition at line 420 of file MultiPlasticityRawComponentAssembler.C.

425{
426 act.assign(9, false);
427
428 RankTwoTensor returned_stress;
429 std::vector<bool> active_tensile;
430 std::vector<bool> active_MC;
431 std::vector<Real> f_single;
432
433 // first try tensile alone
434 f_single.assign(3, 0);
435 f_single[0] = f[0];
436 f_single[1] = f[1];
437 f_single[2] = f[2];
438 _f[0]->activeConstraints(f_single, stress, intnl[0], Eijkl, active_tensile, returned_stress);
439 _f[1]->yieldFunctionV(returned_stress, intnl[1], f_single);
440 if (f_single[0] <= _f[1]->_f_tol && f_single[1] <= _f[1]->_f_tol &&
441 f_single[2] <= _f[1]->_f_tol && f_single[3] <= _f[1]->_f_tol &&
442 f_single[4] <= _f[1]->_f_tol && f_single[5] <= _f[1]->_f_tol)
443 {
444 act[0] = active_tensile[0];
445 act[1] = active_tensile[1];
446 act[2] = active_tensile[2];
447 return;
448 }
449
450 // next try MC alone
451 f_single.assign(6, 0);
452 f_single[0] = f[3];
453 f_single[1] = f[4];
454 f_single[2] = f[5];
455 f_single[3] = f[6];
456 f_single[4] = f[7];
457 f_single[5] = f[8];
458 _f[1]->activeConstraints(f_single, stress, intnl[1], Eijkl, active_MC, returned_stress);
459 _f[0]->yieldFunctionV(returned_stress, intnl[0], f_single);
460 if (f_single[0] <= _f[0]->_f_tol && f_single[1] <= _f[0]->_f_tol && f_single[2] <= _f[0]->_f_tol)
461 {
462 act[3] = active_MC[0];
463 act[4] = active_MC[1];
464 act[5] = active_MC[2];
465 act[6] = active_MC[3];
466 act[7] = active_MC[4];
467 act[8] = active_MC[5];
468 return;
469 }
470
471 // must be a mix.
472 // The possibilities are enumerated below.
473
474 // tensile=edge, MC=tip (two possibilities)
475 if (active_tensile[0] == false && active_tensile[1] == true && active_tensile[2] == true &&
476 active_MC[0] == true && active_MC[1] == true && active_MC[2] == false &&
477 active_MC[3] == true && active_MC[4] == false && active_MC[5] == false)
478 {
479 act[1] = act[2] = act[6] = true;
480 act[4] = true;
481 return;
482 }
483 if (active_tensile[0] == false && active_tensile[1] == true && active_tensile[2] == true &&
484 active_MC[0] == false && active_MC[1] == true && active_MC[2] == false &&
485 active_MC[3] == true && active_MC[4] == false && active_MC[5] == true)
486 {
487 act[1] = act[2] = act[6] = true; // i don't think act[4] is necessary, is it?!
488 return;
489 }
490
491 // tensile = edge, MC=edge (two possibilities)
492 if (active_tensile[0] == false && active_tensile[1] == true && active_tensile[2] == true &&
493 active_MC[0] == false && active_MC[1] == true && active_MC[2] == false &&
494 active_MC[3] == true && active_MC[4] == false && active_MC[5] == false)
495 {
496 act[1] = act[2] = act[4] = act[6] = true;
497 return;
498 }
499 if (active_tensile[0] == false && active_tensile[1] == true && active_tensile[2] == true &&
500 active_MC[0] == false && active_MC[1] == false && active_MC[2] == false &&
501 active_MC[3] == true && active_MC[4] == false && active_MC[5] == true)
502 {
503 act[1] = act[2] = act[4] = act[6] = true;
504 return;
505 }
506
507 // tensile = edge, MC=face
508 if (active_tensile[0] == false && active_tensile[1] == true && active_tensile[2] == true &&
509 active_MC[0] == false && active_MC[1] == false && active_MC[2] == false &&
510 active_MC[3] == true && active_MC[4] == false && active_MC[5] == false)
511 {
512 act[1] = act[2] = act[6] = true;
513 return;
514 }
515
516 // tensile = face, MC=tip (two possibilities)
517 if (active_tensile[0] == false && active_tensile[1] == false && active_tensile[2] == true &&
518 active_MC[0] == true && active_MC[1] == true && active_MC[2] == false &&
519 active_MC[3] == true && active_MC[4] == false && active_MC[5] == false)
520 {
521 act[2] = act[6] = true;
522 act[4] = true;
523 act[8] = true;
524 return;
525 }
526 if (active_tensile[0] == false && active_tensile[1] == false && active_tensile[2] == true &&
527 active_MC[0] == false && active_MC[1] == true && active_MC[2] == false &&
528 active_MC[3] == true && active_MC[4] == false && active_MC[5] == true)
529 {
530 act[2] = act[6] = true;
531 act[8] = true;
532 return;
533 }
534
535 // tensile = face, MC=face
536 if (active_tensile[0] == false && active_tensile[1] == false && active_tensile[2] == true &&
537 active_MC[0] == false && active_MC[1] == false && active_MC[2] == false &&
538 active_MC[3] == true && active_MC[4] == false && active_MC[5] == false)
539 {
540 act[1] = act[2] = act[6] = true;
541 return;
542 }
543
544 // tensile = face, MC=edge (two possibilites).
545 act[2] = true; // tensile face
546 act[3] = active_MC[0];
547 act[4] = active_MC[1];
548 act[5] = active_MC[2];
549 act[6] = active_MC[3];
550 act[7] = active_MC[4];
551 act[8] = active_MC[5];
552 return;
553}

Referenced by MultiPlasticityRawComponentAssembler::buildActiveConstraints().

◆ buildDumbOrder()

void ComputeMultiPlasticityStress::buildDumbOrder ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< unsigned int > &  dumb_order 
)
protected

Builds the order which "dumb" activation will take.

Parameters
stressstress to evaluate yield functions and derivatives at
intnlinternal parameters to evaluate yield functions and derivatives at
[out]dumb_orderdumb_order[0] will be the yield surface furthest away from (stress, intnl), dumb_order[1] will be the next yield surface, etc. The distance measure used is f/|df_dstress|. This array can then be fed into incrementDumb in order to first try the yield surfaces which are farthest away from the (stress, intnl).

Definition at line 1522 of file ComputeMultiPlasticityStress.C.

1525{
1526 if (dumb_order.size() != 0)
1527 return;
1528
1529 std::vector<bool> act;
1530 act.assign(_num_surfaces, true);
1531
1532 std::vector<Real> f;
1533 yieldFunction(stress, intnl, act, f);
1534 std::vector<RankTwoTensor> df_dstress;
1535 dyieldFunction_dstress(stress, intnl, act, df_dstress);
1536
1537 typedef std::pair<Real, unsigned> pair_for_sorting;
1538 std::vector<pair_for_sorting> dist(_num_surfaces);
1539 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1540 {
1541 dist[surface].first = f[surface] / df_dstress[surface].L2norm();
1542 dist[surface].second = surface;
1543 }
1544 std::sort(dist.begin(), dist.end()); // sorted in ascending order of f/df_dstress
1545
1546 dumb_order.resize(_num_surfaces);
1547 for (unsigned i = 0; i < _num_surfaces; ++i)
1548 dumb_order[i] = dist[_num_surfaces - 1 - i].second;
1549 // now dumb_order[0] is the surface with the greatest f/df_dstress
1550}
virtual void dyieldFunction_dstress(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &df_dstress)
The derivative of the active yield function(s) with respect to stress.
virtual void yieldFunction(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &f)
The active yield function(s)

Referenced by changeScheme(), and returnMap().

◆ calculateConstraints()

void MultiPlasticityLinearSystem::calculateConstraints ( const RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
const std::vector< Real > &  intnl,
const std::vector< Real > &  pm,
const RankTwoTensor delta_dp,
std::vector< Real > &  f,
std::vector< RankTwoTensor > &  r,
RankTwoTensor epp,
std::vector< Real > &  ic,
const std::vector< bool > &  active 
)
protectedvirtualinherited

The constraints.

These are set to zero (or <=0 in the case of the yield functions) by the Newton-Raphson process, except in the case of linear-dependence which complicates things.

Parameters
stressThe stress
intnl_oldold values of the internal parameters
intnlinternal parameters
pmCurrent value(s) of the plasticity multiplier(s) (consistency parameters)
delta_dpChange in plastic strain incurred so far during the return
[out]fActive yield function(s)
[out]rActive flow directions
[out]eppPlastic-strain increment constraint
[out]icActive internal-parameter constraint
activeThe active constraints.

Definition at line 227 of file MultiPlasticityLinearSystem.C.

237{
238 // see comments at the start of .h file
239
240 mooseAssert(intnl_old.size() == _num_models,
241 "Size of intnl_old is " << intnl_old.size()
242 << " which is incorrect in calculateConstraints");
243 mooseAssert(intnl.size() == _num_models,
244 "Size of intnl is " << intnl.size() << " which is incorrect in calculateConstraints");
245 mooseAssert(pm.size() == _num_surfaces,
246 "Size of pm is " << pm.size() << " which is incorrect in calculateConstraints");
247 mooseAssert(active.size() == _num_surfaces,
248 "Size of active is " << active.size()
249 << " which is incorrect in calculateConstraints");
250
251 // yield functions
252 yieldFunction(stress, intnl, active, f);
253
254 // flow directions and "epp"
255 flowPotential(stress, intnl, active, r);
256 epp = RankTwoTensor();
257 unsigned ind = 0;
258 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
259 if (active[surface])
260 epp += pm[surface] * r[ind++]; // note, even the deactivated_due_to_ld must get added in
261 epp -= delta_dp;
262
263 // internal constraints
264 std::vector<Real> h;
265 hardPotential(stress, intnl, active, h);
266 ic.resize(0);
267 ind = 0;
268 std::vector<unsigned int> active_surfaces;
269 std::vector<unsigned int>::iterator active_surface;
270 for (unsigned model = 0; model < _num_models; ++model)
271 {
272 activeSurfaces(model, active, active_surfaces);
273 if (active_surfaces.size() > 0)
274 {
275 // some surfaces are active in this model, so must form an internal constraint
276 ic.push_back(intnl[model] - intnl_old[model]);
277 for (active_surface = active_surfaces.begin(); active_surface != active_surfaces.end();
278 ++active_surface)
279 ic[ic.size() - 1] += pm[*active_surface] * h[ind++]; // we know the correct one is h[ind]
280 // since it was constructed in the same
281 // manner
282 }
283 }
284}
virtual void hardPotential(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &h)
The active hardening potentials (one for each internal parameter and for each yield function) by assu...
void activeSurfaces(int model, const std::vector< bool > &active, std::vector< unsigned int > &active_surfaces)
Returns the external surface number(s) of the active surfaces of the given model This may be of size=...
virtual void flowPotential(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &r)
The active flow potential(s) - one for each yield function.

Referenced by MultiPlasticityLinearSystem::calculateRHS(), and lineSearch().

◆ calculateJacobian()

void MultiPlasticityLinearSystem::calculateJacobian ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< Real > &  pm,
const RankFourTensor E_inv,
const std::vector< bool > &  active,
const std::vector< bool > &  deactivated_due_to_ld,
std::vector< std::vector< Real > > &  jac 
)
protectedvirtualinherited

d(rhs)/d(dof)

Definition at line 366 of file MultiPlasticityLinearSystem.C.

373{
374 // see comments at the start of .h file
375
376 mooseAssert(intnl.size() == _num_models,
377 "Size of intnl is " << intnl.size() << " which is incorrect in calculateJacobian");
378 mooseAssert(pm.size() == _num_surfaces,
379 "Size of pm is " << pm.size() << " which is incorrect in calculateJacobian");
380 mooseAssert(active.size() == _num_surfaces,
381 "Size of active is " << active.size() << " which is incorrect in calculateJacobian");
382 mooseAssert(deactivated_due_to_ld.size() == _num_surfaces,
383 "Size of deactivated_due_to_ld is " << deactivated_due_to_ld.size()
384 << " which is incorrect in calculateJacobian");
385
386 unsigned ind = 0;
387 unsigned active_surface_ind = 0;
388
389 std::vector<bool> active_surface(_num_surfaces); // active and not deactivated_due_to_ld
390 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
391 active_surface[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
392 unsigned num_active_surface = 0;
393 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
394 if (active_surface[surface])
395 num_active_surface++;
396
397 std::vector<bool> active_model(
398 _num_models); // whether a model has surfaces that are active and not deactivated_due_to_ld
399 for (unsigned model = 0; model < _num_models; ++model)
400 active_model[model] = anyActiveSurfaces(model, active_surface);
401
402 unsigned num_active_model = 0;
403 for (unsigned model = 0; model < _num_models; ++model)
404 if (active_model[model])
405 num_active_model++;
406
407 ind = 0;
408 std::vector<unsigned int> active_model_index(_num_models);
409 for (unsigned model = 0; model < _num_models; ++model)
410 if (active_model[model])
411 active_model_index[model] = ind++;
412 else
413 active_model_index[model] =
414 _num_models + 1; // just a dummy, that will probably cause a crash if something goes wrong
415
416 std::vector<RankTwoTensor> df_dstress;
417 dyieldFunction_dstress(stress, intnl, active_surface, df_dstress);
418
419 std::vector<Real> df_dintnl;
420 dyieldFunction_dintnl(stress, intnl, active_surface, df_dintnl);
421
422 std::vector<RankTwoTensor> r;
423 flowPotential(stress, intnl, active, r);
424
425 std::vector<RankFourTensor> dr_dstress;
426 dflowPotential_dstress(stress, intnl, active, dr_dstress);
427
428 std::vector<RankTwoTensor> dr_dintnl;
429 dflowPotential_dintnl(stress, intnl, active, dr_dintnl);
430
431 std::vector<Real> h;
432 hardPotential(stress, intnl, active, h);
433
434 std::vector<RankTwoTensor> dh_dstress;
435 dhardPotential_dstress(stress, intnl, active, dh_dstress);
436
437 std::vector<Real> dh_dintnl;
438 dhardPotential_dintnl(stress, intnl, active, dh_dintnl);
439
440 // d(epp)/dstress = sum_{active alpha} pm[alpha]*dr_dstress
441 RankFourTensor depp_dstress;
442 ind = 0;
443 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
444 if (active[surface]) // includes deactivated_due_to_ld
445 depp_dstress += pm[surface] * dr_dstress[ind++];
446 depp_dstress += E_inv;
447
448 // d(epp)/dpm_{active_surface_index} = r_{active_surface_index}
449 std::vector<RankTwoTensor> depp_dpm;
450 depp_dpm.resize(num_active_surface);
451 ind = 0;
452 active_surface_ind = 0;
453 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
454 {
455 if (active[surface])
456 {
457 if (active_surface[surface]) // do not include the deactived_due_to_ld, since their pm are not
458 // dofs in the NR
459 depp_dpm[active_surface_ind++] = r[ind];
460 ind++;
461 }
462 }
463
464 // d(epp)/dintnl_{active_model_index} = sum(pm[asdf]*dr_dintnl[fdsa])
465 std::vector<RankTwoTensor> depp_dintnl;
466 depp_dintnl.assign(num_active_model, RankTwoTensor());
467 ind = 0;
468 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
469 {
470 if (active[surface])
471 {
472 unsigned int model_num = modelNumber(surface);
473 if (active_model[model_num]) // only include models with surfaces which are still active after
474 // deactivated_due_to_ld
475 depp_dintnl[active_model_index[model_num]] += pm[surface] * dr_dintnl[ind];
476 ind++;
477 }
478 }
479
480 // df_dstress has been calculated above
481 // df_dpm is always zero
482 // df_dintnl has been calculated above, but only the active_surface+active_model stuff needs to be
483 // included in Jacobian: see below
484
485 std::vector<RankTwoTensor> dic_dstress;
486 dic_dstress.assign(num_active_model, RankTwoTensor());
487 ind = 0;
488 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
489 {
490 if (active[surface])
491 {
492 unsigned int model_num = modelNumber(surface);
493 if (active_model[model_num]) // only include ic for models with active_surface (ie, if model
494 // only contains deactivated_due_to_ld don't include it)
495 dic_dstress[active_model_index[model_num]] += pm[surface] * dh_dstress[ind];
496 ind++;
497 }
498 }
499
500 std::vector<std::vector<Real>> dic_dpm;
501 dic_dpm.resize(num_active_model);
502 ind = 0;
503 active_surface_ind = 0;
504 for (unsigned model = 0; model < num_active_model; ++model)
505 dic_dpm[model].assign(num_active_surface, 0);
506 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
507 {
508 if (active[surface])
509 {
510 if (active_surface[surface]) // only take derivs wrt active-but-not-deactivated_due_to_ld pm
511 {
512 unsigned int model_num = modelNumber(surface);
513 // if (active_model[model_num]) // do not need this check as if the surface has
514 // active_surface, the model must be deemed active!
515 dic_dpm[active_model_index[model_num]][active_surface_ind] = h[ind];
516 active_surface_ind++;
517 }
518 ind++;
519 }
520 }
521
522 std::vector<std::vector<Real>> dic_dintnl;
523 dic_dintnl.resize(num_active_model);
524 for (unsigned model = 0; model < num_active_model; ++model)
525 {
526 dic_dintnl[model].assign(num_active_model, 0);
527 dic_dintnl[model][model] = 1; // deriv wrt internal parameter
528 }
529 ind = 0;
530 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
531 {
532 if (active[surface])
533 {
534 unsigned int model_num = modelNumber(surface);
535 if (active_model[model_num]) // only the models that contain surfaces that are still active
536 // after deactivation_due_to_ld
537 dic_dintnl[active_model_index[model_num]][active_model_index[model_num]] +=
538 pm[surface] * dh_dintnl[ind];
539 ind++;
540 }
541 }
542
543 unsigned int dim = 3;
544 unsigned int system_size =
545 6 + num_active_surface + num_active_model; // "6" comes from symmeterizing epp
546 jac.resize(system_size);
547 for (unsigned i = 0; i < system_size; ++i)
548 jac[i].assign(system_size, 0);
549
550 unsigned int row_num = 0;
551 unsigned int col_num = 0;
552 for (unsigned i = 0; i < dim; ++i)
553 for (unsigned j = 0; j <= i; ++j)
554 {
555 for (unsigned k = 0; k < dim; ++k)
556 for (unsigned l = 0; l <= k; ++l)
557 jac[col_num][row_num++] =
558 depp_dstress(i, j, k, l) +
559 (k != l ? depp_dstress(i, j, l, k)
560 : 0); // extra part is needed because i assume dstress(i, j) = dstress(j, i)
561 for (unsigned surface = 0; surface < num_active_surface; ++surface)
562 jac[col_num][row_num++] = depp_dpm[surface](i, j);
563 for (unsigned a = 0; a < num_active_model; ++a)
564 jac[col_num][row_num++] = depp_dintnl[a](i, j);
565 row_num = 0;
566 col_num++;
567 }
568
569 ind = 0;
570 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
571 if (active_surface[surface])
572 {
573 for (unsigned k = 0; k < dim; ++k)
574 for (unsigned l = 0; l <= k; ++l)
575 jac[col_num][row_num++] =
576 df_dstress[ind](k, l) +
577 (k != l ? df_dstress[ind](l, k)
578 : 0); // extra part is needed because i assume dstress(i, j) = dstress(j, i)
579 for (unsigned beta = 0; beta < num_active_surface; ++beta)
580 jac[col_num][row_num++] = 0; // df_dpm
581 for (unsigned model = 0; model < _num_models; ++model)
582 if (active_model[model]) // only use df_dintnl for models in active_model
583 {
584 if (modelNumber(surface) == model)
585 jac[col_num][row_num++] = df_dintnl[ind];
586 else
587 jac[col_num][row_num++] = 0;
588 }
589 ind++;
590 row_num = 0;
591 col_num++;
592 }
593
594 for (unsigned a = 0; a < num_active_model; ++a)
595 {
596 for (unsigned k = 0; k < dim; ++k)
597 for (unsigned l = 0; l <= k; ++l)
598 jac[col_num][row_num++] =
599 dic_dstress[a](k, l) +
600 (k != l ? dic_dstress[a](l, k)
601 : 0); // extra part is needed because i assume dstress(i, j) = dstress(j, i)
602 for (unsigned alpha = 0; alpha < num_active_surface; ++alpha)
603 jac[col_num][row_num++] = dic_dpm[a][alpha];
604 for (unsigned b = 0; b < num_active_model; ++b)
605 jac[col_num][row_num++] = dic_dintnl[a][b];
606 row_num = 0;
607 col_num++;
608 }
609
610 mooseAssert(col_num == system_size, "Incorrect filling of cols in Jacobian");
611}
unsigned int dim
bool anyActiveSurfaces(int model, const std::vector< bool > &active)
returns true if any internal surfaces of the given model are active according to 'active'
virtual void dhardPotential_dintnl(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &dh_dintnl)
The derivative of the active hardening potentials with respect to the active internal parameters.
virtual void dyieldFunction_dintnl(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< Real > &df_dintnl)
The derivative of active yield function(s) with respect to their internal parameters (the user object...
virtual void dflowPotential_dstress(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankFourTensor > &dr_dstress)
The derivative of the active flow potential(s) with respect to stress.
virtual void dhardPotential_dstress(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &dh_dstress)
The derivative of the active hardening potentials with respect to stress By assumption in the Userobj...
virtual void dflowPotential_dintnl(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< bool > &active, std::vector< RankTwoTensor > &dr_dintnl)
The derivative of the active flow potentials with respect to the active internal parameters The UserO...

Referenced by MultiPlasticityDebugger::checkJacobian(), MultiPlasticityDebugger::checkSolution(), and MultiPlasticityLinearSystem::nrStep().

◆ calculateRHS()

void MultiPlasticityLinearSystem::calculateRHS ( const RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
const std::vector< Real > &  intnl,
const std::vector< Real > &  pm,
const RankTwoTensor delta_dp,
std::vector< Real > &  rhs,
const std::vector< bool > &  active,
bool  eliminate_ld,
std::vector< bool > &  deactivated_due_to_ld 
)
protectedvirtualinherited

Calculate the RHS which is rhs = -(epp(0,0), epp(1,0), epp(1,1), epp(2,0), epp(2,1), epp(2,2), f[0], f[1], ..., f[num_f], ic[0], ic[1], ..., ic[num_ic])

Note that the 'epp' components only contain the upper diagonal. These contain flow directions and plasticity-multipliers for all active surfaces, even the deactivated_due_to_ld surfaces. Note that the 'f' components only contain the active and not deactivated_due_to_ld surfaces Note that the 'ic' components only contain the internal constraints for models which contain active and not deactivated_due_to_ld surfaces. They contain hardening-potentials and plasticity-multipliers for the active surfaces, even the deactivated_due_to_ld surfaces

Parameters
stressThe stress
intnl_oldold values of the internal parameters
intnlinternal parameters
pmCurrent value(s) of the plasticity multiplier(s) (consistency parameters)
delta_dpChange in plastic strain incurred so far during the return
[out]rhsthe rhs
activeThe active constraints.
eliminate_ldCheck for linear dependence of constraints and put the results into deactivated_due_to_ld. Usually this should be true, but for certain debug operations it should be false
[out]deactivated_due_to_ldconstraints deactivated due to linear-dependence of flow directions

Definition at line 287 of file MultiPlasticityLinearSystem.C.

296{
297 // see comments at the start of .h file
298
299 mooseAssert(intnl_old.size() == _num_models,
300 "Size of intnl_old is " << intnl_old.size() << " which is incorrect in calculateRHS");
301 mooseAssert(intnl.size() == _num_models,
302 "Size of intnl is " << intnl.size() << " which is incorrect in calculateRHS");
303 mooseAssert(pm.size() == _num_surfaces,
304 "Size of pm is " << pm.size() << " which is incorrect in calculateRHS");
305 mooseAssert(active.size() == _num_surfaces,
306 "Size of active is " << active.size() << " which is incorrect in calculateRHS");
307
308 std::vector<Real> f; // the yield functions
309 RankTwoTensor epp; // the plastic-strain constraint ("direction constraint")
310 std::vector<Real> ic; // the "internal constraints"
311
312 std::vector<RankTwoTensor> r;
313 calculateConstraints(stress, intnl_old, intnl, pm, delta_dp, f, r, epp, ic, active);
314
315 if (eliminate_ld)
316 eliminateLinearDependence(stress, intnl, f, r, active, deactivated_due_to_ld);
317 else
318 deactivated_due_to_ld.assign(_num_surfaces, false);
319
320 std::vector<bool> active_not_deact(_num_surfaces);
321 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
322 active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
323
324 unsigned num_active_f = 0;
325 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
326 if (active_not_deact[surface])
327 num_active_f++;
328
329 unsigned num_active_ic = 0;
330 for (unsigned model = 0; model < _num_models; ++model)
331 if (anyActiveSurfaces(model, active_not_deact))
332 num_active_ic++;
333
334 unsigned int dim = 3;
335 unsigned int system_size = 6 + num_active_f + num_active_ic; // "6" comes from symmeterizing epp,
336 // num_active_f comes from "f",
337 // num_active_f comes from "ic"
338
339 rhs.resize(system_size);
340
341 unsigned ind = 0;
342 for (unsigned i = 0; i < dim; ++i)
343 for (unsigned j = 0; j <= i; ++j)
344 rhs[ind++] = -epp(i, j);
345 unsigned active_surface = 0;
346 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
347 if (active[surface])
348 {
349 if (!deactivated_due_to_ld[surface])
350 rhs[ind++] = -f[active_surface];
351 active_surface++;
352 }
353 unsigned active_model = 0;
354 for (unsigned model = 0; model < _num_models; ++model)
355 if (anyActiveSurfaces(model, active))
356 {
357 if (anyActiveSurfaces(model, active_not_deact))
358 rhs[ind++] = -ic[active_model];
359 active_model++;
360 }
361
362 mooseAssert(ind == system_size, "Incorrect filling of the rhs in calculateRHS");
363}
virtual void calculateConstraints(const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, std::vector< Real > &f, std::vector< RankTwoTensor > &r, RankTwoTensor &epp, std::vector< Real > &ic, const std::vector< bool > &active)
The constraints.
virtual void eliminateLinearDependence(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< Real > &f, const std::vector< RankTwoTensor > &r, const std::vector< bool > &active, std::vector< bool > &deactivated_due_to_ld)
Performs a number of singular-value decompositions to check for linear-dependence of the active direc...

Referenced by MultiPlasticityDebugger::checkSolution(), MultiPlasticityDebugger::fdJacobian(), and MultiPlasticityLinearSystem::nrStep().

◆ canAddConstraints()

bool ComputeMultiPlasticityStress::canAddConstraints ( const std::vector< bool > &  act,
const std::vector< Real > &  all_f 
)
protected

Definition at line 1013 of file ComputeMultiPlasticityStress.C.

1015{
1016 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1017 if (!act[surface] && (all_f[surface] > _f[modelNumber(surface)]->_f_tol))
1018 return true;
1019 return false;
1020}

Referenced by returnMap().

◆ canChangeScheme()

bool ComputeMultiPlasticityStress::canChangeScheme ( DeactivationSchemeEnum  current_deactivation_scheme,
bool  can_revert_to_dumb 
)
protected

Definition at line 1023 of file ComputeMultiPlasticityStress.C.

1025{
1026 if (current_deactivation_scheme == optimized && _deactivation_scheme == optimized_to_safe)
1027 return true;
1028
1029 if (current_deactivation_scheme == optimized && _deactivation_scheme == optimized_to_safe_to_dumb)
1030 return true;
1031
1032 if (current_deactivation_scheme == safe && _deactivation_scheme == safe_to_dumb &&
1033 can_revert_to_dumb)
1034 return true;
1035
1036 if (current_deactivation_scheme == safe && _deactivation_scheme == optimized_to_safe_to_dumb &&
1037 can_revert_to_dumb)
1038 return true;
1039
1040 if (current_deactivation_scheme == optimized && _deactivation_scheme == optimized_to_dumb &&
1041 can_revert_to_dumb)
1042 return true;
1043
1044 return false;
1045}

Referenced by returnMap().

◆ canIncrementDumb()

bool ComputeMultiPlasticityStress::canIncrementDumb ( int  dumb_iteration)
protected

Definition at line 1565 of file ComputeMultiPlasticityStress.C.

1566{
1567 // (1 << _num_surfaces) = 2^_num_surfaces
1568 return ((dumb_iteration + 1) < (1 << _num_surfaces));
1569}

Referenced by returnMap().

◆ changeScheme()

void ComputeMultiPlasticityStress::changeScheme ( const std::vector< bool > &  initial_act,
bool  can_revert_to_dumb,
const RankTwoTensor initial_stress,
const std::vector< Real > &  intnl_old,
DeactivationSchemeEnum current_deactivation_scheme,
std::vector< bool > &  act,
int dumb_iteration,
std::vector< unsigned int > &  dumb_order 
)
protected

Definition at line 1048 of file ComputeMultiPlasticityStress.C.

1056{
1057 if (current_deactivation_scheme == optimized &&
1060 {
1061 current_deactivation_scheme = safe;
1062 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1063 act[surface] = initial_act[surface];
1064 }
1065 else if ((current_deactivation_scheme == safe &&
1068 can_revert_to_dumb) ||
1069 (current_deactivation_scheme == optimized && _deactivation_scheme == optimized_to_dumb &&
1070 can_revert_to_dumb))
1071 {
1072 current_deactivation_scheme = dumb;
1073 dumb_iteration = 0;
1074 buildDumbOrder(initial_stress, intnl_old, dumb_order);
1075 incrementDumb(dumb_iteration, dumb_order, act);
1076 }
1077}
virtual void incrementDumb(int &dumb_iteration, const std::vector< unsigned int > &dumb_order, std::vector< bool > &act)
Increments "dumb_iteration" by 1, and sets "act" appropriately (act[alpha] = true iff alpha_th bit of...
void buildDumbOrder(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< unsigned int > &dumb_order)
Builds the order which "dumb" activation will take.

Referenced by returnMap().

◆ checkAdmissible()

bool ComputeMultiPlasticityStress::checkAdmissible ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< Real > &  all_f 
)
protectedvirtual

Checks whether the yield functions are in the admissible region.

Parameters
stressstress
intnlinternal parameters
[out]all_fthe values of all the yield functions
Returns
return false if any yield functions exceed their tolerance

Definition at line 1269 of file ComputeMultiPlasticityStress.C.

1272{
1273 std::vector<bool> act;
1274 act.assign(_num_surfaces, true);
1275
1276 yieldFunction(stress, intnl, act, all_f);
1277
1278 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1279 if (all_f[surface] > _f[modelNumber(surface)]->_f_tol)
1280 return false;
1281
1282 return true;
1283}

Referenced by returnMap().

◆ checkDerivatives()

void MultiPlasticityDebugger::checkDerivatives ( )
inherited

Checks the derivatives, eg dyieldFunction_dstress by using finite difference approximations.

Definition at line 85 of file MultiPlasticityDebugger.C.

86{
87 Moose::err
88 << "\n\n++++++++++++++++++++++++\nChecking the derivatives\n++++++++++++++++++++++++\n";
90
91 std::vector<bool> act;
92 act.assign(_num_surfaces, true);
93
94 Moose::err << "\ndyieldFunction_dstress. Relative L2 norms.\n";
95 std::vector<RankTwoTensor> df_dstress;
96 std::vector<RankTwoTensor> fddf_dstress;
99 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
100 {
101 Moose::err << "surface = " << surface << " Relative L2norm = "
102 << 2 * (df_dstress[surface] - fddf_dstress[surface]).L2norm() /
103 (df_dstress[surface] + fddf_dstress[surface]).L2norm()
104 << "\n";
105 Moose::err << "Coded:\n";
106 df_dstress[surface].print();
107 Moose::err << "Finite difference:\n";
108 fddf_dstress[surface].print();
109 }
110
111 Moose::err << "\ndyieldFunction_dintnl.\n";
112 std::vector<Real> df_dintnl;
114 Moose::err << "Coded:\n";
115 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
116 Moose::err << df_dintnl[surface] << " ";
117 Moose::err << "\n";
118 std::vector<Real> fddf_dintnl;
120 Moose::err << "Finite difference:\n";
121 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
122 Moose::err << fddf_dintnl[surface] << " ";
123 Moose::err << "\n";
124
125 Moose::err << "\ndflowPotential_dstress. Relative L2 norms.\n";
126 std::vector<RankFourTensor> dr_dstress;
127 std::vector<RankFourTensor> fddr_dstress;
130 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
131 {
132 Moose::err << "surface = " << surface << " Relative L2norm = "
133 << 2 * (dr_dstress[surface] - fddr_dstress[surface]).L2norm() /
134 (dr_dstress[surface] + fddr_dstress[surface]).L2norm()
135 << "\n";
136 Moose::err << "Coded:\n";
137 dr_dstress[surface].print();
138 Moose::err << "Finite difference:\n";
139 fddr_dstress[surface].print();
140 }
141
142 Moose::err << "\ndflowPotential_dintnl. Relative L2 norms.\n";
143 std::vector<RankTwoTensor> dr_dintnl;
144 std::vector<RankTwoTensor> fddr_dintnl;
147 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
148 {
149 Moose::err << "surface = " << surface << " Relative L2norm = "
150 << 2 * (dr_dintnl[surface] - fddr_dintnl[surface]).L2norm() /
151 (dr_dintnl[surface] + fddr_dintnl[surface]).L2norm()
152 << "\n";
153 Moose::err << "Coded:\n";
154 dr_dintnl[surface].print();
155 Moose::err << "Finite difference:\n";
156 fddr_dintnl[surface].print();
157 }
158
159 Moose::err << std::flush;
160}
virtual void fddflowPotential_dstress(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankFourTensor > &dr_dstress)
The finite-difference derivative of the flow potential(s) with respect to stress.
RankTwoTensor _fspb_debug_stress
Debug the Jacobian entries at this stress.
void outputAndCheckDebugParameters()
Outputs the debug parameters: _fspb_debug_stress, _fspd_debug_pm, etc and checks that they are sized ...
std::vector< Real > _fspb_debug_intnl
Debug the Jacobian entires at these internal parameters.
virtual void fddflowPotential_dintnl(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankTwoTensor > &dr_dintnl)
The finite-difference derivative of the flow potentials with respect to internal parameters.
void fddyieldFunction_dstress(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< RankTwoTensor > &df_dstress)
The finite-difference derivative of yield function(s) with respect to stress.
void fddyieldFunction_dintnl(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< Real > &df_dintnl)
The finite-difference derivative of yield function(s) with respect to internal parameter(s)
T L2norm(const RankTwoTensorTempl< T > &r2tensor)

Referenced by initQpStatefulProperties(), and plasticStep().

◆ checkJacobian()

void MultiPlasticityDebugger::checkJacobian ( const RankFourTensor E_inv,
const std::vector< Real > &  intnl_old 
)
inherited

Checks the full Jacobian, which is just certain linear combinations of the dyieldFunction_dstress, etc, by using finite difference approximations.

Definition at line 163 of file MultiPlasticityDebugger.C.

165{
166 Moose::err << "\n\n+++++++++++++++++++++\nChecking the Jacobian\n+++++++++++++++++++++\n";
168
169 std::vector<bool> act;
170 act.assign(_num_surfaces, true);
171 std::vector<bool> deactivated_due_to_ld;
172 deactivated_due_to_ld.assign(_num_surfaces, false);
173
174 RankTwoTensor delta_dp = -E_inv * _fspb_debug_stress;
175
176 std::vector<std::vector<Real>> jac;
180 E_inv,
181 act,
182 deactivated_due_to_ld,
183 jac);
184
185 std::vector<std::vector<Real>> fdjac;
187 intnl_old,
190 delta_dp,
191 E_inv,
192 false,
193 fdjac);
194
195 Real L2_numer = 0;
196 Real L2_denom = 0;
197 for (unsigned row = 0; row < jac.size(); ++row)
198 for (unsigned col = 0; col < jac.size(); ++col)
199 {
200 L2_numer += Utility::pow<2>(jac[row][col] - fdjac[row][col]);
201 L2_denom += Utility::pow<2>(jac[row][col] + fdjac[row][col]);
202 }
203 Moose::err << "\nRelative L2norm = " << std::sqrt(L2_numer / L2_denom) / 0.5 << "\n";
204
205 Moose::err << "\nHand-coded Jacobian:\n";
206 for (unsigned row = 0; row < jac.size(); ++row)
207 {
208 for (unsigned col = 0; col < jac.size(); ++col)
209 Moose::err << jac[row][col] << " ";
210 Moose::err << "\n";
211 }
212
213 Moose::err << "Finite difference Jacobian:\n";
214 for (unsigned row = 0; row < fdjac.size(); ++row)
215 {
216 for (unsigned col = 0; col < fdjac.size(); ++col)
217 Moose::err << fdjac[row][col] << " ";
218 Moose::err << "\n";
219 }
220
221 Moose::err << std::flush;
222}
virtual void fdJacobian(const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, const RankFourTensor &E_inv, bool eliminate_ld, std::vector< std::vector< Real > > &jac)
The Jacobian calculated using finite differences.
std::vector< Real > _fspb_debug_pm
Debug the Jacobian entires at these plastic multipliers.
virtual void calculateJacobian(const RankTwoTensor &stress, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankFourTensor &E_inv, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld, std::vector< std::vector< Real > > &jac)
d(rhs)/d(dof)

Referenced by computeQpStress(), and plasticStep().

◆ checkKuhnTucker()

bool ComputeMultiPlasticityStress::checkKuhnTucker ( const std::vector< Real > &  f,
const std::vector< Real > &  pm,
const std::vector< bool > &  active 
)
protectedvirtual

Checks Kuhn-Tucker conditions, and alters "active" if appropriate.

Do not let the simplicity of this routine fool you! Explicitly: (1) checks that pm = 0 for all the f < 0. If not, then active is set to false for that constraint. This may be triggered if upon exit of the NR loops a constraint got deactivated due to linear dependence, and then f<0 and its pm>0. (2) checks that pm = 0 for all inactive constraints. This should always be true unless someone has screwed with the code. (3) if any pm < 0, then active is set to false for that constraint. This may be triggered if _deactivation_scheme!="optimized".

Parameters
fvalues of the active yield functions
pmvalues of all the plastic multipliers
activethe active constraints (true if active)
Returns
return false if any of the Kuhn-Tucker conditions were violated (and hence the set of active constraints was changed)

Definition at line 1286 of file ComputeMultiPlasticityStress.C.

1289{
1290 unsigned ind = 0;
1291 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1292 {
1293 if (active[surface])
1294 {
1295 if (f[ind++] < -_f[modelNumber(surface)]->_f_tol)
1296 if (pm[surface] != 0)
1297 return false;
1298 }
1299 else if (pm[surface] != 0)
1300 mooseError("Crash due to plastic multiplier not being zero. This occurred because of poor "
1301 "coding!!");
1302 }
1303 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1304 if (pm[surface] < 0)
1305 return false;
1306
1307 return true;
1308}

Referenced by returnMap().

◆ checkSolution()

void MultiPlasticityDebugger::checkSolution ( const RankFourTensor E_inv)
inherited

Checks that Ax does equal b in the NR procedure.

Definition at line 371 of file MultiPlasticityDebugger.C.

372{
373 Moose::err << "\n\n+++++++++++++++++++++\nChecking the Solution\n";
374 Moose::err << "(Ie, checking Ax = b)\n+++++++++++++++++++++\n";
376
377 std::vector<bool> act;
378 act.assign(_num_surfaces, true);
379 std::vector<bool> deactivated_due_to_ld;
380 deactivated_due_to_ld.assign(_num_surfaces, false);
381
382 RankTwoTensor delta_dp = -E_inv * _fspb_debug_stress;
383
384 std::vector<Real> orig_rhs;
389 delta_dp,
390 orig_rhs,
391 act,
392 true,
393 deactivated_due_to_ld);
394
395 Moose::err << "\nb = ";
396 for (unsigned i = 0; i < orig_rhs.size(); ++i)
397 Moose::err << orig_rhs[i] << " ";
398 Moose::err << "\n\n";
399
400 std::vector<std::vector<Real>> jac_coded;
404 E_inv,
405 act,
406 deactivated_due_to_ld,
407 jac_coded);
408
409 Moose::err
410 << "Before checking Ax=b is correct, check that the Jacobians given below are equal.\n";
411 Moose::err
412 << "The hand-coded Jacobian is used in calculating the solution 'x', given 'b' above.\n";
413 Moose::err << "Note that this only includes degrees of freedom that aren't deactivated due to "
414 "linear dependence.\n";
415 Moose::err << "Hand-coded Jacobian:\n";
416 for (unsigned row = 0; row < jac_coded.size(); ++row)
417 {
418 for (unsigned col = 0; col < jac_coded.size(); ++col)
419 Moose::err << jac_coded[row][col] << " ";
420 Moose::err << "\n";
421 }
422
423 deactivated_due_to_ld.assign(_num_surfaces,
424 false); // this potentially gets changed by nrStep, below
425 RankTwoTensor dstress;
426 std::vector<Real> dpm;
427 std::vector<Real> dintnl;
432 E_inv,
433 delta_dp,
434 dstress,
435 dpm,
436 dintnl,
437 act,
438 deactivated_due_to_ld);
439
440 std::vector<bool> active_not_deact(_num_surfaces);
441 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
442 active_not_deact[surface] = !deactivated_due_to_ld[surface];
443
444 std::vector<Real> x;
445 x.assign(orig_rhs.size(), 0);
446 unsigned ind = 0;
447 for (unsigned i = 0; i < 3; ++i)
448 for (unsigned j = 0; j <= i; ++j)
449 x[ind++] = dstress(i, j);
450 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
451 if (active_not_deact[surface])
452 x[ind++] = dpm[surface];
453 for (unsigned model = 0; model < _num_models; ++model)
454 if (anyActiveSurfaces(model, active_not_deact))
455 x[ind++] = dintnl[model];
456
457 mooseAssert(ind == orig_rhs.size(),
458 "Incorrect extracting of changes from NR solution in the "
459 "finite-difference checking of nrStep");
460
461 Moose::err << "\nThis yields x =";
462 for (unsigned i = 0; i < orig_rhs.size(); ++i)
463 Moose::err << x[i] << " ";
464 Moose::err << "\n";
465
466 std::vector<std::vector<Real>> jac_fd;
471 delta_dp,
472 E_inv,
473 true,
474 jac_fd);
475
476 Moose::err << "\nThe finite-difference Jacobian is used to multiply by this 'x',\n";
477 Moose::err << "in order to check that the solution is correct\n";
478 Moose::err << "Finite-difference Jacobian:\n";
479 for (unsigned row = 0; row < jac_fd.size(); ++row)
480 {
481 for (unsigned col = 0; col < jac_fd.size(); ++col)
482 Moose::err << jac_fd[row][col] << " ";
483 Moose::err << "\n";
484 }
485
486 Real L2_numer = 0;
487 Real L2_denom = 0;
488 for (unsigned row = 0; row < jac_coded.size(); ++row)
489 for (unsigned col = 0; col < jac_coded.size(); ++col)
490 {
491 L2_numer += Utility::pow<2>(jac_coded[row][col] - jac_fd[row][col]);
492 L2_denom += Utility::pow<2>(jac_coded[row][col] + jac_fd[row][col]);
493 }
494 Moose::err << "Relative L2norm of the hand-coded and finite-difference Jacobian is "
495 << std::sqrt(L2_numer / L2_denom) / 0.5 << "\n";
496
497 std::vector<Real> fd_times_x;
498 fd_times_x.assign(orig_rhs.size(), 0);
499 for (unsigned row = 0; row < orig_rhs.size(); ++row)
500 for (unsigned col = 0; col < orig_rhs.size(); ++col)
501 fd_times_x[row] += jac_fd[row][col] * x[col];
502
503 Moose::err << "\n(Finite-difference Jacobian)*x =\n";
504 for (unsigned i = 0; i < orig_rhs.size(); ++i)
505 Moose::err << fd_times_x[i] << " ";
506 Moose::err << "\n";
507 Moose::err << "Recall that b = \n";
508 for (unsigned i = 0; i < orig_rhs.size(); ++i)
509 Moose::err << orig_rhs[i] << " ";
510 Moose::err << "\n";
511
512 L2_numer = 0;
513 L2_denom = 0;
514 for (unsigned i = 0; i < orig_rhs.size(); ++i)
515 {
516 L2_numer += Utility::pow<2>(orig_rhs[i] - fd_times_x[i]);
517 L2_denom += Utility::pow<2>(orig_rhs[i] + fd_times_x[i]);
518 }
519 Moose::err << "\nRelative L2norm of these is " << std::sqrt(L2_numer / L2_denom) / 0.5
520 << std::endl;
521}
const std::vector< double > x
virtual void calculateRHS(const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankTwoTensor &delta_dp, std::vector< Real > &rhs, const std::vector< bool > &active, bool eliminate_ld, std::vector< bool > &deactivated_due_to_ld)
Calculate the RHS which is rhs = -(epp(0,0), epp(1,0), epp(1,1), epp(2,0), epp(2,1),...
virtual void nrStep(const RankTwoTensor &stress, const std::vector< Real > &intnl_old, const std::vector< Real > &intnl, const std::vector< Real > &pm, const RankFourTensor &E_inv, const RankTwoTensor &delta_dp, RankTwoTensor &dstress, std::vector< Real > &dpm, std::vector< Real > &dintnl, const std::vector< bool > &active, std::vector< bool > &deactivated_due_to_ld)
Performs one Newton-Raphson step.

Referenced by computeQpStress(), and plasticStep().

◆ computeQpProperties()

void ComputeGeneralStressBase::computeQpProperties ( )
overrideprotectedvirtualinherited

Definition at line 44 of file ComputeGeneralStressBase.C.

45{
47
48 // Add in extra stress
49 _stress[_qp] += _extra_stress[_qp];
50}
const MaterialProperty< RankTwoTensor > & _extra_stress
Extra stress tensor.
virtual void computeQpStress()=0
Compute the stress and store it in the _stress material property for the current quadrature point.
MaterialProperty< RankTwoTensor > & _stress
Stress material property.

◆ computeQpStress()

void ComputeMultiPlasticityStress::computeQpStress ( )
protectedvirtual

Compute the stress and store it in the _stress material property for the current quadrature point.

Implements ComputeGeneralStressBase.

Definition at line 219 of file ComputeMultiPlasticityStress.C.

220{
221 // the following "_my" variables can get rotated by preReturnMap and postReturnMap
224 if (_cosserat)
225 {
226 _my_flexural_rigidity_tensor = (*_elastic_flexural_rigidity_tensor)[_qp];
227 _my_curvature = (*_curvature)[_qp];
228 }
229
230 if (_fspb_debug == "jacobian_and_linear_system")
231 {
232 // cannot do this at initQpStatefulProperties level since E_ijkl is not defined
233 checkJacobian(_elasticity_tensor[_qp].invSymm(), _intnl_old[_qp]);
234 checkSolution(_elasticity_tensor[_qp].invSymm());
235 mooseError("Finite-differencing completed. Exiting with no error");
236 }
237
238 preReturnMap(); // do rotations to new frame if necessary
239
240 unsigned int number_iterations;
241 bool linesearch_needed = false;
242 bool ld_encountered = false;
243 bool constraints_added = false;
244
245 _cumulative_pm.assign(_num_surfaces, 0);
246 // try a "quick" return first - this can be purely elastic, or a customised plastic return defined
247 // by a SolidMechanicsPlasticXXXX UserObject
248 const bool found_solution = quickStep(rot(_stress_old[_qp]),
249 _stress[_qp],
250 _intnl_old[_qp],
251 _intnl[_qp],
252 _dummy_pm,
255 _plastic_strain[_qp],
258 _yf[_qp],
259 number_iterations,
260 _Jacobian_mult[_qp],
262 true);
263
264 // if not purely elastic or the customised stuff failed, do some plastic return
265 if (!found_solution)
267 _stress[_qp],
268 _intnl_old[_qp],
269 _intnl[_qp],
271 _plastic_strain[_qp],
274 _yf[_qp],
275 number_iterations,
276 linesearch_needed,
277 ld_encountered,
278 constraints_added,
279 _Jacobian_mult[_qp]);
280
281 if (_cosserat)
282 {
283 (*_couple_stress)[_qp] = (*_elastic_flexural_rigidity_tensor)[_qp] * _my_curvature;
284 (*_Jacobian_mult_couple)[_qp] = _my_flexural_rigidity_tensor;
285 }
286
287 postReturnMap(); // rotate back from new frame if necessary
288
289 _iter[_qp] = 1.0 * number_iterations;
290 _linesearch_needed[_qp] = linesearch_needed;
291 _ld_encountered[_qp] = ld_encountered;
292 _constraints_added[_qp] = constraints_added;
293
294 // Update measures of strain
297
298 // Rotate the tensors to the current configuration
300 {
302 _elastic_strain[_qp] =
303 _rotation_increment[_qp] * _elastic_strain[_qp] * _rotation_increment[_qp].transpose();
304 _plastic_strain[_qp] =
305 _rotation_increment[_qp] * _plastic_strain[_qp] * _rotation_increment[_qp].transpose();
306 }
307}
MaterialProperty< RankFourTensor > & _Jacobian_mult
derivative of stress w.r.t. strain (_dstress_dstrain)
MaterialProperty< RankTwoTensor > & _elastic_strain
Elastic strain material property.
virtual bool quickStep(const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, std::vector< Real > &cumulative_pm, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &yf, unsigned int &iterations, RankFourTensor &consistent_tangent_operator, const quickStep_called_from_t called_from, bool final_step)
Attempts to find an admissible (stress, intnl) by using the customized return-map algorithms defined ...
virtual bool plasticStep(const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &yf, unsigned int &iterations, bool &linesearch_needed, bool &ld_encountered, bool &constraints_added, RankFourTensor &consistent_tangent_operator)
performs a plastic step
RankTwoTensor rot(const RankTwoTensor &tens)
void checkSolution(const RankFourTensor &E_inv)
Checks that Ax does equal b in the NR procedure.
void checkJacobian(const RankFourTensor &E_inv, const std::vector< Real > &intnl_old)
Checks the full Jacobian, which is just certain linear combinations of the dyieldFunction_dstress,...
MooseEnum _fspb_debug
none - don't do any debugging crash - currently inactive jacobian - check the jacobian entries jacobi...
RankTwoTensorTempl< T > transpose() const

◆ consistentTangentOperator()

RankFourTensor ComputeMultiPlasticityStress::consistentTangentOperator ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const RankFourTensor E_ijkl,
const std::vector< Real > &  pm_this_step,
const std::vector< Real > &  cumulative_pm 
)
protected

Computes the consistent tangent operator (another name for the jacobian = d(stress_rate)/d(strain_rate)

The computations performed depend upon _tangent_operator_type

Parameters
stressThe value of stress after the return map algorithm has converged
intnlThe internal parameters after the return map has converged
E_ijklThe elasticity tensor (in the case of no plasticity this is the jacobian)
pm_this_stepThe plastic multipliers coming from the final strain increment. In many cases these will be equal to cumulative_pm, but in the case where the returnMap algorithm had to be performed in multiple substeps of smaller applied strain increments, pm_this_step are just the plastic multipliers for the final application of the strain incrment
cumulative_pmThe plastic multipliers needed for this current Return (this is the sum of the plastic multipliers over all substeps if the strain increment was applied in small substeps)

Definition at line 1583 of file ComputeMultiPlasticityStress.C.

1588{
1589
1591 return E_ijkl;
1592
1593 // Typically act_at_some_step = act, but it is possible
1594 // that when subdividing a strain increment, a surface
1595 // is only active for one sub-step
1596 std::vector<bool> act_at_some_step(_num_surfaces);
1597 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1598 act_at_some_step[surface] = (cumulative_pm[surface] > 0);
1599
1600 // "act" might contain surfaces that are linearly dependent
1601 // with others. Only the plastic multipliers that are > 0
1602 // for this strain increment need to be varied to find
1603 // the consistent tangent operator
1604 std::vector<bool> act_vary(_num_surfaces);
1605 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1606 act_vary[surface] = (pm_this_step[surface] > 0);
1607
1608 std::vector<RankTwoTensor> df_dstress;
1609 dyieldFunction_dstress(stress, intnl, act_vary, df_dstress);
1610 std::vector<Real> df_dintnl;
1611 dyieldFunction_dintnl(stress, intnl, act_vary, df_dintnl);
1612 std::vector<RankTwoTensor> r;
1613 flowPotential(stress, intnl, act_vary, r);
1614 std::vector<RankFourTensor> dr_dstress_at_some_step;
1615 dflowPotential_dstress(stress, intnl, act_at_some_step, dr_dstress_at_some_step);
1616 std::vector<RankTwoTensor> dr_dintnl_at_some_step;
1617 dflowPotential_dintnl(stress, intnl, act_at_some_step, dr_dintnl_at_some_step);
1618 std::vector<Real> h;
1619 hardPotential(stress, intnl, act_vary, h);
1620
1621 unsigned ind1;
1622 unsigned ind2;
1623
1624 // r_minus_stuff[alpha] = r[alpha] -
1625 // pm_cumulatve[gamma]*dr[gamma]_dintnl[a]_at_some_step*h[a][alpha], with alpha only being in
1626 // act_vary, but gamma being act_at_some_step
1627 std::vector<RankTwoTensor> r_minus_stuff;
1628 ind1 = 0;
1629 for (unsigned surface1 = 0; surface1 < _num_surfaces; ++surface1)
1630 if (act_vary[surface1])
1631 {
1632 r_minus_stuff.push_back(r[ind1]);
1633 ind2 = 0;
1634 for (unsigned surface2 = 0; surface2 < _num_surfaces; ++surface2)
1635 if (act_at_some_step[surface2])
1636 {
1637 if (modelNumber(surface1) == modelNumber(surface2))
1638 {
1639 r_minus_stuff.back() -=
1640 cumulative_pm[surface2] * dr_dintnl_at_some_step[ind2] * h[ind1];
1641 }
1642 ind2++;
1643 }
1644 ind1++;
1645 }
1646
1647 unsigned int num_currently_active = 0;
1648 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1649 if (act_vary[surface])
1650 num_currently_active += 1;
1651
1652 // zzz is a matrix in the form that can be easily
1653 // inverted by MatrixTools::inverse
1654 // Eg for num_currently_active = 3
1655 // (zzz[0] zzz[1] zzz[2])
1656 // (zzz[3] zzz[4] zzz[5])
1657 // (zzz[6] zzz[7] zzz[8])
1658 std::vector<PetscScalar> zzz;
1659 zzz.assign(num_currently_active * num_currently_active, 0.0);
1660
1661 ind1 = 0;
1662 RankTwoTensor r2;
1663 for (unsigned surface1 = 0; surface1 < _num_surfaces; ++surface1)
1664 if (act_vary[surface1])
1665 {
1666 ind2 = 0;
1667 for (unsigned surface2 = 0; surface2 < _num_surfaces; ++surface2)
1668 if (act_vary[surface2])
1669 {
1670 r2 = df_dstress[ind1] * (E_ijkl * r_minus_stuff[ind2]);
1671 zzz[ind1 * num_currently_active + ind2] += r2(0, 0) + r2(1, 1) + r2(2, 2);
1672 if (modelNumber(surface1) == modelNumber(surface2))
1673 zzz[ind1 * num_currently_active + ind2] += df_dintnl[ind1] * h[ind2];
1674 ind2++;
1675 }
1676 ind1++;
1677 }
1678
1679 if (num_currently_active > 0)
1680 {
1681 // invert zzz, in place. if num_currently_active = 0 then zzz is not needed.
1682 try
1683 {
1684 MatrixTools::inverse(zzz, num_currently_active);
1685 }
1686 catch (const MooseException & e)
1687 {
1688 // in the very rare case of zzz being singular, just return the "elastic" tangent operator
1689 return E_ijkl;
1690 }
1691 }
1692
1693 RankFourTensor strain_coeff = E_ijkl;
1694 ind1 = 0;
1695 for (unsigned surface1 = 0; surface1 < _num_surfaces; ++surface1)
1696 if (act_vary[surface1])
1697 {
1698 RankTwoTensor part1 = E_ijkl * r_minus_stuff[ind1];
1699 ind2 = 0;
1700 for (unsigned surface2 = 0; surface2 < _num_surfaces; ++surface2)
1701 if (act_vary[surface2])
1702 {
1703 RankTwoTensor part2 = E_ijkl * df_dstress[ind2];
1704 for (unsigned i = 0; i < 3; i++)
1705 for (unsigned j = 0; j < 3; j++)
1706 for (unsigned k = 0; k < 3; k++)
1707 for (unsigned l = 0; l < 3; l++)
1708 strain_coeff(i, j, k, l) -=
1709 part1(i, j) * part2(k, l) * zzz[ind1 * num_currently_active + ind2];
1710 ind2++;
1711 }
1712 ind1++;
1713 }
1714
1716 return strain_coeff;
1717
1719
1720 RankFourTensor part3;
1721 ind1 = 0;
1722 for (unsigned surface1 = 0; surface1 < _num_surfaces; ++surface1)
1723 if (act_at_some_step[surface1])
1724 {
1725 part3 += cumulative_pm[surface1] * E_ijkl * dr_dstress_at_some_step[ind1];
1726 ind1++;
1727 }
1728
1729 stress_coeff += part3;
1730
1731 part3 = part3.transposeMajor(); // this is because below i want df_dstress[ind2]*part3, and this
1732 // equals (part3.transposeMajor())*df_dstress[ind2]
1733
1734 ind1 = 0;
1735 for (unsigned surface1 = 0; surface1 < _num_surfaces; ++surface1)
1736 if (act_vary[surface1])
1737 {
1738 RankTwoTensor part1 = E_ijkl * r_minus_stuff[ind1];
1739 ind2 = 0;
1740 for (unsigned surface2 = 0; surface2 < _num_surfaces; ++surface2)
1741 if (act_vary[surface2])
1742 {
1743 RankTwoTensor part2 = part3 * df_dstress[ind2];
1744 for (unsigned i = 0; i < 3; i++)
1745 for (unsigned j = 0; j < 3; j++)
1746 for (unsigned k = 0; k < 3; k++)
1747 for (unsigned l = 0; l < 3; l++)
1748 stress_coeff(i, j, k, l) -=
1749 part1(i, j) * part2(k, l) * zzz[ind1 * num_currently_active + ind2];
1750 ind2++;
1751 }
1752 ind1++;
1753 }
1754
1755 // need to find the inverse of stress_coeff, but remember
1756 // stress_coeff does not have the symmetries commonly found
1757 // in tensor mechanics:
1758 // stress_coeff(i, j, k, l) = stress_coeff(j, i, k, l) = stress_coeff(i, j, l, k) !=
1759 // stress_coeff(k, l, i, j)
1760 // (note the final not-equals). We want s_inv, such that
1761 // s_inv(i, j, m, n)*stress_coeff(m, n, k, l) = (de_ik*de_jl + de_il*de_jk)/2
1762 // where de_ij = 1 if i=j, and 0 otherwise.
1763 RankFourTensor s_inv;
1764 try
1765 {
1766 s_inv = stress_coeff.invSymm();
1767 }
1768 catch (const MooseException & e)
1769 {
1770 return strain_coeff; // when stress_coeff is singular (perhaps for incompressible plasticity?)
1771 // return the "linear" tangent operator
1772 }
1773
1774 return s_inv * strain_coeff;
1775}
RankFourTensorTempl< T > invSymm() const
RankFourTensorTempl< T > transposeMajor() const
void inverse(const std::vector< std::vector< Real > > &m, std::vector< std::vector< Real > > &m_inv)

Referenced by quickStep(), and returnMap().

◆ dflowPotential_dintnl()

void MultiPlasticityRawComponentAssembler::dflowPotential_dintnl ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< RankTwoTensor > &  dr_dintnl 
)
protectedvirtualinherited

The derivative of the active flow potentials with respect to the active internal parameters The UserObjects explicitly assume that r[alpha] is only dependent on intnl[alpha].

Parameters
stressthe stress at which to calculate the flow potential
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "dr_dintnl"
[out]dr_dintnlthe derivatives. dr_dintnl[alpha](i, j) = dr[alpha](i, j)/dintnl[alpha]

Definition at line 233 of file MultiPlasticityRawComponentAssembler.C.

237{
238 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
239 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
240
241 dr_dintnl.resize(0);
242 std::vector<unsigned int> active_surfaces_of_model;
243 std::vector<unsigned int>::iterator active_surface;
244 std::vector<RankTwoTensor> model_dr_dintnl;
245 for (unsigned model = 0; model < _num_models; ++model)
246 {
247 activeModelSurfaces(model, active, active_surfaces_of_model);
248 if (active_surfaces_of_model.size() > 0)
249 {
250 _f[model]->dflowPotential_dintnlV(stress, intnl[model], model_dr_dintnl);
251 for (active_surface = active_surfaces_of_model.begin();
252 active_surface != active_surfaces_of_model.end();
253 ++active_surface)
254 dr_dintnl.push_back(model_dr_dintnl[*active_surface]);
255 }
256 }
257}
void activeModelSurfaces(int model, const std::vector< bool > &active, std::vector< unsigned int > &active_surfaces_of_model)
Returns the internal surface number(s) of the active surfaces of the given model This may be of size=...

Referenced by MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityDebugger::checkDerivatives(), and consistentTangentOperator().

◆ dflowPotential_dstress()

void MultiPlasticityRawComponentAssembler::dflowPotential_dstress ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< RankFourTensor > &  dr_dstress 
)
protectedvirtualinherited

The derivative of the active flow potential(s) with respect to stress.

Parameters
stressthe stress at which to calculate the flow potential
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "dr_dstress"
[out]dr_dstressthe derivative. dr_dstress[alpha](i, j, k, l) = dr[alpha](i, j)/dstress(k, l)

Definition at line 205 of file MultiPlasticityRawComponentAssembler.C.

210{
211 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
212 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
213
214 dr_dstress.resize(0);
215 std::vector<unsigned int> active_surfaces_of_model;
216 std::vector<unsigned int>::iterator active_surface;
217 std::vector<RankFourTensor> model_dr_dstress;
218 for (unsigned model = 0; model < _num_models; ++model)
219 {
220 activeModelSurfaces(model, active, active_surfaces_of_model);
221 if (active_surfaces_of_model.size() > 0)
222 {
223 _f[model]->dflowPotential_dstressV(stress, intnl[model], model_dr_dstress);
224 for (active_surface = active_surfaces_of_model.begin();
225 active_surface != active_surfaces_of_model.end();
226 ++active_surface)
227 dr_dstress.push_back(model_dr_dstress[*active_surface]);
228 }
229 }
230}

Referenced by MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityDebugger::checkDerivatives(), and consistentTangentOperator().

◆ dhardPotential_dintnl()

void MultiPlasticityRawComponentAssembler::dhardPotential_dintnl ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< Real > &  dh_dintnl 
)
protectedvirtualinherited

The derivative of the active hardening potentials with respect to the active internal parameters.

Parameters
stressthe stress at which to calculate the hardening potentials
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "dh_dintnl"
[out]dh_dintnlthe derivatives. dh_dintnl[a][alpha][b] = dh[a][alpha]/dintnl[b]. Note that the userobjects assume that there is exactly one internal parameter per yield function, so the derivative is only nonzero for a=alpha=b, so that is all we calculate

Definition at line 315 of file MultiPlasticityRawComponentAssembler.C.

319{
320 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
321 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
322
323 dh_dintnl.resize(0);
324 std::vector<unsigned int> active_surfaces_of_model;
325 std::vector<unsigned int>::iterator active_surface;
326 std::vector<Real> model_dh_dintnl;
327 for (unsigned model = 0; model < _num_models; ++model)
328 {
329 activeModelSurfaces(model, active, active_surfaces_of_model);
330 if (active_surfaces_of_model.size() > 0)
331 {
332 _f[model]->dhardPotential_dintnlV(stress, intnl[model], model_dh_dintnl);
333 for (active_surface = active_surfaces_of_model.begin();
334 active_surface != active_surfaces_of_model.end();
335 ++active_surface)
336 dh_dintnl.push_back(model_dh_dintnl[*active_surface]);
337 }
338 }
339}

Referenced by MultiPlasticityLinearSystem::calculateJacobian().

◆ dhardPotential_dstress()

void MultiPlasticityRawComponentAssembler::dhardPotential_dstress ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< RankTwoTensor > &  dh_dstress 
)
protectedvirtualinherited

The derivative of the active hardening potentials with respect to stress By assumption in the Userobjects, the h[a][alpha] is nonzero only for a = alpha, so we only calculate those here.

Parameters
stressthe stress at which to calculate the hardening potentials
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "dh_dstress"
[out]dh_dstressthe derivative. dh_dstress[a](i, j) = dh[a]/dstress(k, l)

Definition at line 287 of file MultiPlasticityRawComponentAssembler.C.

292{
293 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
294 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
295
296 dh_dstress.resize(0);
297 std::vector<unsigned int> active_surfaces_of_model;
298 std::vector<unsigned int>::iterator active_surface;
299 std::vector<RankTwoTensor> model_dh_dstress;
300 for (unsigned model = 0; model < _num_models; ++model)
301 {
302 activeModelSurfaces(model, active, active_surfaces_of_model);
303 if (active_surfaces_of_model.size() > 0)
304 {
305 _f[model]->dhardPotential_dstressV(stress, intnl[model], model_dh_dstress);
306 for (active_surface = active_surfaces_of_model.begin();
307 active_surface != active_surfaces_of_model.end();
308 ++active_surface)
309 dh_dstress.push_back(model_dh_dstress[*active_surface]);
310 }
311 }
312}

Referenced by MultiPlasticityLinearSystem::calculateJacobian().

◆ dof_included()

bool MultiPlasticityDebugger::dof_included ( unsigned int  dof,
const std::vector< bool > &  deactivated_due_to_ld 
)
privateinherited

Definition at line 353 of file MultiPlasticityDebugger.C.

355{
356 if (dof < unsigned(6))
357 // these are the stress components
358 return true;
359 unsigned eff_dof = dof - 6;
360 if (eff_dof < _num_surfaces)
361 // these are the plastic multipliers, pm
362 return !deactivated_due_to_ld[eff_dof];
363 eff_dof -= _num_surfaces; // now we know the dof is an intnl parameter
364 std::vector<bool> active_surface(_num_surfaces);
365 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
366 active_surface[surface] = !deactivated_due_to_ld[surface];
367 return anyActiveSurfaces(eff_dof, active_surface);
368}

Referenced by MultiPlasticityDebugger::fdJacobian().

◆ dyieldFunction_dintnl()

void MultiPlasticityRawComponentAssembler::dyieldFunction_dintnl ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< Real > &  df_dintnl 
)
protectedvirtualinherited

The derivative of active yield function(s) with respect to their internal parameters (the user objects assume there is exactly one internal param per yield function)

Parameters
stressthe stress at which to calculate the yield function
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "df_dintnl"
[out]df_dintnlthe derivatives. df_dstress[alpha] = dyieldFunction[alpha]/dintnl[alpha]

Definition at line 151 of file MultiPlasticityRawComponentAssembler.C.

155{
156 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
157 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
158
159 df_dintnl.resize(0);
160 std::vector<unsigned int> active_surfaces_of_model;
161 std::vector<unsigned int>::iterator active_surface;
162 std::vector<Real> model_df_dintnl;
163 for (unsigned model = 0; model < _num_models; ++model)
164 {
165 activeModelSurfaces(model, active, active_surfaces_of_model);
166 if (active_surfaces_of_model.size() > 0)
167 {
168 _f[model]->dyieldFunction_dintnlV(stress, intnl[model], model_df_dintnl);
169 for (active_surface = active_surfaces_of_model.begin();
170 active_surface != active_surfaces_of_model.end();
171 ++active_surface)
172 df_dintnl.push_back(model_df_dintnl[*active_surface]);
173 }
174 }
175}

Referenced by MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityDebugger::checkDerivatives(), and consistentTangentOperator().

◆ dyieldFunction_dstress()

void MultiPlasticityRawComponentAssembler::dyieldFunction_dstress ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< RankTwoTensor > &  df_dstress 
)
protectedvirtualinherited

The derivative of the active yield function(s) with respect to stress.

Parameters
stressthe stress at which to calculate the yield function
intnlvector of internal parameters
activeset of active constraints - only the active derivatives are put into "df_dstress"
[out]df_dstressthe derivative (or derivatives in the case of multisurface plasticity). df_dstress[alpha](i, j) = dyieldFunction[alpha]/dstress(i, j)

Definition at line 123 of file MultiPlasticityRawComponentAssembler.C.

128{
129 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
130 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
131
132 df_dstress.resize(0);
133 std::vector<unsigned int> active_surfaces_of_model;
134 std::vector<unsigned int>::iterator active_surface;
135 std::vector<RankTwoTensor> model_df_dstress;
136 for (unsigned model = 0; model < _num_models; ++model)
137 {
138 activeModelSurfaces(model, active, active_surfaces_of_model);
139 if (active_surfaces_of_model.size() > 0)
140 {
141 _f[model]->dyieldFunction_dstressV(stress, intnl[model], model_df_dstress);
142 for (active_surface = active_surfaces_of_model.begin();
143 active_surface != active_surfaces_of_model.end();
144 ++active_surface)
145 df_dstress.push_back(model_df_dstress[*active_surface]);
146 }
147 }
148}

Referenced by buildDumbOrder(), MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityDebugger::checkDerivatives(), consistentTangentOperator(), and MultiPlasticityLinearSystem::eliminateLinearDependence().

◆ eliminateLinearDependence()

void MultiPlasticityLinearSystem::eliminateLinearDependence ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< Real > &  f,
const std::vector< RankTwoTensor > &  r,
const std::vector< bool > &  active,
std::vector< bool > &  deactivated_due_to_ld 
)
privatevirtualinherited

Performs a number of singular-value decompositions to check for linear-dependence of the active directions "r" If linear dependence is found, then deactivated_due_to_ld will contain 'true' entries where surfaces need to be deactivated_due_to_ld.

Parameters
stressthe current stress
intnlthe current values of internal parameters
fActive yield function values
rthe flow directions that for those yield functions that are active upon entry to this function
activetrue if active
[out]deactivated_due_to_ldYield functions deactivated due to linearly-dependent flow directions

Definition at line 106 of file MultiPlasticityLinearSystem.C.

112{
113 deactivated_due_to_ld.resize(_num_surfaces, false);
114
115 unsigned num_active = r.size();
116
117 if (num_active <= 1)
118 return;
119
120 std::vector<double> s;
121 int info = singularValuesOfR(r, s);
122 if (info != 0)
123 mooseError("In finding the SVD in the return-map algorithm, the PETSC LAPACK gesvd routine "
124 "returned with error code ",
125 info);
126
127 // num_lin_dep are the number of linearly dependent
128 // "r vectors", if num_active <= 6
129 unsigned int num_lin_dep = 0;
130
131 unsigned i = s.size();
132 while (i-- > 0)
133 if (s[i] < _svd_tol * s[0])
134 num_lin_dep++;
135 else
136 break;
137
138 if (num_lin_dep == 0 && num_active <= 6)
139 return;
140
141 // From here on, some flow directions are linearly dependent
142
143 // Find the signed "distance" of the current (stress, internal) configuration
144 // from the yield surfaces. This distance will not be precise, but
145 // i want to preferentially deactivate yield surfaces that are close
146 // to the current stress point.
147 std::vector<RankTwoTensor> df_dstress;
148 dyieldFunction_dstress(stress, intnl, active, df_dstress);
149
150 typedef std::pair<Real, unsigned> pair_for_sorting;
151 std::vector<pair_for_sorting> dist(num_active);
152 for (unsigned i = 0; i < num_active; ++i)
153 {
154 dist[i].first = f[i] / df_dstress[i].L2norm();
155 dist[i].second = i;
156 }
157 std::sort(dist.begin(), dist.end()); // sorted in ascending order
158
159 // There is a potential problem when we have equal f[i], for it can give oscillations
160 bool equals_detected = false;
161 for (unsigned i = 0; i < num_active - 1; ++i)
162 if (std::abs(dist[i].first - dist[i + 1].first) < _min_f_tol)
163 {
164 equals_detected = true;
165 dist[i].first += _min_f_tol * (MooseRandom::rand() - 0.5);
166 }
167 if (equals_detected)
168 std::sort(dist.begin(), dist.end()); // sorted in ascending order
169
170 std::vector<bool> scheduled_for_deactivation;
171 scheduled_for_deactivation.assign(num_active, false);
172
173 // In the following loop we go through all the flow directions, from
174 // the one with the largest dist, to the one with the smallest dist,
175 // adding them one-by-one into r_tmp. Upon each addition we check
176 // for linear-dependence. if LD is found, we schedule the most
177 // recently added flow direction for deactivation, and pop it
178 // back off r_tmp
179 unsigned current_yf;
180 current_yf = dist[num_active - 1].second;
181 // the one with largest dist
182 std::vector<RankTwoTensor> r_tmp = {r[current_yf]};
183
184 unsigned num_kept_active = 1;
185 for (unsigned yf_to_try = 2; yf_to_try <= num_active; ++yf_to_try)
186 {
187 current_yf = dist[num_active - yf_to_try].second;
188 if (num_active == 2) // shortcut to we don't have to singularValuesOfR
189 scheduled_for_deactivation[current_yf] = true;
190 else if (num_kept_active >= 6) // shortcut to we don't have to singularValuesOfR: there can
191 // never be > 6 linearly-independent r vectors
192 scheduled_for_deactivation[current_yf] = true;
193 else
194 {
195 r_tmp.push_back(r[current_yf]);
196 info = singularValuesOfR(r_tmp, s);
197 if (info != 0)
198 mooseError("In finding the SVD in the return-map algorithm, the PETSC LAPACK gesvd routine "
199 "returned with error code ",
200 info);
201 if (s[s.size() - 1] < _svd_tol * s[0])
202 {
203 scheduled_for_deactivation[current_yf] = true;
204 r_tmp.pop_back();
205 num_lin_dep--;
206 }
207 else
208 num_kept_active++;
209 if (num_lin_dep == 0 && num_active <= 6)
210 // have taken out all the vectors that were linearly dependent
211 // so no point continuing
212 break;
213 }
214 }
215
216 unsigned int old_active_number = 0;
217 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
218 if (active[surface])
219 {
220 if (scheduled_for_deactivation[old_active_number])
221 deactivated_due_to_ld[surface] = true;
222 old_active_number++;
223 }
224}
static Real rand()
virtual int singularValuesOfR(const std::vector< RankTwoTensor > &r, std::vector< Real > &s)
Performs a singular-value decomposition of r and returns the singular values.
Real _svd_tol
Tolerance on the minimum ratio of singular values before flow-directions are deemed linearly dependen...
Real _min_f_tol
Minimum value of the _f_tol parameters for the Yield Function User Objects.
MPI_Info info

Referenced by MultiPlasticityLinearSystem::calculateRHS().

◆ fddflowPotential_dintnl()

void MultiPlasticityDebugger::fddflowPotential_dintnl ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< RankTwoTensor > &  dr_dintnl 
)
privatevirtualinherited

The finite-difference derivative of the flow potentials with respect to internal parameters.

Parameters
stressthe stress at which to calculate the flow potential
intnlvector of internal parameters
[out]dr_dintnlthe derivatives. dr_dintnl[alpha](i, j) = dr[alpha](i, j)/dintnl[alpha]

Definition at line 612 of file MultiPlasticityDebugger.C.

615{
616 dr_dintnl.resize(_num_surfaces);
617
618 std::vector<bool> act;
619 act.assign(_num_surfaces, true);
620
621 std::vector<RankTwoTensor> origr;
622 flowPotential(stress, intnl, act, origr);
623
624 std::vector<Real> intnlep;
625 intnlep.resize(_num_models);
626 for (unsigned model = 0; model < _num_models; ++model)
627 intnlep[model] = intnl[model];
628 Real ep;
629 std::vector<RankTwoTensor> rep;
630 unsigned int model;
631 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
632 {
633 model = modelNumber(surface);
635 intnlep[model] += ep;
636 flowPotential(stress, intnlep, act, rep);
637 dr_dintnl[surface] = (rep[surface] - origr[surface]) / ep;
638 intnlep[model] -= ep;
639 }
640}
std::vector< Real > _fspb_debug_intnl_change
Debug finite-differencing parameters for the internal parameters.

Referenced by MultiPlasticityDebugger::checkDerivatives().

◆ fddflowPotential_dstress()

void MultiPlasticityDebugger::fddflowPotential_dstress ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< RankFourTensor > &  dr_dstress 
)
privatevirtualinherited

The finite-difference derivative of the flow potential(s) with respect to stress.

Parameters
stressthe stress at which to calculate the flow potential
intnlvector of internal parameters
[out]dr_dstressthe derivative. dr_dstress[alpha](i, j, k, l) = dr[alpha](i, j)/dstress(k, l)

Definition at line 583 of file MultiPlasticityDebugger.C.

586{
587 dr_dstress.assign(_num_surfaces, RankFourTensor());
588
589 std::vector<bool> act;
590 act.assign(_num_surfaces, true);
591
593 RankTwoTensor stressep;
594 std::vector<RankTwoTensor> rep, rep_minus;
595 for (unsigned i = 0; i < 3; ++i)
596 for (unsigned j = 0; j < 3; ++j)
597 {
598 stressep = stress;
599 // do a central difference
600 stressep(i, j) += ep / 2.0;
601 flowPotential(stressep, intnl, act, rep);
602 stressep(i, j) -= ep;
603 flowPotential(stressep, intnl, act, rep_minus);
604 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
605 for (unsigned k = 0; k < 3; ++k)
606 for (unsigned l = 0; l < 3; ++l)
607 dr_dstress[surface](k, l, i, j) = (rep[surface](k, l) - rep_minus[surface](k, l)) / ep;
608 }
609}
Real _fspb_debug_stress_change
Debug finite-differencing parameter for the stress.

Referenced by MultiPlasticityDebugger::checkDerivatives().

◆ fddyieldFunction_dintnl()

void MultiPlasticityDebugger::fddyieldFunction_dintnl ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< Real > &  df_dintnl 
)
privateinherited

The finite-difference derivative of yield function(s) with respect to internal parameter(s)

Parameters
stressthe stress at which to calculate the yield function
intnlvector of internal parameters
[out]df_dintnlthe derivative (or derivatives in the case of multisurface plasticity). df_dintnl[alpha] = dyieldFunction[alpha]/dintnl[alpha]

Definition at line 552 of file MultiPlasticityDebugger.C.

555{
556 df_dintnl.resize(_num_surfaces);
557
558 std::vector<bool> act;
559 act.assign(_num_surfaces, true);
560
561 std::vector<Real> origf;
562 yieldFunction(stress, intnl, act, origf);
563
564 std::vector<Real> intnlep;
565 intnlep.resize(_num_models);
566 for (unsigned model = 0; model < _num_models; ++model)
567 intnlep[model] = intnl[model];
568 Real ep;
569 std::vector<Real> fep;
570 unsigned int model;
571 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
572 {
573 model = modelNumber(surface);
575 intnlep[model] += ep;
576 yieldFunction(stress, intnlep, act, fep);
577 df_dintnl[surface] = (fep[surface] - origf[surface]) / ep;
578 intnlep[model] -= ep;
579 }
580}

Referenced by MultiPlasticityDebugger::checkDerivatives().

◆ fddyieldFunction_dstress()

void MultiPlasticityDebugger::fddyieldFunction_dstress ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
std::vector< RankTwoTensor > &  df_dstress 
)
privateinherited

The finite-difference derivative of yield function(s) with respect to stress.

Parameters
stressthe stress at which to calculate the yield function
intnlvector of internal parameters
[out]df_dstressthe derivative (or derivatives in the case of multisurface plasticity). df_dstress[alpha](i, j) = dyieldFunction[alpha]/dstress(i, j)

Definition at line 524 of file MultiPlasticityDebugger.C.

527{
528 df_dstress.assign(_num_surfaces, RankTwoTensor());
529
530 std::vector<bool> act;
531 act.assign(_num_surfaces, true);
532
534 RankTwoTensor stressep;
535 std::vector<Real> fep, fep_minus;
536 for (unsigned i = 0; i < 3; ++i)
537 for (unsigned j = 0; j < 3; ++j)
538 {
539 stressep = stress;
540 // do a central difference to attempt to capture discontinuities
541 // such as those encountered in tensile and Mohr-Coulomb
542 stressep(i, j) += ep / 2.0;
543 yieldFunction(stressep, intnl, act, fep);
544 stressep(i, j) -= ep;
545 yieldFunction(stressep, intnl, act, fep_minus);
546 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
547 df_dstress[surface](i, j) = (fep[surface] - fep_minus[surface]) / ep;
548 }
549}

Referenced by MultiPlasticityDebugger::checkDerivatives().

◆ fdJacobian()

void MultiPlasticityDebugger::fdJacobian ( const RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
const std::vector< Real > &  intnl,
const std::vector< Real > &  pm,
const RankTwoTensor delta_dp,
const RankFourTensor E_inv,
bool  eliminate_ld,
std::vector< std::vector< Real > > &  jac 
)
privatevirtualinherited

The Jacobian calculated using finite differences.

The output should be equal to calculateJacobian(...) if everything is coded correctly.

Parameters
stressthe stress at which to calculate the Jacobian
intnl_oldthe old values of internal variables (jacobian is inependent of these, but they are needed to do the finite-differencing cleanly)
intnlthe vector of internal parameters at which to calculate the Jacobian
pmthe plasticity multipliers at which to calculate the Jacobian
delta_dpplastic_strain - plastic_strain_old (Jacobian is independent of this, but it is needed to do the finite-differencing cleanly)
E_invinverse of the elasticity tensor
eliminate_ldonly calculate the Jacobian for the linearly independent constraints
[out]jacthe finite-difference Jacobian

Definition at line 225 of file MultiPlasticityDebugger.C.

233{
234 std::vector<bool> active;
235 active.assign(_num_surfaces, true);
236
237 std::vector<bool> deactivated_due_to_ld;
238 std::vector<bool> deactivated_due_to_ld_ep;
239
240 std::vector<Real> orig_rhs;
241 calculateRHS(stress,
242 intnl_old,
243 intnl,
244 pm,
245 delta_dp,
246 orig_rhs,
247 active,
248 eliminate_ld,
249 deactivated_due_to_ld); // this calculates RHS, and also set deactivated_due_to_ld.
250 // The latter stays fixed for the rest of this routine
251
252 unsigned int whole_system_size = 6 + _num_surfaces + _num_models;
253 unsigned int system_size =
254 orig_rhs.size(); // will be = whole_system_size if eliminate_ld = false, since all active=true
255 jac.resize(system_size);
256 for (unsigned row = 0; row < system_size; ++row)
257 jac[row].assign(system_size, 0);
258
259 std::vector<Real> rhs_ep;
260 unsigned col = 0;
261
262 RankTwoTensor stressep;
263 RankTwoTensor delta_dpep;
265 for (unsigned i = 0; i < 3; ++i)
266 for (unsigned j = 0; j <= i; ++j)
267 {
268 stressep = stress;
269 stressep(i, j) += ep;
270 if (i != j)
271 stressep(j, i) += ep;
272 delta_dpep = delta_dp;
273 for (unsigned k = 0; k < 3; ++k)
274 for (unsigned l = 0; l < 3; ++l)
275 {
276 delta_dpep(k, l) -= E_inv(k, l, i, j) * ep;
277 if (i != j)
278 delta_dpep(k, l) -= E_inv(k, l, j, i) * ep;
279 }
280 active.assign(_num_surfaces, true);
281 calculateRHS(stressep,
282 intnl_old,
283 intnl,
284 pm,
285 delta_dpep,
286 rhs_ep,
287 active,
288 false,
289 deactivated_due_to_ld_ep);
290 unsigned row = 0;
291 for (unsigned dof = 0; dof < whole_system_size; ++dof)
292 if (dof_included(dof, deactivated_due_to_ld))
293 {
294 jac[row][col] =
295 -(rhs_ep[dof] - orig_rhs[row]) / ep; // remember jacobian = -d(rhs)/d(something)
296 row++;
297 }
298 col++; // all of the first 6 columns are dof_included since they're stresses
299 }
300
301 std::vector<Real> pmep;
302 pmep.resize(_num_surfaces);
303 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
304 pmep[surface] = pm[surface];
305 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
306 {
307 if (!dof_included(6 + surface, deactivated_due_to_ld))
308 continue;
309 ep = _fspb_debug_pm_change[surface];
310 pmep[surface] += ep;
311 active.assign(_num_surfaces, true);
313 stress, intnl_old, intnl, pmep, delta_dp, rhs_ep, active, false, deactivated_due_to_ld_ep);
314 unsigned row = 0;
315 for (unsigned dof = 0; dof < whole_system_size; ++dof)
316 if (dof_included(dof, deactivated_due_to_ld))
317 {
318 jac[row][col] =
319 -(rhs_ep[dof] - orig_rhs[row]) / ep; // remember jacobian = -d(rhs)/d(something)
320 row++;
321 }
322 pmep[surface] -= ep;
323 col++;
324 }
325
326 std::vector<Real> intnlep;
327 intnlep.resize(_num_models);
328 for (unsigned model = 0; model < _num_models; ++model)
329 intnlep[model] = intnl[model];
330 for (unsigned model = 0; model < _num_models; ++model)
331 {
332 if (!dof_included(6 + _num_surfaces + model, deactivated_due_to_ld))
333 continue;
335 intnlep[model] += ep;
336 active.assign(_num_surfaces, true);
338 stress, intnl_old, intnlep, pm, delta_dp, rhs_ep, active, false, deactivated_due_to_ld_ep);
339 unsigned row = 0;
340 for (unsigned dof = 0; dof < whole_system_size; ++dof)
341 if (dof_included(dof, deactivated_due_to_ld))
342 {
343 jac[row][col] =
344 -(rhs_ep[dof] - orig_rhs[row]) / ep; // remember jacobian = -d(rhs)/d(something)
345 row++;
346 }
347 intnlep[model] -= ep;
348 col++;
349 }
350}
bool dof_included(unsigned int dof, const std::vector< bool > &deactivated_due_to_ld)
std::vector< Real > _fspb_debug_pm_change
Debug finite-differencing parameters for the plastic multipliers.

Referenced by MultiPlasticityDebugger::checkJacobian(), and MultiPlasticityDebugger::checkSolution().

◆ flowPotential()

void MultiPlasticityRawComponentAssembler::flowPotential ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< RankTwoTensor > &  r 
)
protectedvirtualinherited

The active flow potential(s) - one for each yield function.

Parameters
stressthe stress at which to calculate the flow potential
intnlvector of internal parameters
activeset of active constraints - only the active flow potentials are put into "r"
[out]rthe flow potential (flow potentials in the multi-surface case)

Definition at line 178 of file MultiPlasticityRawComponentAssembler.C.

182{
183 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
184 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
185
186 r.resize(0);
187 std::vector<unsigned int> active_surfaces_of_model;
188 std::vector<unsigned int>::iterator active_surface;
189 std::vector<RankTwoTensor> model_r;
190 for (unsigned model = 0; model < _num_models; ++model)
191 {
192 activeModelSurfaces(model, active, active_surfaces_of_model);
193 if (active_surfaces_of_model.size() > 0)
194 {
195 _f[model]->flowPotentialV(stress, intnl[model], model_r);
196 for (active_surface = active_surfaces_of_model.begin();
197 active_surface != active_surfaces_of_model.end();
198 ++active_surface)
199 r.push_back(model_r[*active_surface]);
200 }
201 }
202}

Referenced by MultiPlasticityLinearSystem::calculateConstraints(), MultiPlasticityLinearSystem::calculateJacobian(), consistentTangentOperator(), MultiPlasticityDebugger::fddflowPotential_dintnl(), and MultiPlasticityDebugger::fddflowPotential_dstress().

◆ hardPotential()

void MultiPlasticityRawComponentAssembler::hardPotential ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< Real > &  h 
)
protectedvirtualinherited

The active hardening potentials (one for each internal parameter and for each yield function) by assumption in the Userobjects, the h[a][alpha] is nonzero only if the surface alpha is part of model a, so we only calculate those here.

Parameters
stressthe stress at which to calculate the hardening potential
intnlvector of internal parameters
activeset of active constraints - only the active hardening potentials are put into "h"
[out]hthe hardening potentials. h[alpha] = hardening potential for yield fcn alpha (and, by the above assumption we know which hardening parameter, a, this belongs to)

Definition at line 260 of file MultiPlasticityRawComponentAssembler.C.

264{
265 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
266 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
267
268 h.resize(0);
269 std::vector<unsigned int> active_surfaces_of_model;
270 std::vector<unsigned int>::iterator active_surface;
271 std::vector<Real> model_h;
272 for (unsigned model = 0; model < _num_models; ++model)
273 {
274 activeModelSurfaces(model, active, active_surfaces_of_model);
275 if (active_surfaces_of_model.size() > 0)
276 {
277 _f[model]->hardPotentialV(stress, intnl[model], model_h);
278 for (active_surface = active_surfaces_of_model.begin();
279 active_surface != active_surfaces_of_model.end();
280 ++active_surface)
281 h.push_back(model_h[*active_surface]);
282 }
283 }
284}

Referenced by MultiPlasticityLinearSystem::calculateConstraints(), MultiPlasticityLinearSystem::calculateJacobian(), and consistentTangentOperator().

◆ incrementDumb()

void ComputeMultiPlasticityStress::incrementDumb ( int dumb_iteration,
const std::vector< unsigned int > &  dumb_order,
std::vector< bool > &  act 
)
protectedvirtual

Increments "dumb_iteration" by 1, and sets "act" appropriately (act[alpha] = true iff alpha_th bit of dumb_iteration == 1)

Parameters
[in,out]dumb_iterationUsed to set act bitwise - the "dumb" scheme tries all possible combinations of act until a successful return
[in]dumb_orderdumb_order dumb_order[0] will be the yield surface furthest away from (stress, intnl), dumb_order[1] will be the next yield surface, etc. The distance measure used is f/|df_dstress|. This array can then be fed into incrementDumb in order to first try the yield surfaces which are farthest away from the (stress, intnl).
[out]actactive constraints

Definition at line 1553 of file ComputeMultiPlasticityStress.C.

1556{
1557 dumb_iteration += 1;
1558 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1559 act[dumb_order[surface]] =
1560 (dumb_iteration &
1561 (1 << surface)); // returns true if the surface_th bit of dumb_iteration == 1
1562}

Referenced by changeScheme(), and returnMap().

◆ initQpStatefulProperties()

void ComputeMultiPlasticityStress::initQpStatefulProperties ( )
protectedvirtual

Reimplemented from ComputeGeneralStressBase.

Definition at line 189 of file ComputeMultiPlasticityStress.C.

190{
192
193 _plastic_strain[_qp].zero();
194
195 _intnl[_qp].assign(_num_models, 0);
196
197 _yf[_qp].assign(_num_surfaces, 0);
198
199 _dummy_pm.assign(_num_surfaces, 0);
200
201 _iter[_qp] = 0.0; // this is really an unsigned int, but for visualisation i convert it to Real
202 _linesearch_needed[_qp] = 0;
203 _ld_encountered[_qp] = 0;
204 _constraints_added[_qp] = 0;
205
206 _n[_qp] = _n_input;
207
208 if (_cosserat)
209 (*_couple_stress)[_qp].zero();
210
211 if (_fspb_debug == "jacobian")
212 {
214 mooseError("Finite-differencing completed. Exiting with no error");
215 }
216}
virtual void initQpStatefulProperties() override
void checkDerivatives()
Checks the derivatives, eg dyieldFunction_dstress by using finite difference approximations.

◆ lineSearch()

bool ComputeMultiPlasticityStress::lineSearch ( Real &  nr_res2,
RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
std::vector< Real > &  intnl,
std::vector< Real > &  pm,
const RankFourTensor E_inv,
RankTwoTensor delta_dp,
const RankTwoTensor dstress,
const std::vector< Real > &  dpm,
const std::vector< Real > &  dintnl,
std::vector< Real > &  f,
RankTwoTensor epp,
std::vector< Real > &  ic,
const std::vector< bool > &  active,
const std::vector< bool > &  deactivated_due_to_ld,
bool &  linesearch_needed 
)
protectedvirtual

Performs a line search.

Algorithm is taken straight from "Numerical Recipes". Given the changes dstress, dpm and dintnl provided by the nrStep routine, a line-search looks for an appropriate under-relaxation that reduces the residual-squared (nr_res2).

Most variables are input/output variables: they enter the function with their values at the start of the Newton step, and they exit the function with values attained after applying the under-relaxation

Parameters
[in,out]nr_res2The residual-squared
[out]stressThe stress after returning to the yield surface
intnl_oldThe internal variables at the previous "time" step
[in,out]intnlThe internal variables
[in,out]pmThe plasticity multiplier(s) (consistency parameter(s))
E_invinverse of the elasticity tensor
[in,out]delta_dpChange in plastic strain from start of "time" step to current configuration (plastic_strain - plastic_strain_old)
dstressChange in stress for a full Newton step
dpmChange in plasticity multiplier for a full Newton step
dintnlchange in internal parameter(s) for a full Newton step
[in,out]fYield function(s). In this routine, only the active constraints that are not deactivated_due_to_ld are contained in f.
[in,out]eppPlastic strain increment constraint
[in,out]icInternal constraint. In this routine, only the active constraints that are not deactivated_due_to_ld are contained in ic.
activeThe active constraints.
deactivated_due_to_ldTrue if a constraint has temporarily been made deactive due to linear dependence.
[out]linesearch_neededTrue if the full Newton-Raphson step was cut by the linesearch
Returns
true if successfully found a step that reduces the residual-squared

Definition at line 1389 of file ComputeMultiPlasticityStress.C.

1405{
1406 // Line search algorithm straight out of "Numerical Recipes"
1407
1408 bool success =
1409 true; // return value: will be false if linesearch couldn't reduce the residual-squared
1410
1411 // Aim is to decrease residual2
1412
1413 Real lam = 1.0; // the line-search parameter: 1.0 is a full Newton step
1414 Real lam_min =
1415 1E-10; // minimum value of lam allowed - perhaps this should be dynamically calculated?
1416 Real f0 = nr_res2; // initial value of residual2
1417 Real slope = -2 * nr_res2; // "Numerical Recipes" uses -b*A*x, in order to check for roundoff, but
1418 // i hope the nrStep would warn if there were problems.
1419 Real tmp_lam; // cached value of lam used in quadratic & cubic line search
1420 Real f2 = nr_res2; // cached value of f = residual2 used in the cubic in the line search
1421 Real lam2 = lam; // cached value of lam used in the cubic in the line search
1422
1423 // pm during the line-search
1424 std::vector<Real> ls_pm;
1425 ls_pm.resize(pm.size());
1426
1427 // delta_dp during the line-search
1428 RankTwoTensor ls_delta_dp;
1429
1430 // internal parameter during the line-search
1431 std::vector<Real> ls_intnl;
1432 ls_intnl.resize(intnl.size());
1433
1434 // stress during the line-search
1435 RankTwoTensor ls_stress;
1436
1437 // flow directions (not used in line search, but calculateConstraints returns this parameter)
1438 std::vector<RankTwoTensor> r;
1439
1440 while (true)
1441 {
1442 // update the variables using this line-search parameter
1443 for (unsigned alpha = 0; alpha < pm.size(); ++alpha)
1444 ls_pm[alpha] = pm[alpha] + dpm[alpha] * lam;
1445 ls_delta_dp = delta_dp - E_inv * dstress * lam;
1446 for (unsigned a = 0; a < intnl.size(); ++a)
1447 ls_intnl[a] = intnl[a] + dintnl[a] * lam;
1448 ls_stress = stress + dstress * lam;
1449
1450 // calculate the new active yield functions, epp and active internal constraints
1451 calculateConstraints(ls_stress, intnl_old, ls_intnl, ls_pm, ls_delta_dp, f, r, epp, ic, active);
1452
1453 // calculate the new residual-squared
1454 nr_res2 = residual2(ls_pm, f, epp, ic, active, deactivated_due_to_ld);
1455
1456 if (nr_res2 < f0 + 1E-4 * lam * slope)
1457 break;
1458 else if (lam < lam_min)
1459 {
1460 success = false;
1461 // restore plastic multipliers, yield functions, etc to original values
1462 for (unsigned alpha = 0; alpha < pm.size(); ++alpha)
1463 ls_pm[alpha] = pm[alpha];
1464 ls_delta_dp = delta_dp;
1465 for (unsigned a = 0; a < intnl.size(); ++a)
1466 ls_intnl[a] = intnl[a];
1467 ls_stress = stress;
1469 ls_stress, intnl_old, ls_intnl, ls_pm, ls_delta_dp, f, r, epp, ic, active);
1470 nr_res2 = residual2(ls_pm, f, epp, ic, active, deactivated_due_to_ld);
1471 break;
1472 }
1473 else if (lam == 1.0)
1474 {
1475 // model as a quadratic
1476 tmp_lam = -slope / 2.0 / (nr_res2 - f0 - slope);
1477 }
1478 else
1479 {
1480 // model as a cubic
1481 Real rhs1 = nr_res2 - f0 - lam * slope;
1482 Real rhs2 = f2 - f0 - lam2 * slope;
1483 Real a = (rhs1 / Utility::pow<2>(lam) - rhs2 / Utility::pow<2>(lam2)) / (lam - lam2);
1484 Real b =
1485 (-lam2 * rhs1 / Utility::pow<2>(lam) + lam * rhs2 / Utility::pow<2>(lam2)) / (lam - lam2);
1486 if (a == 0)
1487 tmp_lam = -slope / (2.0 * b);
1488 else
1489 {
1490 Real disc = Utility::pow<2>(b) - 3 * a * slope;
1491 if (disc < 0)
1492 tmp_lam = 0.5 * lam;
1493 else if (b <= 0)
1494 tmp_lam = (-b + std::sqrt(disc)) / (3.0 * a);
1495 else
1496 tmp_lam = -slope / (b + std::sqrt(disc));
1497 }
1498 if (tmp_lam > 0.5 * lam)
1499 tmp_lam = 0.5 * lam;
1500 }
1501 lam2 = lam;
1502 f2 = nr_res2;
1503 lam = std::max(tmp_lam, 0.1 * lam);
1504 }
1505
1506 if (lam < 1.0)
1507 linesearch_needed = true;
1508
1509 // assign the quantities found in the line-search
1510 // back to the originals
1511 for (unsigned alpha = 0; alpha < pm.size(); ++alpha)
1512 pm[alpha] = ls_pm[alpha];
1513 delta_dp = ls_delta_dp;
1514 for (unsigned a = 0; a < intnl.size(); ++a)
1515 intnl[a] = ls_intnl[a];
1516 stress = ls_stress;
1517
1518 return success;
1519}
virtual Real residual2(const std::vector< Real > &pm, const std::vector< Real > &f, const RankTwoTensor &epp, const std::vector< Real > &ic, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld)
The residual-squared.

Referenced by singleStep().

◆ modelNumber()

unsigned int MultiPlasticityRawComponentAssembler::modelNumber ( unsigned int  surface)
protectedinherited

◆ nrStep()

void MultiPlasticityLinearSystem::nrStep ( const RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
const std::vector< Real > &  intnl,
const std::vector< Real > &  pm,
const RankFourTensor E_inv,
const RankTwoTensor delta_dp,
RankTwoTensor dstress,
std::vector< Real > &  dpm,
std::vector< Real > &  dintnl,
const std::vector< bool > &  active,
std::vector< bool > &  deactivated_due_to_ld 
)
protectedvirtualinherited

Performs one Newton-Raphson step.

The purpose here is to find the changes, dstress, dpm and dintnl according to the Newton-Raphson procedure

Parameters
stressCurrent value of stress
intnl_oldThe internal variables at the previous "time" step
intnlCurrent value of the internal variables
pmCurrent value of the plasticity multipliers (consistency parameters)
E_invinverse of the elasticity tensor
delta_dpCurrent value of the plastic-strain increment (ie plastic_strain - plastic_strain_old)
[out]dstressThe change in stress for a full Newton step
[out]dpmThe change in all plasticity multipliers for a full Newton step
[out]dintnlThe change in all internal variables for a full Newton step
activeThe active constraints
[out]deactivated_due_to_ldThe constraints deactivated due to linear-dependence of the flow directions

Definition at line 614 of file MultiPlasticityLinearSystem.C.

625{
626 // Calculate RHS and Jacobian
627 std::vector<Real> rhs;
628 calculateRHS(stress, intnl_old, intnl, pm, delta_dp, rhs, active, true, deactivated_due_to_ld);
629
630 std::vector<std::vector<Real>> jac;
631 calculateJacobian(stress, intnl, pm, E_inv, active, deactivated_due_to_ld, jac);
632
633 // prepare for LAPACKgesv_ routine provided by PETSc
634 PetscBLASInt system_size = rhs.size();
635
636 std::vector<double> a(system_size * system_size);
637 // Fill in the a "matrix" by going down columns
638 unsigned ind = 0;
639 for (int col = 0; col < system_size; ++col)
640 for (int row = 0; row < system_size; ++row)
641 a[ind++] = jac[row][col];
642
643 PetscBLASInt nrhs = 1;
644 std::vector<PetscBLASInt> ipiv(system_size);
645 PetscBLASInt info;
646 LAPACKgesv_(&system_size, &nrhs, &a[0], &system_size, &ipiv[0], &rhs[0], &system_size, &info);
647
648 if (info != 0)
649 mooseError("In solving the linear system in a Newton-Raphson process, the PETSC LAPACK gsev "
650 "routine returned with error code ",
651 info);
652
653 // Extract the results back to dstress, dpm and dintnl
654 std::vector<bool> active_not_deact(_num_surfaces);
655 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
656 active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
657
658 unsigned int dim = 3;
659 ind = 0;
660
661 for (unsigned i = 0; i < dim; ++i)
662 for (unsigned j = 0; j <= i; ++j)
663 dstress(i, j) = dstress(j, i) = rhs[ind++];
664 dpm.assign(_num_surfaces, 0);
665 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
666 if (active_not_deact[surface])
667 dpm[surface] = rhs[ind++];
668 dintnl.assign(_num_models, 0);
669 for (unsigned model = 0; model < _num_models; ++model)
670 if (anyActiveSurfaces(model, active_not_deact))
671 dintnl[model] = rhs[ind++];
672
673 mooseAssert(static_cast<int>(ind) == system_size,
674 "Incorrect extracting of changes from NR solution in nrStep");
675}

Referenced by MultiPlasticityDebugger::checkSolution(), and singleStep().

◆ numberActive()

unsigned ComputeMultiPlasticityStress::numberActive ( const std::vector< bool > &  active)
protectedvirtual

counts the number of active constraints

Definition at line 1259 of file ComputeMultiPlasticityStress.C.

1260{
1261 unsigned num_active = 0;
1262 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1263 if (active[surface])
1264 num_active++;
1265 return num_active;
1266}

Referenced by returnMap(), and singleStep().

◆ outputAndCheckDebugParameters()

void MultiPlasticityDebugger::outputAndCheckDebugParameters ( )
inherited

Outputs the debug parameters: _fspb_debug_stress, _fspd_debug_pm, etc and checks that they are sized correctly.

Definition at line 53 of file MultiPlasticityDebugger.C.

54{
55 Moose::err << "Debug Parameters are as follows\n";
56 Moose::err << "stress = \n";
58
59 if (_fspb_debug_pm.size() != _num_surfaces || _fspb_debug_intnl.size() != _num_models ||
62 mooseError("The debug parameters have the wrong size\n");
63
64 Moose::err << "plastic multipliers =\n";
65 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
66 Moose::err << _fspb_debug_pm[surface] << "\n";
67
68 Moose::err << "internal parameters =\n";
69 for (unsigned model = 0; model < _num_models; ++model)
70 Moose::err << _fspb_debug_intnl[model] << "\n";
71
72 Moose::err << "finite-differencing parameter for stress-changes:\n"
74 Moose::err << "finite-differencing parameter(s) for plastic-multiplier(s):\n";
75 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
76 Moose::err << _fspb_debug_pm_change[surface] << "\n";
77 Moose::err << "finite-differencing parameter(s) for internal-parameter(s):\n";
78 for (unsigned model = 0; model < _num_models; ++model)
79 Moose::err << _fspb_debug_intnl_change[model] << "\n";
80
81 Moose::err << std::flush;
82}
void print(std::ostream &stm=Moose::out) const

Referenced by MultiPlasticityDebugger::checkDerivatives(), MultiPlasticityDebugger::checkJacobian(), and MultiPlasticityDebugger::checkSolution().

◆ plasticStep()

bool ComputeMultiPlasticityStress::plasticStep ( const RankTwoTensor stress_old,
RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
std::vector< Real > &  intnl,
const RankTwoTensor plastic_strain_old,
RankTwoTensor plastic_strain,
const RankFourTensor E_ijkl,
const RankTwoTensor strain_increment,
std::vector< Real > &  yf,
unsigned int iterations,
bool &  linesearch_needed,
bool &  ld_encountered,
bool &  constraints_added,
RankFourTensor consistent_tangent_operator 
)
protectedvirtual

performs a plastic step

Parameters
stress_oldThe value of stress at the previous "time" step
[out]stressstress after returning to the yield surface
intnl_oldThe internal variables at the previous "time" step
[out]intnlinternal variables after returning to the yield surface
plastic_strain_oldThe value of plastic strain at the previous "time" step
[out]plastic_strainplastic_strain after returning to the yield surface
E_ijklThe elasticity tensor.
strain_incrementThe applied strain increment
[out]yfAll the yield functions at (stress, intnl)
[out]iterationsThe total number of Newton-Raphson iterations used
[out]linesearch_neededTrue if a linesearch was needed at any stage during the Newton-Raphson proceedure
[out]ld_encounteredTrue if a linear-dependence of the flow directions was encountered at any stage during the Newton-Raphson proceedure
[out]constraints_addedTrue if constraints were added into the active set at any stage during the Newton-Raphson proceedure
[out]consistent_tangent_operatorThe consistent tangent operator d(stress_rate)/d(strain_rate)
Returns
true if the (stress, intnl) are admissible. Otherwise, if _ignore_failures==true, the output variables will be the best admissible ones found during the return-map. Otherwise, if _ignore_failures==false, this routine will perform some finite-diference checks and call mooseError

the idea in the following is to potentially subdivide the strain increment into smaller fractions, of size "step_size". First step_size = 1 is tried, and if that fails then 0.5 is tried, then 0.25, etc. As soon as a step is successful, its results are put into the "good" variables, which are used if a subsequent step fails. If >= 2 consecutive steps are successful, the step_size is increased by 1.2

The point of all this is that I hope that the time-step for the entire mesh need not be cut if there are only a few "bad" quadpoints where the return-map is difficult

Definition at line 466 of file ComputeMultiPlasticityStress.C.

480{
496 bool return_successful = false;
497
498 // total number of Newton-Raphson iterations used
499 unsigned int iter = 0;
500
501 Real step_size = 1.0;
502 Real time_simulated = 0.0;
503
504 // the "good" variables hold the latest admissible stress
505 // and internal parameters.
506 RankTwoTensor stress_good = stress_old;
507 RankTwoTensor plastic_strain_good = plastic_strain_old;
508 std::vector<Real> intnl_good(_num_models);
509 for (unsigned model = 0; model < _num_models; ++model)
510 intnl_good[model] = intnl_old[model];
511 std::vector<Real> yf_good(_num_surfaces);
512
513 // Following is necessary because I want strain_increment to be "const"
514 // but I also want to be able to subdivide an initial_stress
515 RankTwoTensor this_strain_increment = strain_increment;
516
517 RankTwoTensor dep = step_size * this_strain_increment;
518
519 _cumulative_pm.assign(_num_surfaces, 0);
520
521 unsigned int num_consecutive_successes = 0;
522 while (time_simulated < 1.0 && step_size >= _min_stepsize)
523 {
524 iter = 0;
525 return_successful = returnMap(stress_good,
526 stress,
527 intnl_good,
528 intnl,
529 plastic_strain_good,
530 plastic_strain,
531 E_ijkl,
532 dep,
533 yf,
534 iter,
535 step_size <= _max_stepsize_for_dumb,
536 linesearch_needed,
537 ld_encountered,
538 constraints_added,
539 time_simulated + step_size >= 1,
540 consistent_tangent_operator,
542 iterations += iter;
543
544 if (return_successful)
545 {
546 num_consecutive_successes += 1;
547 time_simulated += step_size;
548
549 if (time_simulated < 1.0) // this condition is just for optimization: if time_simulated=1 then
550 // the "good" quantities are no longer needed
551 {
552 stress_good = stress;
553 plastic_strain_good = plastic_strain;
554 for (unsigned model = 0; model < _num_models; ++model)
555 intnl_good[model] = intnl[model];
556 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
557 yf_good[surface] = yf[surface];
558 if (num_consecutive_successes >= 2)
559 step_size *= 1.2;
560 }
561 step_size = std::min(step_size, 1.0 - time_simulated); // avoid overshoots
562 }
563 else
564 {
565 step_size *= 0.5;
566 num_consecutive_successes = 0;
567 stress = stress_good;
568 plastic_strain = plastic_strain_good;
569 for (unsigned model = 0; model < _num_models; ++model)
570 intnl[model] = intnl_good[model];
571 yf.resize(_num_surfaces); // might have excited with junk
572 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
573 yf[surface] = yf_good[surface];
574 dep = step_size * this_strain_increment;
575 }
576 }
577
578 if (!return_successful)
579 {
581 {
582 stress = stress_good;
583 plastic_strain = plastic_strain_good;
584 for (unsigned model = 0; model < _num_models; ++model)
585 intnl[model] = intnl_good[model];
586 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
587 yf[surface] = yf_good[surface];
588 }
589 else
590 {
591 Moose::out << "After reducing the stepsize to " << step_size
592 << " with original strain increment with L2norm " << this_strain_increment.L2norm()
593 << " the returnMap algorithm failed" << std::endl;
594
595 _fspb_debug_stress = stress_good + E_ijkl * dep;
596 _fspb_debug_pm.assign(
598 1); // this is chosen arbitrarily - please change if a more suitable value occurs to you!
600 for (unsigned model = 0; model < _num_models; ++model)
601 _fspb_debug_intnl[model] = intnl_good[model];
605 mooseError("Exiting\n");
606 }
607 }
608
609 return return_successful;
610}
virtual bool returnMap(const RankTwoTensor &stress_old, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, const RankTwoTensor &plastic_strain_old, RankTwoTensor &plastic_strain, const RankFourTensor &E_ijkl, const RankTwoTensor &strain_increment, std::vector< Real > &f, unsigned int &iter, bool can_revert_to_dumb, bool &linesearch_needed, bool &ld_encountered, bool &constraints_added, bool final_step, RankFourTensor &consistent_tangent_operator, std::vector< Real > &cumulative_pm)
Implements the return map.

Referenced by computeQpStress().

◆ postReturnMap()

void ComputeMultiPlasticityStress::postReturnMap ( )
protectedvirtual

Definition at line 337 of file ComputeMultiPlasticityStress.C.

338{
339 if (_n_supplied)
340 {
341 // this is a rotation matrix that will rotate "z" axis back to _n
342 _rot = _rot.transpose();
343
344 // rotate the tensors back to original frame where _n is correctly oriented
346 _Jacobian_mult[_qp].rotate(_rot);
348 _stress[_qp].rotate(_rot);
349 _plastic_strain[_qp].rotate(_rot);
350 if (_cosserat)
351 {
353 (*_Jacobian_mult_couple)[_qp].rotate(_rot);
355 (*_couple_stress)[_qp].rotate(_rot);
356 }
357
358 // Rotate n by _rotation_increment
359 for (const auto i : make_range(Moose::dim))
360 {
361 _n[_qp](i) = 0;
362 for (const auto j : make_range(Moose::dim))
363 _n[_qp](i) += _rotation_increment[_qp](i, j) * _n_old[_qp](j);
364 }
365 }
366}
void rotate(const TypeTensor< T > &R)
void rotate(const RankTwoTensorTempl< T > &R)
IntRange< T > make_range(T beg, T end)

Referenced by computeQpStress().

◆ preReturnMap()

void ComputeMultiPlasticityStress::preReturnMap ( )
protectedvirtual

Definition at line 318 of file ComputeMultiPlasticityStress.C.

319{
320 if (_n_supplied)
321 {
322 // this is a rotation matrix that will rotate _n to the "z" axis
324
325 // rotate the tensors to this frame
328 if (_cosserat)
329 {
332 }
333 }
334}
GenericRealTensorValue< is_ad > rotVecToZ(GenericRealVectorValue< is_ad > vec)

Referenced by computeQpStress().

◆ quickStep()

bool ComputeMultiPlasticityStress::quickStep ( const RankTwoTensor stress_old,
RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
std::vector< Real > &  intnl,
std::vector< Real > &  pm,
std::vector< Real > &  cumulative_pm,
const RankTwoTensor plastic_strain_old,
RankTwoTensor plastic_strain,
const RankFourTensor E_ijkl,
const RankTwoTensor strain_increment,
std::vector< Real > &  yf,
unsigned int iterations,
RankFourTensor consistent_tangent_operator,
const quickStep_called_from_t  called_from,
bool  final_step 
)
protectedvirtual

Attempts to find an admissible (stress, intnl) by using the customized return-map algorithms defined through the SolidMechanicsPlasticXXXX.returnMap functions.

Parameters
stress_oldThe value of stress at the previous "time" step
[out]stressIf returnvalue=true then this is the returned value of stress. Otherwise, this is undefined
intnl_oldThe internal variables at the previous "time" step
[out]intnlIf returnvalue=true then this is the value of the internal parameters after returning. Otherwise, this is undefined
[out]pmIf returnvalue=true, this is the plastic multipliers needed to bring aout the return. Otherwise, this is undefined
[in/out]cumulative_pm If returnvalue=true, this is cumulative plastic multipliers, updated with pm. Otherwise, this is untouched by the algorithm
plastic_strain_oldThe value of plastic strain at the previous "time" step
[out]plastic_strainIf returnvalue=true, this is the new plastic strain. Otherwise it is set to plastic_strain_old
E_ijklThe elasticity tensor.
strain_incrementThe applied strain increment
[out]yfIf returnvalue=true, then all the yield functions at (stress, intnl). Otherwise, all the yield functions at (stress_old, intnl_old)
[out]iterationsNumber of NR iterations used, which is always zero in the current implementation.
called_fromThis can be called from computeQpStress, in which case it can actually provde an answer to the returnmap algorithm, or from returnMap in which case it is probably only providing an answer to a particular subdivision of the returnmap algorithm. The consistent tangent operator is calculated idfferently in each case
final_stepThe consistent tangent operator is calculated if this is true
[out]consistent_tangent_operatorIf final_step==true and returnvalue=true, then this is the consistent tangent operator d(stress_rate)/d(strain_rate). Otherwise it is undefined.
Returns
true if the (stress, intnl) are admissible, in which case the (stress_old, intnl_old) could have been admissible, or exactly one of the plastic models successfully used its custom returnMap function to provide the returned (stress, intnl) values and all other plastic models are admissible at that configuration. Or, false, then (stress_old, intnl_old) is not admissible according to >=1 plastic model and the custom returnMap functions failed in some way.

Definition at line 369 of file ComputeMultiPlasticityStress.C.

384{
385 iterations = 0;
386
387 unsigned num_plastic_returns;
388 RankTwoTensor delta_dp;
389
390 // the following does the customized returnMap algorithm
391 // for all the plastic models.
392 unsigned custom_model = 0;
393 bool successful_return = returnMapAll(stress_old + E_ijkl * strain_increment,
394 intnl_old,
395 E_ijkl,
396 _epp_tol,
397 stress,
398 intnl,
399 pm,
400 cumulative_pm,
401 delta_dp,
402 yf,
403 num_plastic_returns,
404 custom_model);
405
406 // the following updates the plastic_strain, when necessary
407 // and calculates the consistent_tangent_operator, when necessary
408 if (num_plastic_returns == 0)
409 {
410 // if successful_return = true, then a purely elastic step
411 // if successful_return = false, then >=1 plastic model is in
412 // inadmissible zone and failed to return using its customized
413 // returnMap function.
414 // In either case:
415 plastic_strain = plastic_strain_old;
416 if (successful_return && final_step)
417 {
418 if (called_from == computeQpStress_function)
419 consistent_tangent_operator = E_ijkl;
420 else // cannot necessarily use E_ijkl since different plastic models may have been active
421 // during other substeps
422 consistent_tangent_operator =
423 consistentTangentOperator(stress, intnl, E_ijkl, pm, cumulative_pm);
424 }
425 return successful_return;
426 }
427 else if (num_plastic_returns == 1 && successful_return)
428 {
429 // one model has successfully completed its custom returnMap algorithm
430 // and the other models have signalled they are elastic at
431 // the trial stress
432 plastic_strain = plastic_strain_old + delta_dp;
433 if (final_step)
434 {
435 if (called_from == computeQpStress_function && _f[custom_model]->useCustomCTO())
436 {
438 consistent_tangent_operator = E_ijkl;
439 else
440 {
441 std::vector<Real> custom_model_pm;
442 for (unsigned surface = 0; surface < _f[custom_model]->numberSurfaces(); ++surface)
443 custom_model_pm.push_back(cumulative_pm[_surfaces_given_model[custom_model][surface]]);
444 consistent_tangent_operator =
445 _f[custom_model]->consistentTangentOperator(stress_old + E_ijkl * strain_increment,
446 intnl_old[custom_model],
447 stress,
448 intnl[custom_model],
449 E_ijkl,
450 custom_model_pm);
451 }
452 }
453 else // cannot necessarily use the custom consistentTangentOperator since different plastic
454 // models may have been active during other substeps or the custom model says not to use
455 // its custom CTO algorithm
456 consistent_tangent_operator =
457 consistentTangentOperator(stress, intnl, E_ijkl, pm, cumulative_pm);
458 }
459 return true;
460 }
461 else // presumably returnMapAll is incorrectly coded!
462 mooseError("ComputeMultiPlasticityStress::quickStep should not get here!");
463}
RankFourTensor consistentTangentOperator(const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &E_ijkl, const std::vector< Real > &pm_this_step, const std::vector< Real > &cumulative_pm)
Computes the consistent tangent operator (another name for the jacobian = d(stress_rate)/d(strain_rat...
bool returnMapAll(const RankTwoTensor &trial_stress, const std::vector< Real > &intnl_old, const RankFourTensor &E_ijkl, Real ep_plastic_tolerance, RankTwoTensor &stress, std::vector< Real > &intnl, std::vector< Real > &pm, std::vector< Real > &cumulative_pm, RankTwoTensor &delta_dp, std::vector< Real > &yf, unsigned &num_successful_plastic_returns, unsigned &custom_model)
Performs a returnMap for each plastic model using their inbuilt returnMap functions.

Referenced by computeQpStress(), and returnMap().

◆ reinstateLinearDependentConstraints()

bool ComputeMultiPlasticityStress::reinstateLinearDependentConstraints ( std::vector< bool > &  deactivated_due_to_ld)
protectedvirtual

makes all deactivated_due_to_ld false, and if >0 of them were initially true, returns true

Definition at line 1246 of file ComputeMultiPlasticityStress.C.

1248{
1249 bool reinstated_actives = false;
1250 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1251 if (deactivated_due_to_ld[surface])
1252 reinstated_actives = true;
1253
1254 deactivated_due_to_ld.assign(_num_surfaces, false);
1255 return reinstated_actives;
1256}

Referenced by singleStep().

◆ residual2()

Real ComputeMultiPlasticityStress::residual2 ( const std::vector< Real > &  pm,
const std::vector< Real > &  f,
const RankTwoTensor epp,
const std::vector< Real > &  ic,
const std::vector< bool > &  active,
const std::vector< bool > &  deactivated_due_to_ld 
)
protectedvirtual

The residual-squared.

Parameters
pmthe plastic multipliers for all constraints
fthe active yield function(s) (not including the ones that are deactivated_due_to_ld)
eppthe plastic strain increment constraint
icthe active internal constraint(s) (not including the ones that are deactivated_due_to_ld)
activetrue if constraint is active
deactivated_due_to_ldtrue if constraint has been temporarily deactivated due to linear dependence of flow directions

Definition at line 1352 of file ComputeMultiPlasticityStress.C.

1358{
1359 Real nr_res2 = 0;
1360 unsigned ind = 0;
1361
1362 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1363 if (active[surface])
1364 {
1365 if (!deactivated_due_to_ld[surface])
1366 {
1367 if (!(pm[surface] == 0 && f[ind] <= 0))
1368 nr_res2 += 0.5 * Utility::pow<2>(f[ind] / _f[modelNumber(surface)]->_f_tol);
1369 }
1370 else if (deactivated_due_to_ld[surface] && f[ind] > 0)
1371 nr_res2 += 0.5 * Utility::pow<2>(f[ind] / _f[modelNumber(surface)]->_f_tol);
1372 ind++;
1373 }
1374
1375 nr_res2 += 0.5 * Utility::pow<2>(epp.L2norm() / _epp_tol);
1376
1377 std::vector<bool> active_not_deact(_num_surfaces);
1378 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1379 active_not_deact[surface] = (active[surface] && !deactivated_due_to_ld[surface]);
1380 ind = 0;
1381 for (unsigned model = 0; model < _num_models; ++model)
1382 if (anyActiveSurfaces(model, active_not_deact))
1383 nr_res2 += 0.5 * Utility::pow<2>(ic[ind++] / _f[model]->_ic_tol);
1384
1385 return nr_res2;
1386}

Referenced by lineSearch(), and singleStep().

◆ returnMap()

bool ComputeMultiPlasticityStress::returnMap ( const RankTwoTensor stress_old,
RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
std::vector< Real > &  intnl,
const RankTwoTensor plastic_strain_old,
RankTwoTensor plastic_strain,
const RankFourTensor E_ijkl,
const RankTwoTensor strain_increment,
std::vector< Real > &  f,
unsigned int iter,
bool  can_revert_to_dumb,
bool &  linesearch_needed,
bool &  ld_encountered,
bool &  constraints_added,
bool  final_step,
RankFourTensor consistent_tangent_operator,
std::vector< Real > &  cumulative_pm 
)
protectedvirtual

Implements the return map.

Note that this algorithm doesn't do any rotations. In order to find the final stress and plastic_strain must be rotated using _rotation_increment. This is usually done in computeQpStress

Parameters
stress_oldThe value of stress at the previous "time" step
[out]stressThe stress after returning to the yield surface
intnl_oldThe internal variables at the previous "time" step
[out]intnlAll the internal variables after returning to the yield surface
plastic_strain_oldThe value of plastic strain at the previous "time" step
[out]plastic_strainThe value of plastic strain after returning to the yield surface
E_ijklThe elasticity tensor. If no plasticity then stress = stress_old + E_ijkl*strain_increment
strain_incrementThe applied strain increment
[out]fAll the yield functions after returning to the yield surface
[out]iterThe number of Newton-Raphson iterations used
can_revert_to_dumbIf the _deactivation_scheme is set to revert to dumb, it will only be allowed to do so if this parameter is true
[out]linesearch_neededTrue if a linesearch was needed at any stage during the Newton-Raphson proceedure
[out]ld_encounteredTrue if a linear-dependence of the flow directions was encountered at any stage during the Newton-Raphson proceedure
[out]constraints_addedTrue if constraints were added into the active set at any stage during the Newton-Raphson proceedure
final_stepEach strain increment may be decomposed into a sum of smaller increments if the return-map algorithm fails. This flag indicates whether this is the last application of incremental strain
[out]consistent_tangent_operatorThe consistent tangent operator d(stress_rate)/d(strain_rate). This is only output if final_step=true, and the return value of returnMap is also true.
[in,out]cumulative_pmUpon input: the plastic multipliers before the return map. Upon output: the plastic multipliers after this return map, if the return map was successful
Returns
true if the stress was successfully returned to the yield surface

Definition at line 613 of file ComputeMultiPlasticityStress.C.

630{
631
632 // The "consistency parameters" (plastic multipliers)
633 // Change in plastic strain in this timestep = pm*flowPotential
634 // Each pm must be non-negative
635 std::vector<Real> pm;
636 pm.assign(_num_surfaces, 0.0);
637
638 bool successful_return = quickStep(stress_old,
639 stress,
640 intnl_old,
641 intnl,
642 pm,
643 cumulative_pm,
644 plastic_strain_old,
645 plastic_strain,
646 E_ijkl,
647 strain_increment,
648 f,
649 iter,
650 consistent_tangent_operator,
652 final_step);
653
654 if (successful_return)
655 return successful_return;
656
657 // Here we know that the trial stress and intnl_old
658 // is inadmissible, and we have to return from those values
659 // value to the yield surface. There are three
660 // types of constraints we have to satisfy, listed
661 // below, and calculated in calculateConstraints(...)
662 // f<=0, epp=0, ic=0 (up to tolerances), and these are
663 // guaranteed to hold if nr_res2<=0.5
664 //
665 // Kuhn-Tucker conditions must also be satisfied
666 // These are:
667 // pm>=0, which may not hold upon exit of the NR loops
668 // due to _deactivation_scheme!=optimized;
669 // pm*f=0 (up to tolerances), which may not hold upon exit
670 // of the NR loops if a constraint got deactivated
671 // due to linear dependence, and then f<0, and its pm>0
672
673 // Plastic strain constraint, L2 norm must be zero (up to a tolerance)
674 RankTwoTensor epp;
675
676 // Yield function constraint passed to this function as
677 // std::vector<Real> & f
678 // Each yield function must be <= 0 (up to tolerance)
679 // Note that only the constraints that are active will be
680 // contained in f until the final few lines of returnMap
681
682 // Internal constraint(s), must be zero (up to a tolerance)
683 // Note that only the constraints that are active will be
684 // contained in ic.
685 std::vector<Real> ic;
686
687 // Record the stress before Newton-Raphson in case of failure-and-restart
688 RankTwoTensor initial_stress = stress;
689
690 iter = 0;
691
692 // Initialize the set of active constraints
693 // At this stage, the active constraints are
694 // those that exceed their _f_tol
695 // active constraints.
696 std::vector<bool> act;
697 buildActiveConstraints(f, stress, intnl, E_ijkl, act);
698
699 // Inverse of E_ijkl (assuming symmetric)
700 RankFourTensor E_inv = E_ijkl.invSymm();
701
702 // convenience variable that holds the change in plastic strain incurred during the return
703 // delta_dp = plastic_strain - plastic_strain_old
704 // delta_dp = E^{-1}*(initial_stress - stress), where initial_stress = E*(strain -
705 // plastic_strain_old)
706 RankTwoTensor delta_dp = RankTwoTensor();
707
708 // whether single step was successful (whether line search was successful, and whether turning off
709 // constraints was successful)
710 bool single_step_success = true;
711
712 // deactivation scheme
714
715 // For complicated deactivation schemes we have to record the initial active set
716 std::vector<bool> initial_act;
717 initial_act.resize(_num_surfaces);
721 {
722 // if "optimized" fails we can change the deactivation scheme to "safe", etc
723 deact_scheme = optimized;
724 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
725 initial_act[surface] = act[surface];
726 }
727
729 deact_scheme = safe;
730
731 // For "dumb" deactivation, the active set takes all combinations until a solution is found
732 int dumb_iteration = 0;
733 std::vector<unsigned int> dumb_order;
734
735 if (_deactivation_scheme == dumb ||
736 (_deactivation_scheme == optimized_to_safe_to_dumb && can_revert_to_dumb) ||
737 (_deactivation_scheme == safe_to_dumb && can_revert_to_dumb) ||
738 (_deactivation_scheme == optimized_to_dumb && can_revert_to_dumb))
739 buildDumbOrder(stress, intnl, dumb_order);
740
742 {
743 incrementDumb(dumb_iteration, dumb_order, act);
744 yieldFunction(stress, intnl, act, f);
745 }
746
747 // To avoid any re-trials of "act" combinations that
748 // we've already tried and rejected, i record the
749 // combinations in actives_tried
750 std::set<unsigned int> actives_tried;
751 actives_tried.insert(activeCombinationNumber(act));
752
753 // The residual-squared that the line-search will reduce
754 // Later it will get contributions from epp and ic, but
755 // at present these are zero
756 Real nr_res2 = 0;
757 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
758 if (act[surface])
759 nr_res2 += 0.5 * Utility::pow<2>(f[surface] / _f[modelNumber(surface)]->_f_tol);
760
761 successful_return = false;
762
763 bool still_finding_solution = true;
764 while (still_finding_solution)
765 {
766 single_step_success = true;
767 unsigned int local_iter = 0;
768
769 // The Newton-Raphson loops
770 while (nr_res2 > 0.5 && local_iter++ < _max_iter && single_step_success)
771 single_step_success = singleStep(nr_res2,
772 stress,
773 intnl_old,
774 intnl,
775 pm,
776 delta_dp,
777 E_inv,
778 f,
779 epp,
780 ic,
781 act,
782 deact_scheme,
783 linesearch_needed,
784 ld_encountered);
785
786 bool nr_good = (nr_res2 <= 0.5 && local_iter <= _max_iter && single_step_success);
787
788 iter += local_iter;
789
790 // 'act' might have changed due to using deact_scheme = optimized, so
791 actives_tried.insert(activeCombinationNumber(act));
792
793 if (!nr_good)
794 {
795 // failure of NR routine.
796 // We might be able to change the deactivation_scheme and
797 // then re-try the NR starting from the initial values
798 // Or, if deact_scheme == "dumb", we just increarse the
799 // dumb_iteration number and re-try
800 bool change_scheme = false;
801 bool increment_dumb = false;
802 change_scheme = canChangeScheme(deact_scheme, can_revert_to_dumb);
803 if (!change_scheme && deact_scheme == dumb)
804 increment_dumb = canIncrementDumb(dumb_iteration);
805
806 still_finding_solution = (change_scheme || increment_dumb);
807
808 if (change_scheme)
809 changeScheme(initial_act,
810 can_revert_to_dumb,
811 initial_stress,
812 intnl_old,
813 deact_scheme,
814 act,
815 dumb_iteration,
816 dumb_order);
817
818 if (increment_dumb)
819 incrementDumb(dumb_iteration, dumb_order, act);
820
821 if (!still_finding_solution)
822 {
823 // we cannot change the scheme, or have run out of "dumb" options
824 successful_return = false;
825 break;
826 }
827 }
828
829 bool kt_good = false;
830 if (nr_good)
831 {
832 // check Kuhn-Tucker
833 kt_good = checkKuhnTucker(f, pm, act);
834 if (!kt_good)
835 {
836 if (deact_scheme != dumb)
837 {
838 applyKuhnTucker(f, pm, act);
839
840 // true if we haven't tried this active set before
841 still_finding_solution =
842 (actives_tried.find(activeCombinationNumber(act)) == actives_tried.end());
843 if (!still_finding_solution)
844 {
845 // must have tried turning off the constraints already.
846 // so try changing the scheme
847 if (canChangeScheme(deact_scheme, can_revert_to_dumb))
848 {
849 still_finding_solution = true;
850 changeScheme(initial_act,
851 can_revert_to_dumb,
852 initial_stress,
853 intnl_old,
854 deact_scheme,
855 act,
856 dumb_iteration,
857 dumb_order);
858 }
859 }
860 }
861 else
862 {
863 bool increment_dumb = false;
864 increment_dumb = canIncrementDumb(dumb_iteration);
865 still_finding_solution = increment_dumb;
866 if (increment_dumb)
867 incrementDumb(dumb_iteration, dumb_order, act);
868 }
869
870 if (!still_finding_solution)
871 {
872 // have tried turning off the constraints already,
873 // or have run out of "dumb" options
874 successful_return = false;
875 break;
876 }
877 }
878 }
879
880 bool admissible = false;
881 if (nr_good && kt_good)
882 {
883 // check admissible
884 std::vector<Real> all_f;
885 if (_num_surfaces == 1)
886 admissible = true; // for a single surface if NR has exited successfully then (stress,
887 // intnl) must be admissible
888 else
889 admissible = checkAdmissible(stress, intnl, all_f);
890
891 if (!admissible)
892 {
893 // Not admissible.
894 // We can try adding constraints back in
895 // We can try changing the deactivation scheme
896 // Or, if deact_scheme == dumb, just increase dumb_iteration
897 bool add_constraints = canAddConstraints(act, all_f);
898 if (add_constraints)
899 {
900 constraints_added = true;
901 std::vector<bool> act_plus(_num_surfaces,
902 false); // "act" with the positive constraints added in
903 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
904 if (act[surface] ||
905 (!act[surface] && (all_f[surface] > _f[modelNumber(surface)]->_f_tol)))
906 act_plus[surface] = true;
907 if (actives_tried.find(activeCombinationNumber(act_plus)) == actives_tried.end())
908 {
909 // haven't tried this combination of actives yet
910 constraints_added = true;
911 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
912 act[surface] = act_plus[surface];
913 }
914 else
915 add_constraints = false; // haven't managed to add a new combination
916 }
917
918 bool change_scheme = false;
919 bool increment_dumb = false;
920
921 if (!add_constraints)
922 change_scheme = canChangeScheme(deact_scheme, can_revert_to_dumb);
923
924 if (!add_constraints && !change_scheme && deact_scheme == dumb)
925 increment_dumb = canIncrementDumb(dumb_iteration);
926
927 still_finding_solution = (add_constraints || change_scheme || increment_dumb);
928
929 if (change_scheme)
930 changeScheme(initial_act,
931 can_revert_to_dumb,
932 initial_stress,
933 intnl_old,
934 deact_scheme,
935 act,
936 dumb_iteration,
937 dumb_order);
938
939 if (increment_dumb)
940 incrementDumb(dumb_iteration, dumb_order, act);
941
942 if (!still_finding_solution)
943 {
944 // we cannot change the scheme, or have run out of "dumb" options
945 successful_return = false;
946 break;
947 }
948 }
949 }
950
951 successful_return = (nr_good && admissible && kt_good);
952 if (successful_return)
953 break;
954
955 if (still_finding_solution)
956 {
957 stress = initial_stress;
958 delta_dp = RankTwoTensor(); // back to zero change in plastic strain
959 for (unsigned model = 0; model < _num_models; ++model)
960 intnl[model] = intnl_old[model]; // back to old internal params
961 pm.assign(_num_surfaces, 0.0); // back to zero plastic multipliers
962
963 unsigned num_active = numberActive(act);
964 if (num_active == 0)
965 {
966 successful_return = false;
967 break; // failure
968 }
969
970 actives_tried.insert(activeCombinationNumber(act));
971
972 // Since "act" set has changed, either by changing deact_scheme, or by KT failing, so need to
973 // re-calculate nr_res2
974 yieldFunction(stress, intnl, act, f);
975
976 nr_res2 = 0;
977 unsigned ind = 0;
978 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
979 if (act[surface])
980 {
981 if (f[ind] > _f[modelNumber(surface)]->_f_tol)
982 nr_res2 += 0.5 * Utility::pow<2>(f[ind] / _f[modelNumber(surface)]->_f_tol);
983 ind++;
984 }
985 }
986 }
987
988 // returned, with either success or failure
989 if (successful_return)
990 {
991 plastic_strain += delta_dp;
992
993 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
994 cumulative_pm[surface] += pm[surface];
995
996 if (final_step)
997 consistent_tangent_operator =
998 consistentTangentOperator(stress, intnl, E_ijkl, pm, cumulative_pm);
999
1000 if (f.size() != _num_surfaces)
1001 {
1002 // at this stage f.size() = num_active, but we need to return with all the yield functions
1003 // evaluated, so:
1004 act.assign(_num_surfaces, true);
1005 yieldFunction(stress, intnl, act, f);
1006 }
1007 }
1008
1009 return successful_return;
1010}
virtual unsigned int numberActive(const std::vector< bool > &active)
counts the number of active constraints
virtual bool checkAdmissible(const RankTwoTensor &stress, const std::vector< Real > &intnl, std::vector< Real > &all_f)
Checks whether the yield functions are in the admissible region.
unsigned int activeCombinationNumber(const std::vector< bool > &act)
virtual void applyKuhnTucker(const std::vector< Real > &f, const std::vector< Real > &pm, std::vector< bool > &active)
Checks Kuhn-Tucker conditions, and alters "active" if appropriate.
void changeScheme(const std::vector< bool > &initial_act, bool can_revert_to_dumb, const RankTwoTensor &initial_stress, const std::vector< Real > &intnl_old, DeactivationSchemeEnum &current_deactivation_scheme, std::vector< bool > &act, int &dumb_iteration, std::vector< unsigned int > &dumb_order)
virtual bool singleStep(Real &nr_res2, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, RankTwoTensor &delta_dp, const RankFourTensor &E_inv, std::vector< Real > &f, RankTwoTensor &epp, std::vector< Real > &ic, std::vector< bool > &active, DeactivationSchemeEnum deactivation_scheme, bool &linesearch_needed, bool &ld_encountered)
Performs a single Newton-Raphson + linesearch step Constraints are deactivated and the step is re-don...
bool canAddConstraints(const std::vector< bool > &act, const std::vector< Real > &all_f)
bool canChangeScheme(DeactivationSchemeEnum current_deactivation_scheme, bool can_revert_to_dumb)
virtual bool checkKuhnTucker(const std::vector< Real > &f, const std::vector< Real > &pm, const std::vector< bool > &active)
Checks Kuhn-Tucker conditions, and alters "active" if appropriate.
virtual void buildActiveConstraints(const std::vector< Real > &f, const RankTwoTensor &stress, const std::vector< Real > &intnl, const RankFourTensor &Eijkl, std::vector< bool > &act)
Constructs a set of active constraints, given the yield functions, f.

Referenced by plasticStep().

◆ returnMapAll()

bool MultiPlasticityRawComponentAssembler::returnMapAll ( const RankTwoTensor trial_stress,
const std::vector< Real > &  intnl_old,
const RankFourTensor E_ijkl,
Real  ep_plastic_tolerance,
RankTwoTensor stress,
std::vector< Real > &  intnl,
std::vector< Real > &  pm,
std::vector< Real > &  cumulative_pm,
RankTwoTensor delta_dp,
std::vector< Real > &  yf,
unsigned &  num_successful_plastic_returns,
unsigned &  custom_model 
)
protectedinherited

Performs a returnMap for each plastic model using their inbuilt returnMap functions.

Performs a returnMap for each plastic model.

This may be used to quickly ascertain whether a (trial_stress, intnl_old) configuration is admissible, or whether a single model's customized returnMap function can provide a solution to the return-map problem, or whether a full Newton-Raphson approach such as implemented in ComputeMultiPlasticityStress is needed.

There are three cases mentioned below: (A) The (trial_stress, intnl_old) configuration is admissible according to all plastic models (B) The (trial_stress, intnl_old) configuration is inadmissible to exactly one plastic model, and that model can successfully use its customized returnMap function to provide a returned (stress, intnl) configuration, and that configuration is admissible according to all plastic models (C) All other cases. This includes customized returnMap functions failing, or more than one plastic_model being inadmissible, etc

Parameters
trial_stressthe trial stress
intnl_oldthe old values of the internal parameters
E_ijklthe elasticity tensor
ep_plastic_tolerancethe tolerance on the plastic strain
[out]stressis set to trial_stress in case (A) or (C), and the returned value of stress in case (B).
[out]intnlis set to intnl_old in case (A) or (C), and the returned value of intnl in case (B)
[out]pmZero in case (A) or (C), otherwise the plastic multipliers needed to bring about the returnMap in case (B)
[in/out]cumulative_pm cumulative plastic multipliers, updated in case (B), otherwise left untouched
[out]delta_dpis unchanged in case (A) or (C), and is set to the change in plastic strain in case(B)
[out]yfwill contain the yield function values at (stress, intnl)
[out]num_successful_plastic_returnswill be 0 for (A) and (C), and 1 for (B)
Returns
true in case (A) and (B), and false in case (C)

If all models actually signal "elastic" by returning true from their returnMap, and by returning model_plastically_active=0, then yf will contain the yield function values num_successful_plastic_returns will be zero intnl = intnl_old delta_dp will be unchanged from its input value stress will be set to trial_stress pm will be zero cumulative_pm will be unchanged return value will be true num_successful_plastic_returns = 0

If only one model signals "plastically active" by returning true from its returnMap, and by returning model_plastically_active=1, then yf will contain the yield function values num_successful_plastic_returns will be one intnl will be set by the returnMap algorithm delta_dp will be set by the returnMap algorithm stress will be set by the returnMap algorithm pm will be nonzero for the single model, and zero for other models cumulative_pm will be updated return value will be true num_successful_plastic_returns = 1

If >1 model signals "plastically active" or if >=1 model's returnMap fails, then yf will contain the yield function values num_successful_plastic_returns will be set appropriately intnl = intnl_old delta_dp will be unchanged from its input value stress will be set to trial_stress pm will be zero cumulative_pm will be unchanged return value will be true if all returnMap functions returned true, otherwise it will be false num_successful_plastic_returns is set appropriately

Definition at line 597 of file MultiPlasticityRawComponentAssembler.C.

609{
610 mooseAssert(intnl_old.size() == _num_models,
611 "returnMapAll: Incorrect size of internal parameters");
612 mooseAssert(intnl.size() == _num_models, "returnMapAll: Incorrect size of internal parameters");
613 mooseAssert(pm.size() == _num_surfaces, "returnMapAll: Incorrect size of pm");
614
615 num_successful_plastic_returns = 0;
616 yf.resize(0);
617 pm.assign(_num_surfaces, 0.0);
618
619 RankTwoTensor returned_stress; // each model will give a returned_stress. if only one model is
620 // plastically active, i set stress=returned_stress, so as to
621 // record this returned value
622 std::vector<Real> model_f;
623 RankTwoTensor model_delta_dp;
624 std::vector<Real> model_pm;
625 bool trial_stress_inadmissible;
626 bool successful_return = true;
627 unsigned the_single_plastic_model = 0;
628 bool using_custom_return_map = true;
629
630 // run through all the plastic models, performing their
631 // returnMap algorithms.
632 // If one finds (trial_stress, intnl) inadmissible and
633 // successfully returns, break from the loop to evaluate
634 // all the others at that returned stress
635 for (unsigned model = 0; model < _num_models; ++model)
636 {
637 if (using_custom_return_map)
638 {
639 model_pm.assign(_f[model]->numberSurfaces(), 0.0);
640 bool model_returned = _f[model]->returnMap(trial_stress,
641 intnl_old[model],
642 E_ijkl,
643 ep_plastic_tolerance,
644 returned_stress,
645 intnl[model],
646 model_pm,
647 model_delta_dp,
648 model_f,
649 trial_stress_inadmissible);
650 if (!trial_stress_inadmissible)
651 {
652 // in the elastic zone: record the yield-function values (returned_stress, intnl, model_pm
653 // and model_delta_dp are undefined)
654 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces();
655 ++model_surface)
656 yf.push_back(model_f[model_surface]);
657 }
658 else if (trial_stress_inadmissible && !model_returned)
659 {
660 // in the plastic zone, and the customized returnMap failed
661 // for some reason (or wasn't implemented). The coder
662 // should have correctly returned model_f(trial_stress, intnl_old)
663 // so record them
664 // (returned_stress, intnl, model_pm and model_delta_dp are undefined)
665 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces();
666 ++model_surface)
667 yf.push_back(model_f[model_surface]);
668 // now there's almost zero point in using the custom
669 // returnMap functions
670 using_custom_return_map = false;
671 successful_return = false;
672 }
673 else
674 {
675 // in the plastic zone, and the customized returnMap
676 // succeeded.
677 // record the first returned_stress and delta_dp if everything is going OK
678 // as they could be the actual answer
679 if (trial_stress_inadmissible)
680 num_successful_plastic_returns++;
681 the_single_plastic_model = model;
682 stress = returned_stress;
683 // note that i break here, and don't push_back
684 // model_f to yf. So now yf contains only the values of
685 // model_f from previous models to the_single_plastic_model
686 // also i don't set delta_dp = model_delta_dp yet, because
687 // i might find problems later on
688 // also, don't increment cumulative_pm for the same reason
689
690 break;
691 }
692 }
693 else
694 {
695 // not using custom returnMap functions because one
696 // has already failed and that one said trial_stress
697 // was inadmissible. So now calculate the yield functions
698 // at the trial stress
699 _f[model]->yieldFunctionV(trial_stress, intnl_old[model], model_f);
700 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
701 yf.push_back(model_f[model_surface]);
702 }
703 }
704
705 if (num_successful_plastic_returns == 0)
706 {
707 // here either all the models were elastic (successful_return=true),
708 // or some were plastic and either the customized returnMap failed
709 // or wasn't implemented (successful_return=false).
710 // In either case, have to set the following:
711 stress = trial_stress;
712 for (unsigned model = 0; model < _num_models; ++model)
713 intnl[model] = intnl_old[model];
714 return successful_return;
715 }
716
717 // Now we know that num_successful_plastic_returns == 1 and all the other
718 // models (with model number < the_single_plastic_model) must have been
719 // admissible at (trial_stress, intnl). However, all models might
720 // not be admissible at (trial_stress, intnl), so must check that
721 std::vector<Real> yf_at_returned_stress(0);
722 bool all_admissible = true;
723 for (unsigned model = 0; model < _num_models; ++model)
724 {
725 if (model == the_single_plastic_model)
726 {
727 // no need to spend time calculating the yield function: we know its admissible
728 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
729 yf_at_returned_stress.push_back(model_f[model_surface]);
730 continue;
731 }
732 _f[model]->yieldFunctionV(stress, intnl_old[model], model_f);
733 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
734 {
735 if (model_f[model_surface] > _f[model]->_f_tol)
736 // bummer, this model is not admissible at the returned_stress
737 all_admissible = false;
738 yf_at_returned_stress.push_back(model_f[model_surface]);
739 }
740 if (!all_admissible)
741 // no point in continuing computing yield functions
742 break;
743 }
744
745 if (!all_admissible)
746 {
747 // we tried using the returned value of stress predicted by
748 // the_single_plastic_model, but it wasn't admissible according
749 // to other plastic models. We need to set:
750 stress = trial_stress;
751 for (unsigned model = 0; model < _num_models; ++model)
752 intnl[model] = intnl_old[model];
753 // and calculate the remainder of the yield functions at trial_stress
754 for (unsigned model = the_single_plastic_model; model < _num_models; ++model)
755 {
756 _f[model]->yieldFunctionV(trial_stress, intnl[model], model_f);
757 for (unsigned model_surface = 0; model_surface < _f[model]->numberSurfaces(); ++model_surface)
758 yf.push_back(model_f[model_surface]);
759 }
760 num_successful_plastic_returns = 0;
761 return false;
762 }
763
764 // So the customized returnMap algorithm can provide a returned
765 // (stress, intnl) configuration, and that is admissible according
766 // to all plastic models
767 yf.resize(0);
768 for (unsigned surface = 0; surface < yf_at_returned_stress.size(); ++surface)
769 yf.push_back(yf_at_returned_stress[surface]);
770 delta_dp = model_delta_dp;
771 for (unsigned model_surface = 0; model_surface < _f[the_single_plastic_model]->numberSurfaces();
772 ++model_surface)
773 {
774 cumulative_pm[_surfaces_given_model[the_single_plastic_model][model_surface]] +=
775 model_pm[model_surface];
776 pm[_surfaces_given_model[the_single_plastic_model][model_surface]] = model_pm[model_surface];
777 }
778 custom_model = the_single_plastic_model;
779 return true;
780}

Referenced by quickStep().

◆ rot()

RankTwoTensor ComputeMultiPlasticityStress::rot ( const RankTwoTensor tens)
private

Definition at line 310 of file ComputeMultiPlasticityStress.C.

311{
312 if (!_n_supplied)
313 return tens;
314 return tens.rotated(_rot);
315}
RankTwoTensorTempl< T > rotated(const RankTwoTensorTempl< T > &R) const

Referenced by computeQpStress().

◆ singleStep()

bool ComputeMultiPlasticityStress::singleStep ( Real &  nr_res2,
RankTwoTensor stress,
const std::vector< Real > &  intnl_old,
std::vector< Real > &  intnl,
std::vector< Real > &  pm,
RankTwoTensor delta_dp,
const RankFourTensor E_inv,
std::vector< Real > &  f,
RankTwoTensor epp,
std::vector< Real > &  ic,
std::vector< bool > &  active,
DeactivationSchemeEnum  deactivation_scheme,
bool &  linesearch_needed,
bool &  ld_encountered 
)
protectedvirtual

Performs a single Newton-Raphson + linesearch step Constraints are deactivated and the step is re-done if deactivation_scheme is set appropriately.

Parameters
[in,out]nr_res2Residual-squared that the line-search will reduce
[in,out]stressstress
[in]intnl_oldold values of the internal parameters
[in,out]intnlinternal parameters
[in,out]pmplastic multipliers
[in,out]delta_dpChange in plastic strain from start of "time" step to current configuration (plastic_strain - plastic_strain_old)
[in]E_invInverse of the elasticity tensor
[in,out]fYield function(s). Upon successful exit only the active constraints are contained in f
[in,out]eppPlastic strain increment constraint
[in,out]icInternal constraint. Upon successful exit only the active constraints are contained in ic
activeThe active constraints. This is may be modified, depending upon deactivation_scheme
deactivation_schemeThe scheme used for deactivating constraints
[out]linesearch_neededTrue if a linesearch was employed during this Newton-Raphson step
[out]ld_encounteredTrue if a linear-dependence of the flow directions was encountered at any stage during the Newton-Raphson proceedure
Returns
true if the step was successful, ie, if the linesearch was successful and the number of constraints wasn't reduced to zero via deactivation

Definition at line 1080 of file ComputeMultiPlasticityStress.C.

1094{
1095 bool successful_step; // return value
1096
1097 Real nr_res2_before_step = nr_res2;
1098 RankTwoTensor stress_before_step;
1099 std::vector<Real> intnl_before_step;
1100 std::vector<Real> pm_before_step;
1101 RankTwoTensor delta_dp_before_step;
1102
1103 if (deactivation_scheme == optimized)
1104 {
1105 // we potentially use the "before_step" quantities, so record them here
1106 stress_before_step = stress;
1107 intnl_before_step.resize(_num_models);
1108 for (unsigned model = 0; model < _num_models; ++model)
1109 intnl_before_step[model] = intnl[model];
1110 pm_before_step.resize(_num_surfaces);
1111 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1112 pm_before_step[surface] = pm[surface];
1113 delta_dp_before_step = delta_dp;
1114 }
1115
1116 // During the Newton-Raphson procedure, we'll be
1117 // changing the following parameters in order to
1118 // (attempt to) satisfy the constraints.
1119 RankTwoTensor dstress; // change in stress
1120 std::vector<Real> dpm; // change in plasticity multipliers ("consistency parameters"). For ALL
1121 // contraints (active and deactive)
1122 std::vector<Real>
1123 dintnl; // change in internal parameters. For ALL internal params (active and deactive)
1124
1125 // The constraints that have been deactivated for this NR step
1126 // due to the flow directions being linearly dependent
1127 std::vector<bool> deact_ld;
1128 deact_ld.assign(_num_surfaces, false);
1129
1130 /* After NR and linesearch, if _deactivation_scheme == "optimized", the
1131 * active plasticity multipliers are checked for non-negativity. If some
1132 * are negative then they are deactivated forever, and the NR step is
1133 * re-done starting from the _before_step quantities recorded above
1134 */
1135 bool constraints_changing = true;
1136 bool reinstated_actives;
1137 while (constraints_changing)
1138 {
1139 // calculate dstress, dpm and dintnl for one full Newton-Raphson step
1140 nrStep(stress, intnl_old, intnl, pm, E_inv, delta_dp, dstress, dpm, dintnl, active, deact_ld);
1141
1142 for (unsigned surface = 0; surface < deact_ld.size(); ++surface)
1143 if (deact_ld[surface])
1144 {
1145 ld_encountered = true;
1146 break;
1147 }
1148
1149 // perform a line search
1150 // The line-search will exit with updated values
1151 successful_step = lineSearch(nr_res2,
1152 stress,
1153 intnl_old,
1154 intnl,
1155 pm,
1156 E_inv,
1157 delta_dp,
1158 dstress,
1159 dpm,
1160 dintnl,
1161 f,
1162 epp,
1163 ic,
1164 active,
1165 deact_ld,
1166 linesearch_needed);
1167
1168 if (!successful_step)
1169 // completely bomb out
1170 return successful_step;
1171
1172 // See if any active constraints need to be removed, and the step re-done
1173 constraints_changing = false;
1174 if (deactivation_scheme == optimized)
1175 {
1176 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1177 if (active[surface] && pm[surface] < 0.0)
1178 constraints_changing = true;
1179 }
1180
1181 if (constraints_changing)
1182 {
1183 stress = stress_before_step;
1184 delta_dp = delta_dp_before_step;
1185 nr_res2 = nr_res2_before_step;
1186 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1187 {
1188 if (active[surface] && pm[surface] < 0.0)
1189 {
1190 // turn off the constraint forever
1191 active[surface] = false;
1192 pm_before_step[surface] = 0.0;
1193 intnl_before_step[modelNumber(surface)] =
1194 intnl_old[modelNumber(surface)]; // don't want to muck-up hardening!
1195 }
1196 intnl[modelNumber(surface)] = intnl_before_step[modelNumber(surface)];
1197 pm[surface] = pm_before_step[surface];
1198 }
1199 if (numberActive(active) == 0)
1200 {
1201 // completely bomb out
1202 successful_step = false;
1203 return successful_step;
1204 }
1205 }
1206
1207 // reinstate any active values that have been turned off due to linear-dependence
1208 reinstated_actives = reinstateLinearDependentConstraints(deact_ld);
1209 } // ends "constraints_changing" loop
1210
1211 // if active constraints were reinstated then nr_res2 needs to be re-calculated so it is correct
1212 // upson returning
1213 if (reinstated_actives)
1214 {
1215 bool completely_converged = true;
1216 if (successful_step && nr_res2 < 0.5)
1217 {
1218 // Here we have converged to the correct solution if
1219 // all the yield functions are < 0. Excellent!
1220 //
1221 // This is quite tricky - perhaps i can refactor to make it more obvious.
1222 //
1223 // Because actives are now reinstated, the residual2
1224 // calculation below will give nr_res2 > 0.5, because it won't
1225 // realise that we only had to set the active-but-not-deactivated f = 0,
1226 // and not the entire active set. If we pass that nr_res2 back from
1227 // this function then the calling function will not realise we've converged!
1228 // Therefore, check for this case
1229 unsigned ind = 0;
1230 for (unsigned surface = 0; surface < _num_surfaces; ++surface)
1231 if (active[surface])
1232 if (f[ind++] > _f[modelNumber(surface)]->_f_tol)
1233 completely_converged = false;
1234 }
1235 else
1236 completely_converged = false;
1237
1238 if (!completely_converged)
1239 nr_res2 = residual2(pm, f, epp, ic, active, deact_ld);
1240 }
1241
1242 return successful_step;
1243}
virtual bool reinstateLinearDependentConstraints(std::vector< bool > &deactivated_due_to_ld)
makes all deactivated_due_to_ld false, and if >0 of them were initially true, returns true
virtual bool lineSearch(Real &nr_res2, RankTwoTensor &stress, const std::vector< Real > &intnl_old, std::vector< Real > &intnl, std::vector< Real > &pm, const RankFourTensor &E_inv, RankTwoTensor &delta_dp, const RankTwoTensor &dstress, const std::vector< Real > &dpm, const std::vector< Real > &dintnl, std::vector< Real > &f, RankTwoTensor &epp, std::vector< Real > &ic, const std::vector< bool > &active, const std::vector< bool > &deactivated_due_to_ld, bool &linesearch_needed)
Performs a line search.

Referenced by returnMap().

◆ singularValuesOfR()

int MultiPlasticityLinearSystem::singularValuesOfR ( const std::vector< RankTwoTensor > &  r,
std::vector< Real > &  s 
)
privatevirtualinherited

Performs a singular-value decomposition of r and returns the singular values.

Example: If r has size 5 then the singular values of the following matrix are returned: ( r[0](0,0) r[0](0,1) r[0](0,2) r[0](1,1) r[0](1,2) r[0](2,2) ) ( r[1](0,0) r[1](0,1) r[1](0,2) r[1](1,1) r[1](1,2) r[1](2,2) ) a = ( r[2](0,0) r[2](0,1) r[2](0,2) r[2](1,1) r[2](1,2) r[2](2,2) ) ( r[3](0,0) r[3](0,1) r[3](0,2) r[3](1,1) r[3](1,2) r[3](2,2) ) ( r[4](0,0) r[4](0,1) r[4](0,2) r[4](1,1) r[4](1,2) r[4](2,2) )

Parameters
rThe flow directions
[out]sThe singular values
Returns
The return value from the PETSc LAPACK gesvd reoutine

Definition at line 45 of file MultiPlasticityLinearSystem.C.

47{
48 PetscBLASInt bm = r.size();
49 PetscBLASInt bn = 6;
50
51 s.resize(std::min(bm, bn));
52
53 // prepare for gesvd or gesdd routine provided by PETSc
54 // Want to find the singular values of matrix
55 // ( r[0](0,0) r[0](0,1) r[0](0,2) r[0](1,1) r[0](1,2) r[0](2,2) )
56 // ( r[1](0,0) r[1](0,1) r[1](0,2) r[1](1,1) r[1](1,2) r[1](2,2) )
57 // a = ( r[2](0,0) r[2](0,1) r[2](0,2) r[2](1,1) r[2](1,2) r[2](2,2) )
58 // ( r[3](0,0) r[3](0,1) r[3](0,2) r[3](1,1) r[3](1,2) r[3](2,2) )
59 // ( r[4](0,0) r[4](0,1) r[4](0,2) r[4](1,1) r[4](1,2) r[4](2,2) )
60 // bm = 5
61
62 std::vector<double> a(bm * 6);
63 // Fill in the a "matrix" by going down columns
64 unsigned ind = 0;
65 for (int col = 0; col < 3; ++col)
66 for (int row = 0; row < bm; ++row)
67 a[ind++] = r[row](0, col);
68 for (int col = 3; col < 5; ++col)
69 for (int row = 0; row < bm; ++row)
70 a[ind++] = r[row](1, col - 2);
71 for (int row = 0; row < bm; ++row)
72 a[ind++] = r[row](2, 2);
73
74 // u and vt are dummy variables because they won't
75 // get referenced due to the "N" and "N" choices
76 PetscBLASInt sizeu = 1;
77 std::vector<double> u(sizeu);
78 PetscBLASInt sizevt = 1;
79 std::vector<double> vt(sizevt);
80
81 PetscBLASInt sizework =
82 16 * (bm + 6); // this is above the lowerbound specified in the LAPACK doco
83 std::vector<double> work(sizework);
84
85 PetscBLASInt info;
86
87 LAPACKgesvd_("N",
88 "N",
89 &bm,
90 &bn,
91 &a[0],
92 &bm,
93 &s[0],
94 &u[0],
95 &sizeu,
96 &vt[0],
97 &sizevt,
98 &work[0],
99 &sizework,
100 &info);
101
102 return info;
103}

Referenced by MultiPlasticityLinearSystem::eliminateLinearDependence().

◆ validParams()

InputParameters ComputeMultiPlasticityStress::validParams ( )
static

Definition at line 22 of file ComputeMultiPlasticityStress.C.

23{
26 params.addClassDescription("Base class for multi-surface finite-strain plasticity");
27 params.addRangeCheckedParam<unsigned int>("max_NR_iterations",
28 20,
29 "max_NR_iterations>0",
30 "Maximum number of Newton-Raphson iterations allowed");
31 params.addRequiredParam<Real>("ep_plastic_tolerance",
32 "The Newton-Raphson process is only deemed "
33 "converged if the plastic strain increment "
34 "constraints have L2 norm less than this.");
36 "min_stepsize",
37 0.01,
38 "min_stepsize>0 & min_stepsize<=1",
39 "If ordinary Newton-Raphson + line-search fails, then the applied strain increment is "
40 "subdivided, and the return-map is tried again. This parameter is the minimum fraction of "
41 "applied strain increment that may be applied before the algorithm gives up entirely");
42 params.addRangeCheckedParam<Real>("max_stepsize_for_dumb",
43 0.01,
44 "max_stepsize_for_dumb>0 & max_stepsize_for_dumb<=1",
45 "If your deactivation_scheme is 'something_to_dumb', then "
46 "'dumb' will only be used if the stepsize falls below this "
47 "value. This parameter is useful because the 'dumb' scheme is "
48 "computationally expensive");
49 MooseEnum deactivation_scheme("optimized safe dumb optimized_to_safe safe_to_dumb "
50 "optimized_to_safe_to_dumb optimized_to_dumb",
51 "optimized");
52 params.addParam<MooseEnum>(
53 "deactivation_scheme",
54 deactivation_scheme,
55 "Scheme by which constraints are deactivated. (NOTE: This is irrelevant if there is only "
56 "one yield surface.) safe: return to the yield surface and then deactivate constraints with "
57 "negative plasticity multipliers. optimized: deactivate a constraint as soon as its "
58 "plasticity multiplier becomes negative. dumb: iteratively try all combinations of active "
59 "constraints until the solution is found. You may specify fall-back options. Eg "
60 "optimized_to_safe: first use 'optimized', and if that fails, try the return with 'safe'.");
62 "transverse_direction",
63 "If this parameter is provided, before the return-map algorithm is "
64 "called a rotation is performed so that the 'z' axis in the new "
65 "frame lies along the transverse_direction in the original frame. "
66 "After returning, the inverse rotation is performed. The "
67 "transverse_direction will itself rotate with large strains. This "
68 "is so that transversely-isotropic plasticity models may be easily "
69 "defined in the frame where the isotropy holds in the x-y plane.");
70 params.addParam<bool>("ignore_failures",
71 false,
72 "The return-map algorithm will return with the best admissible "
73 "stresses and internal parameters that it can, even if they don't "
74 "fully correspond to the applied strain increment. To speed "
75 "computations, this flag can be set to true, the max_NR_iterations "
76 "set small, and the min_stepsize large.");
77 MooseEnum tangent_operator("elastic linear nonlinear", "nonlinear");
78 params.addParam<MooseEnum>("tangent_operator",
79 tangent_operator,
80 "Type of tangent operator to return. 'elastic': return the "
81 "elasticity tensor. 'linear': return the consistent tangent operator "
82 "that is correct for plasticity with yield functions linear in "
83 "stress. 'nonlinear': return the full, general consistent tangent "
84 "operator. The calculations assume the hardening potentials are "
85 "independent of stress and hardening parameters.");
86 params.addParam<bool>("perform_finite_strain_rotations",
87 true,
88 "Tensors are correctly rotated in "
89 "finite-strain simulations. For "
90 "optimal performance you can set "
91 "this to 'false' if you are only "
92 "ever using small strains");
93 params.addClassDescription("Material for multi-surface finite-strain plasticity");
94 return params;
95}
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
static InputParameters validParams()

◆ yieldFunction()

void MultiPlasticityRawComponentAssembler::yieldFunction ( const RankTwoTensor stress,
const std::vector< Real > &  intnl,
const std::vector< bool > &  active,
std::vector< Real > &  f 
)
protectedvirtualinherited

The active yield function(s)

Parameters
stressthe stress at which to calculate the yield function
intnlvector of internal parameters
activeset of active constraints - only the active yield functions are put into "f"
[out]fthe yield function (or functions in the case of multisurface plasticity)

Definition at line 96 of file MultiPlasticityRawComponentAssembler.C.

100{
101 mooseAssert(intnl.size() == _num_models, "Incorrect size of internal parameters");
102 mooseAssert(active.size() == _num_surfaces, "Incorrect size of active");
103
104 f.resize(0);
105 std::vector<unsigned int> active_surfaces_of_model;
106 std::vector<unsigned int>::iterator active_surface;
107 std::vector<Real> model_f;
108 for (unsigned model = 0; model < _num_models; ++model)
109 {
110 activeModelSurfaces(model, active, active_surfaces_of_model);
111 if (active_surfaces_of_model.size() > 0)
112 {
113 _f[model]->yieldFunctionV(stress, intnl[model], model_f);
114 for (active_surface = active_surfaces_of_model.begin();
115 active_surface != active_surfaces_of_model.end();
116 ++active_surface)
117 f.push_back(model_f[*active_surface]);
118 }
119 }
120}

Referenced by buildDumbOrder(), MultiPlasticityLinearSystem::calculateConstraints(), checkAdmissible(), MultiPlasticityDebugger::fddyieldFunction_dintnl(), MultiPlasticityDebugger::fddyieldFunction_dstress(), and returnMap().

Member Data Documentation

◆ _base_name

const std::string ComputeGeneralStressBase::_base_name
protectedinherited

Base name prepended to all material property names to allow for multi-material systems.

Definition at line 43 of file ComputeGeneralStressBase.h.

Referenced by ComputeCosseratLinearElasticStress::initialSetup(), and ComputeLinearElasticStress::initialSetup().

◆ _constraints_added

MaterialProperty<Real>& ComputeMultiPlasticityStress::_constraints_added
protected

Whether constraints were added in during the latest Newton-Raphson process (1 if true, 0 otherwise)

Definition at line 127 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _cosserat

bool ComputeMultiPlasticityStress::_cosserat
protected

whether Cosserat mechanics should be used

Definition at line 151 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), initQpStatefulProperties(), postReturnMap(), and preReturnMap().

◆ _couple_stress

MaterialProperty<RankTwoTensor>* const ComputeMultiPlasticityStress::_couple_stress
protected

the Cosserat couple-stress

Definition at line 160 of file ComputeMultiPlasticityStress.h.

◆ _couple_stress_old

const MaterialProperty<RankTwoTensor>* const ComputeMultiPlasticityStress::_couple_stress_old
protected

the old value of Cosserat couple-stress

Definition at line 163 of file ComputeMultiPlasticityStress.h.

◆ _cumulative_pm

std::vector<Real> ComputeMultiPlasticityStress::_cumulative_pm
protected

the sum of the plastic multipliers over all the sub-steps.

This is used for calculating the consistent tangent operator

Definition at line 66 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and plasticStep().

◆ _curvature

const MaterialProperty<RankTwoTensor>* const ComputeMultiPlasticityStress::_curvature
protected

The Cosserat curvature strain.

Definition at line 154 of file ComputeMultiPlasticityStress.h.

◆ _deactivation_scheme

enum ComputeMultiPlasticityStress::DeactivationSchemeEnum ComputeMultiPlasticityStress::_deactivation_scheme
protected

◆ _dummy_pm

std::vector<Real> ComputeMultiPlasticityStress::_dummy_pm
protected

dummy "consistency parameters" (plastic multipliers) used in quickStep when called from computeQpStress

Definition at line 60 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _elastic_flexural_rigidity_tensor

const MaterialProperty<RankFourTensor>* const ComputeMultiPlasticityStress::_elastic_flexural_rigidity_tensor
protected

The Cosserat elastic flexural rigidity tensor.

Definition at line 157 of file ComputeMultiPlasticityStress.h.

◆ _elastic_strain

MaterialProperty<RankTwoTensor>& ComputeGeneralStressBase::_elastic_strain
protectedinherited

◆ _elastic_strain_old

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_elastic_strain_old
protected

Old value of elastic strain.

Definition at line 148 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _elasticity_tensor

const MaterialProperty<RankFourTensor>& ComputeMultiPlasticityStress::_elasticity_tensor
protected

Elasticity tensor material property.

Definition at line 100 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _elasticity_tensor_name

const std::string ComputeMultiPlasticityStress::_elasticity_tensor_name
protected

Name of the elasticity tensor material property.

Definition at line 98 of file ComputeMultiPlasticityStress.h.

◆ _epp_tol

Real ComputeMultiPlasticityStress::_epp_tol
protected

Tolerance on the plastic strain increment ("direction") constraint.

Definition at line 57 of file ComputeMultiPlasticityStress.h.

Referenced by ComputeMultiPlasticityStress(), quickStep(), and residual2().

◆ _extra_stress

const MaterialProperty<RankTwoTensor>& ComputeGeneralStressBase::_extra_stress
protectedinherited

Extra stress tensor.

Definition at line 53 of file ComputeGeneralStressBase.h.

Referenced by ComputeGeneralStressBase::computeQpProperties().

◆ _f

std::vector<const SolidMechanicsPlasticModel *> MultiPlasticityRawComponentAssembler::_f
protectedinherited

◆ _fspb_debug

MooseEnum MultiPlasticityDebugger::_fspb_debug
protectedinherited

none - don't do any debugging crash - currently inactive jacobian - check the jacobian entries jacobian_and_linear_system - check entire jacobian and check that Ax=b

Definition at line 57 of file MultiPlasticityDebugger.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _fspb_debug_intnl

std::vector<Real> MultiPlasticityDebugger::_fspb_debug_intnl
protectedinherited

◆ _fspb_debug_intnl_change

std::vector<Real> MultiPlasticityDebugger::_fspb_debug_intnl_change
protectedinherited

◆ _fspb_debug_pm

std::vector<Real> MultiPlasticityDebugger::_fspb_debug_pm
protectedinherited

◆ _fspb_debug_pm_change

std::vector<Real> MultiPlasticityDebugger::_fspb_debug_pm_change
protectedinherited

Debug finite-differencing parameters for the plastic multipliers.

Definition at line 72 of file MultiPlasticityDebugger.h.

Referenced by MultiPlasticityDebugger::fdJacobian(), and MultiPlasticityDebugger::outputAndCheckDebugParameters().

◆ _fspb_debug_stress

RankTwoTensor MultiPlasticityDebugger::_fspb_debug_stress
protectedinherited

◆ _fspb_debug_stress_change

Real MultiPlasticityDebugger::_fspb_debug_stress_change
protectedinherited

◆ _ignore_failures

bool ComputeMultiPlasticityStress::_ignore_failures
protected

Even if the returnMap fails, return the best values found for stress and internal parameters.

Definition at line 46 of file ComputeMultiPlasticityStress.h.

Referenced by plasticStep().

◆ _initial_stress_fcn

std::vector<const Function *> ComputeGeneralStressBase::_initial_stress_fcn
protectedinherited

initial stress components

Definition at line 56 of file ComputeGeneralStressBase.h.

◆ _intnl

MaterialProperty<std::vector<Real> >& ComputeMultiPlasticityStress::_intnl
protected

internal parameters

Definition at line 109 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _intnl_old

const MaterialProperty<std::vector<Real> >& ComputeMultiPlasticityStress::_intnl_old
protected

old values of internal parameters

Definition at line 112 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and plasticStep().

◆ _iter

MaterialProperty<Real>& ComputeMultiPlasticityStress::_iter
protected

Number of Newton-Raphson iterations used in the return-map.

Definition at line 118 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _Jacobian_mult

MaterialProperty<RankFourTensor>& ComputeGeneralStressBase::_Jacobian_mult
protectedinherited

◆ _Jacobian_mult_couple

MaterialProperty<RankFourTensor>* const ComputeMultiPlasticityStress::_Jacobian_mult_couple
protected

derivative of couple-stress w.r.t. curvature

Definition at line 166 of file ComputeMultiPlasticityStress.h.

◆ _ld_encountered

MaterialProperty<Real>& ComputeMultiPlasticityStress::_ld_encountered
protected

Whether linear-dependence was encountered in the latest Newton-Raphson process (1 if true, 0 otherwise)

Definition at line 124 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _linesearch_needed

MaterialProperty<Real>& ComputeMultiPlasticityStress::_linesearch_needed
protected

Whether a line-search was needed in the latest Newton-Raphson process (1 if true, 0 otherwise)

Definition at line 121 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().

◆ _max_iter

unsigned int ComputeMultiPlasticityStress::_max_iter
protected

Maximum number of Newton-Raphson iterations allowed.

Definition at line 37 of file ComputeMultiPlasticityStress.h.

Referenced by returnMap().

◆ _max_stepsize_for_dumb

Real ComputeMultiPlasticityStress::_max_stepsize_for_dumb
protected

"dumb" deactivation will only be used if the stepsize falls below this quantity

Definition at line 43 of file ComputeMultiPlasticityStress.h.

Referenced by plasticStep().

◆ _mechanical_strain

const MaterialProperty<RankTwoTensor>& ComputeGeneralStressBase::_mechanical_strain
protectedinherited

◆ _min_f_tol

Real MultiPlasticityLinearSystem::_min_f_tol
protectedinherited

Minimum value of the _f_tol parameters for the Yield Function User Objects.

Definition at line 131 of file MultiPlasticityLinearSystem.h.

Referenced by MultiPlasticityLinearSystem::eliminateLinearDependence(), and MultiPlasticityLinearSystem::MultiPlasticityLinearSystem().

◆ _min_stepsize

Real ComputeMultiPlasticityStress::_min_stepsize
protected

Minimum fraction of applied strain that may be applied during adaptive stepsizing.

Definition at line 40 of file ComputeMultiPlasticityStress.h.

Referenced by plasticStep().

◆ _model_given_surface

std::vector<unsigned int> MultiPlasticityRawComponentAssembler::_model_given_surface
privateinherited

◆ _model_surface_given_surface

std::vector<unsigned int> MultiPlasticityRawComponentAssembler::_model_surface_given_surface
privateinherited

given a surface number, this returns the corresponding-model's internal surface number

Definition at line 294 of file MultiPlasticityRawComponentAssembler.h.

Referenced by MultiPlasticityRawComponentAssembler::MultiPlasticityRawComponentAssembler().

◆ _my_curvature

RankTwoTensor ComputeMultiPlasticityStress::_my_curvature
protected

Curvature that can be rotated by this class, and split into multiple increments (ie, its not const)

Definition at line 178 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), postReturnMap(), and preReturnMap().

◆ _my_elasticity_tensor

RankFourTensor ComputeMultiPlasticityStress::_my_elasticity_tensor
protected

Elasticity tensor that can be rotated by this class (ie, its not const)

Definition at line 169 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), plasticStep(), postReturnMap(), and preReturnMap().

◆ _my_flexural_rigidity_tensor

RankFourTensor ComputeMultiPlasticityStress::_my_flexural_rigidity_tensor
protected

Flexual rigidity tensor that can be rotated by this class (ie, its not const)

Definition at line 175 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), postReturnMap(), and preReturnMap().

◆ _my_strain_increment

RankTwoTensor ComputeMultiPlasticityStress::_my_strain_increment
protected

Strain increment that can be rotated by this class, and split into multiple increments (ie, its not const)

Definition at line 172 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), postReturnMap(), and preReturnMap().

◆ _n

MaterialProperty<RealVectorValue>& ComputeMultiPlasticityStress::_n
protected

current value of transverse direction

Definition at line 130 of file ComputeMultiPlasticityStress.h.

Referenced by initQpStatefulProperties(), postReturnMap(), and preReturnMap().

◆ _n_input

RealVectorValue ComputeMultiPlasticityStress::_n_input
protected

the supplied transverse direction vector

Definition at line 89 of file ComputeMultiPlasticityStress.h.

Referenced by ComputeMultiPlasticityStress(), and initQpStatefulProperties().

◆ _n_old

const MaterialProperty<RealVectorValue>& ComputeMultiPlasticityStress::_n_old
protected

old value of transverse direction

Definition at line 133 of file ComputeMultiPlasticityStress.h.

Referenced by postReturnMap().

◆ _n_supplied

bool ComputeMultiPlasticityStress::_n_supplied
protected

User supplied the transverse direction vector.

Definition at line 86 of file ComputeMultiPlasticityStress.h.

Referenced by ComputeMultiPlasticityStress(), postReturnMap(), preReturnMap(), and rot().

◆ _num_models

unsigned int MultiPlasticityRawComponentAssembler::_num_models
protectedinherited

◆ _num_surfaces

unsigned int MultiPlasticityRawComponentAssembler::_num_surfaces
protectedinherited

Number of surfaces within the plastic models.

For many situations this will be = _num_models since each model will contain just one surface. More generally it is >= _num_models. For instance, Mohr-Coulomb is a single model with 6 surfaces

Definition at line 62 of file MultiPlasticityRawComponentAssembler.h.

Referenced by activeCombinationNumber(), applyKuhnTucker(), MultiPlasticityRawComponentAssembler::buildActiveConstraints(), buildDumbOrder(), MultiPlasticityLinearSystem::calculateConstraints(), MultiPlasticityLinearSystem::calculateJacobian(), MultiPlasticityLinearSystem::calculateRHS(), canAddConstraints(), canIncrementDumb(), changeScheme(), checkAdmissible(), MultiPlasticityDebugger::checkDerivatives(), MultiPlasticityDebugger::checkJacobian(), checkKuhnTucker(), MultiPlasticityDebugger::checkSolution(), ComputeMultiPlasticityStress(), computeQpStress(), consistentTangentOperator(), MultiPlasticityRawComponentAssembler::dflowPotential_dintnl(), MultiPlasticityRawComponentAssembler::dflowPotential_dstress(), MultiPlasticityRawComponentAssembler::dhardPotential_dintnl(), MultiPlasticityRawComponentAssembler::dhardPotential_dstress(), MultiPlasticityDebugger::dof_included(), MultiPlasticityRawComponentAssembler::dyieldFunction_dintnl(), MultiPlasticityRawComponentAssembler::dyieldFunction_dstress(), MultiPlasticityLinearSystem::eliminateLinearDependence(), MultiPlasticityDebugger::fddflowPotential_dintnl(), MultiPlasticityDebugger::fddflowPotential_dstress(), MultiPlasticityDebugger::fddyieldFunction_dintnl(), MultiPlasticityDebugger::fddyieldFunction_dstress(), MultiPlasticityDebugger::fdJacobian(), MultiPlasticityRawComponentAssembler::flowPotential(), MultiPlasticityRawComponentAssembler::hardPotential(), incrementDumb(), initQpStatefulProperties(), MultiPlasticityRawComponentAssembler::MultiPlasticityRawComponentAssembler(), MultiPlasticityLinearSystem::nrStep(), numberActive(), MultiPlasticityDebugger::outputAndCheckDebugParameters(), plasticStep(), reinstateLinearDependentConstraints(), residual2(), returnMap(), MultiPlasticityRawComponentAssembler::returnMapAll(), singleStep(), and MultiPlasticityRawComponentAssembler::yieldFunction().

◆ _params

const InputParameters& MultiPlasticityRawComponentAssembler::_params
protectedinherited

◆ _perform_finite_strain_rotations

bool ComputeMultiPlasticityStress::_perform_finite_strain_rotations
protected

whether to perform the rotations necessary in finite-strain simulations

Definition at line 95 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _plastic_strain

MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_plastic_strain
protected

plastic strain

Definition at line 103 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), initQpStatefulProperties(), and postReturnMap().

◆ _plastic_strain_old

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_plastic_strain_old
protected

Old value of plastic strain.

Definition at line 106 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _rot

RealTensorValue ComputeMultiPlasticityStress::_rot
protected

rotation matrix that takes _n to (0, 0, 1)

Definition at line 92 of file ComputeMultiPlasticityStress.h.

Referenced by postReturnMap(), preReturnMap(), and rot().

◆ _rotation_increment

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_rotation_increment
protected

Rotation increment (coming from ComputeIncrementalStrain, for example)

Definition at line 142 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and postReturnMap().

◆ _specialIC

MooseEnum MultiPlasticityRawComponentAssembler::_specialIC
protectedinherited

◆ _strain_increment

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_strain_increment
protected

strain increment (coming from ComputeIncrementalStrain, for example)

Definition at line 136 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _stress

MaterialProperty<RankTwoTensor>& ComputeGeneralStressBase::_stress
protectedinherited

Stress material property.

Definition at line 48 of file ComputeGeneralStressBase.h.

Referenced by ComputeMultipleInelasticStressBase::computeAdmissibleState(), ComputeMultipleInelasticCosseratStress::computeAdmissibleState(), ComputeGeneralStressBase::computeQpProperties(), computeQpStress(), ComputeStrainIncrementBasedStress::computeQpStress(), FiniteStrainPlasticMaterial::computeQpStress(), AbaqusUMATStress::computeQpStress(), ComputeCosseratLinearElasticStress::computeQpStress(), ComputeFiniteStrainElasticStress::computeQpStress(), ComputeLinearElasticPFFractureStress::computeQpStress(), ComputeLinearElasticStress::computeQpStress(), ComputeLinearViscoelasticStress::computeQpStress(), ComputeMultipleInelasticStressBase::computeQpStress(), ComputeSmearedCrackingStress::computeQpStress(), ComputeMultipleCrystalPlasticityStress::computeQpStress(), ComputeMultipleInelasticStressBase::computeQpStressIntermediateConfiguration(), ComputeLinearElasticPFFractureStress::computeStrainSpectral(), ComputeLinearElasticPFFractureStress::computeStrainVolDev(), ComputeLinearElasticPFFractureStress::computeStressSpectral(), ComputeCreepPlasticityStress::computeTangentOperators(), ComputeMultipleInelasticStressBase::finiteStrainRotation(), FiniteStrainCrystalPlasticity::initQpStatefulProperties(), FiniteStrainUObasedCP::initQpStatefulProperties(), FiniteStrainHyperElasticViscoPlastic::initQpStatefulProperties(), ComputeGeneralStressBase::initQpStatefulProperties(), postReturnMap(), FiniteStrainCrystalPlasticity::postSolveQp(), FiniteStrainUObasedCP::postSolveQp(), FiniteStrainHyperElasticViscoPlastic::postSolveQp(), ComputeSmearedCrackingStress::updateCrackingStateAndStress(), ComputeCreepPlasticityStress::updateQpState(), ComputeMultipleInelasticStress::updateQpState(), and ComputeMultipleInelasticStressBase::updateQpStateSingleModel().

◆ _stress_old

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_stress_old
protected

Old value of stress.

Definition at line 145 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress().

◆ _surfaces_given_model

std::vector<std::vector<unsigned int> > MultiPlasticityRawComponentAssembler::_surfaces_given_model
protectedinherited

◆ _svd_tol

Real MultiPlasticityLinearSystem::_svd_tol
protectedinherited

Tolerance on the minimum ratio of singular values before flow-directions are deemed linearly dependent.

Definition at line 128 of file MultiPlasticityLinearSystem.h.

Referenced by MultiPlasticityLinearSystem::eliminateLinearDependence().

◆ _tangent_operator_type

enum ComputeMultiPlasticityStress::TangentOperatorEnum ComputeMultiPlasticityStress::_tangent_operator_type
protected

◆ _total_strain_old

const MaterialProperty<RankTwoTensor>& ComputeMultiPlasticityStress::_total_strain_old
protected

Old value of total strain (coming from ComputeIncrementalStrain, for example)

Definition at line 139 of file ComputeMultiPlasticityStress.h.

◆ _yf

MaterialProperty<std::vector<Real> >& ComputeMultiPlasticityStress::_yf
protected

yield functions

Definition at line 115 of file ComputeMultiPlasticityStress.h.

Referenced by computeQpStress(), and initQpStatefulProperties().


The documentation for this class was generated from the following files: