12#include "libmesh/utility.h"
13#include "libmesh/int_range.h"
23 "Optional parameter that allows the user to define multiple crystal plasticity mechanisms");
25 "Crystal Plasticity base class: handles the Newton iteration over the stress residual and "
26 "calculates the Jacobian based on constitutive laws provided by inheriting classes");
30 params.
set<
bool>(
"compute") =
false;
34 "crystal_lattice_type",
36 "Crystal lattice type or representative unit cell, i.e., BCC, FCC, HCP, etc.");
39 "unit_cell_dimension",
40 std::vector<Real>{1.0, 1.0, 1.0},
41 "unit_cell_dimension_size = 3",
42 "The dimension of the unit cell along three directions, where a cubic unit cell is assumed "
43 "for cubic crystals and a hexagonal unit cell (a, a, c) is assumed for HCP crystals. These "
44 "dimensions will be taken into account while computing the slip systems."
45 " Default size is 1.0 along all three directions.");
48 "number_slip_systems",
49 "The total number of possible active slip systems for the crystalline material");
52 "Name of the file containing the slip systems, one slip system per row, with the slip plane "
53 "normal given before the slip plane direction.");
54 params.
addParam<Real>(
"number_cross_slip_directions",
56 "Quanity of unique slip directions, used to determine cross slip familes");
57 params.
addParam<Real>(
"number_cross_slip_planes",
59 "Quanity of slip planes belonging to a single cross slip direction; used "
60 "to determine cross slip families");
62 "slip_increment_tolerance",
64 "Maximum allowable slip in an increment for each individual constitutive model");
66 "stol", 1e-2,
"Constitutive internal state variable relative change tolerance");
67 params.
addParam<Real>(
"resistance_tol",
69 "Constitutive slip system resistance relative residual tolerance for each "
70 "individual constitutive model");
73 "Tolerance for residual check when variable value is zero for each "
74 "individual constitutive model");
76 "print_state_variable_convergence_error_messages",
78 "Whether or not to print warning messages from the crystal plasticity specific convergence "
79 "checks on both the constiutive model internal state variables.");
86 _base_name(isParamValid(
"base_name") ? getParam<
std::string>(
"base_name") +
"_" :
""),
87 _crystal_lattice_type(
89 _unit_cell_dimension(getParam<
std::vector<Real>>(
"unit_cell_dimension")),
90 _number_slip_systems(getParam<unsigned
int>(
"number_slip_systems")),
91 _slip_sys_file_name(getParam<FileName>(
"slip_sys_file_name")),
92 _number_cross_slip_directions(getParam<Real>(
"number_cross_slip_directions")),
93 _number_cross_slip_planes(getParam<Real>(
"number_cross_slip_planes")),
95 _rel_state_var_tol(getParam<Real>(
"stol")),
96 _slip_incr_tol(getParam<Real>(
"slip_increment_tolerance")),
97 _resistance_tol(getParam<Real>(
"resistance_tol")),
98 _zero_tol(getParam<Real>(
"zero_tol")),
100 _slip_resistance(declareProperty<
std::vector<Real>>(_base_name +
"slip_resistance")),
101 _slip_resistance_old(getMaterialPropertyOld<
std::vector<Real>>(_base_name +
"slip_resistance")),
102 _slip_increment(declareProperty<
std::vector<Real>>(_base_name +
"slip_increment")),
104 _slip_direction(_number_slip_systems),
105 _slip_plane_normal(_number_slip_systems),
106 _flow_direction(declareProperty<
std::vector<
RankTwoTensor>>(_base_name +
"flow_direction")),
107 _tau(declareProperty<
std::vector<Real>>(_base_name +
"applied_shear_stress")),
108 _print_convergence_message(getParam<bool>(
"print_state_variable_convergence_error_messages"))
143 bool orthonormal_error =
false;
147 _reader.
setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS);
153 "number_slip_systems",
154 "The number of rows in the slip system file should match the number of slip system.");
171 for (
const auto j : index_range(_reader.
getData(i)))
193 orthonormal_error =
true;
199 if (orthonormal_error)
200 mooseError(
"CrystalPlasticityStressUpdateBase Error: The slip system file contains a slip "
201 "direction and plane normal pair that are not orthonormal in the Cartesian "
202 "coordinate system.");
209 const unsigned int miller_bravais_indices = 4;
210 RealVectorValue temporary_slip_direction, temporary_slip_plane;
216 mooseError(
"CrystalPlasticityStressUpdateBase Error: The specified unit cell dimensions are "
217 "not consistent with expectations for "
218 "HCP crystal hexagonal lattices.");
219 else if (reader.
getData(0).size() != miller_bravais_indices * 2)
220 mooseError(
"CrystalPlasticityStressUpdateBase Error: The number of entries in the first row of "
221 "the slip system file is not consistent with the expectations for the 4-index "
222 "Miller-Bravais assumption for HCP crystals. This file should represent both the "
223 "slip plane normal and the slip direction with 4-indices each.");
227 transform_matrix.zero();
236 for (
const auto j : index_range(reader.
getData(i)))
239 Real basal_pl_sum = 0.0;
241 basal_pl_sum += reader.
getData(i)[k];
245 "CrystalPlasticityStressUpdateBase Error: The specified HCP basal plane Miller-Bravais "
246 "indices do not sum to zero. Check the values supplied in the associated text file.");
249 Real basal_dir_sum = 0.0;
250 for (
const auto k : make_range(miller_bravais_indices, miller_bravais_indices + LIBMESH_DIM))
251 basal_dir_sum += reader.
getData(i)[k];
254 mooseError(
"CrystalPlasticityStressUpdateBase Error: The specified HCP slip direction "
255 "Miller-Bravais indices in the basal plane (U, V, and T) do not sum to zero "
256 "within the user specified tolerance (try loosing zero_tol if using the default "
257 "value). Check the values supplied in the associated text file.");
259 if (j < miller_bravais_indices)
265 temporary_slip_plane(j) = reader.
getData(i)[j];
268 temporary_slip_plane(j - 1) = reader.
getData(i)[j];
272 const auto direction_j = j - miller_bravais_indices;
276 temporary_slip_direction(direction_j) = reader.
getData(i)[j];
278 else if (direction_j == 3)
279 temporary_slip_direction(direction_j - 1) = reader.
getData(i)[j];
305 unsigned int family_counter = 1;
310 for (
unsigned int j = 0; j < family_counter; ++j)
314 Real dot_product = 0.0;
321 if (MooseUtils::absoluteFuzzyEqual(dot_product, 0.0))
326 "Exceeded the number of cross slip planes allowed in a single cross slip family");
332 else if (j == (family_counter - 1) && !MooseUtils::absoluteFuzzyEqual(dot_product, 0.0))
335 mooseError(
"Exceeds the number of cross slip directions specified for this material");
349 Moose::out <<
"In cross slip family " << i << std::endl;
365 mooseError(
"The supplied slip system index is not among the slip system families sorted.");
377 const unsigned int & number_slip_systems,
378 const std::vector<RealVectorValue> & plane_normal_vector,
379 const std::vector<RealVectorValue> & direction_vector,
380 std::vector<RankTwoTensor> & schmid_tensor,
383 std::vector<RealVectorValue> local_direction_vector, local_plane_normal;
384 local_direction_vector.resize(number_slip_systems);
385 local_plane_normal.resize(number_slip_systems);
390 local_direction_vector[i].zero();
391 local_plane_normal[i].zero();
396 local_direction_vector[i](j) =
397 local_direction_vector[i](j) + crysrot(j, k) * direction_vector[i](k);
399 local_plane_normal[i](j) =
400 local_plane_normal[i](j) + crysrot(j, k) * plane_normal_vector[i](k);
407 schmid_tensor[i](j, k) = local_direction_vector[i](j) * local_plane_normal[i](k);
416 const unsigned int & num_eigenstrains)
418 if (!num_eigenstrains)
431 eigenstrain_deformation_grad.
transpose() * pk2 *
432 inverse_eigenstrain_deformation_grad.
transpose();
441 const RankTwoTensor & inverse_eigenstrain_deformation_grad_old,
442 const unsigned int & num_eigenstrains)
452 if (num_eigenstrains)
455 inverse_eigenstrain_deformation_grad_old.
inverse();
456 dtaudpk2[j] = eigenstrain_deformation_grad_old.det() * eigenstrain_deformation_grad_old *
462 dfpinvdpk2 += (dfpinvdslip[j] * dslip_dtau[j] *
_substep_dt).outerProduct(dtaudpk2[j]);
489 const std::vector<Real> & current_var,
490 const std::vector<Real> & var_before_update,
491 const std::vector<Real> & previous_substep_var,
492 const Real & tolerance)
495 unsigned int sz = current_var.
size();
496 mooseAssert(current_var.size() == sz,
"Current variable size does not match");
497 mooseAssert(var_before_update.size() == sz,
"Variable before update size does not match");
498 mooseAssert(previous_substep_var.size() == sz,
"Previous substep variable size does not match");
500 bool is_converged =
true;
503 Real abs_prev_substep_val = 0.0;
504 for (
const auto i : make_range(sz))
506 diff_val = std::abs(var_before_update[i] - current_var[i]);
507 abs_prev_substep_val = std::abs(previous_substep_var[i]);
510 if (abs_prev_substep_val < _zero_tol && diff_val >
_zero_tol)
511 is_converged =
false;
512 else if (abs_prev_substep_val >
_zero_tol && diff_val > tolerance * abs_prev_substep_val)
513 is_converged =
false;
void ErrorVector unsigned int
virtual void calculateEquivalentSlipIncrement(RankTwoTensor &)
const unsigned int _number_slip_systems
Maximum number of active slip systems for the crystalline material being modeled.
MaterialProperty< std::vector< Real > > & _slip_resistance
Slip system resistance.
virtual void calculateTotalPlasticDeformationGradientDerivative(RankFourTensor &dfpinvdpk2, const RankTwoTensor &inverse_plastic_deformation_grad_old, const RankTwoTensor &inverse_eigenstrain_deformation_grad_old, const unsigned int &num_eigenstrains)
Calculates the total value of $\frac{d\mathbf{F}^P^{-1}}{d\mathbf{PK2}}$ and is intended to be an ove...
virtual void setMaterialVectorSize()
CrystalPlasticityStressUpdateBase(const InputParameters ¶meters)
const Real _number_cross_slip_directions
Parameters to characterize the cross slip behavior of the crystal.
void setQp(const unsigned int &qp)
Sets the value of the global variable _qp for inheriting classes.
unsigned int identifyCrossSlipFamily(const unsigned int index)
A helper method for inherting classes to identify to which cross slip family vector a particular slip...
const bool _print_convergence_message
Flag to print to console warning messages on stress, constitutive model convergence.
MaterialProperty< std::vector< Real > > & _slip_increment
Current slip increment material property.
void sortCrossSlipFamilies()
A helper method to sort the slip systems of a crystal into cross slip families based on common slip d...
Real _substep_dt
Substepping time step value used within the inheriting constitutive models.
void transformHexagonalMillerBravaisSlipSystems(const MooseUtils::DelimitedFileReader &reader)
A helper method to transform the Miller-Bravais 4-index notation for HCP crystals into a a 3-index Ca...
virtual void initQpStatefulProperties() override
initializes the stateful properties such as PK2 stress, resolved shear stress, plastic deformation gr...
enum CrystalPlasticityStressUpdateBase::CrystalLatticeType _crystal_lattice_type
Real _zero_tol
Residual tolerance when variable value is zero. Default 1e-12.
static InputParameters validParams()
std::vector< RealVectorValue > _slip_plane_normal
MaterialProperty< std::vector< RankTwoTensor > > & _flow_direction
void calculateShearStress(const RankTwoTensor &pk2, const RankTwoTensor &inverse_eigenstrain_deformation_grad, const unsigned int &num_eigenstrains)
Computes the shear stess for each slip system.
void setSubstepDt(const Real &substep_dt)
Sets the value of the _substep_dt for inheriting classes.
void calculateFlowDirection(const RankTwoTensor &crysrot)
Computes the Schmid tensor (m x n) for the original (reference) crystal lattice orientation for each ...
const Real _number_cross_slip_planes
const std::vector< Real > _unit_cell_dimension
std::vector< std::vector< unsigned int > > _cross_slip_familes
Sorted slip system indices into cross slip family groups.
MaterialProperty< std::vector< Real > > & _tau
Resolved shear stress on each slip system.
bool _calculate_cross_slip
Flag to run the cross slip calculations if cross slip numbers are specified.
std::string _slip_sys_file_name
File should contain slip plane normal and direction.
virtual void calculateConstitutiveSlipDerivative(std::vector< Real > &)=0
This virtual method is called to find the derivative of the slip increment with respect to the applie...
void calculateSchmidTensor(const unsigned int &number_dislocation_systems, const std::vector< RealVectorValue > &plane_normal_vector, const std::vector< RealVectorValue > &direction_vector, std::vector< RankTwoTensor > &schmid_tensor, const RankTwoTensor &crysrot)
A helper method to rotate the a direction and plane normal system set into the local crystal llatice ...
std::vector< RealVectorValue > _slip_direction
Slip system direction and normal and associated Schmid tensors.
virtual bool isConstitutiveStateVariableConverged(const std::vector< Real > ¤t_var, const std::vector< Real > &var_before_update, const std::vector< Real > &previous_substep_var, const Real &tolerance)
Check if a typical state variable, e.g.
virtual void getSlipSystems()
A helper method to read in plane normal and direction vectors from a file and to normalize the vector...
virtual unsigned int size() const override final
virtual void resize(const std::size_t size) override final
static InputParameters validParams()
const InputParameters & parameters() const
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
void mooseWarning(Args &&... args) const
const std::vector< std::vector< T > > & getData() const
void setFormatFlag(FormatFlag value)
T doubleContraction(const RankTwoTensorTempl< T > &a) const
RankTwoTensorTempl< T > inverse() const
RankTwoTensorTempl< T > transpose() const
static constexpr std::size_t dim
static constexpr Real TOLERANCE