https://mooseframework.inl.gov
Loading...
Searching...
No Matches
FiniteStrainHyperElasticViscoPlastic.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "libmesh/utility.h"
12
14
17{
19 params.addParam<Real>(
20 "resid_abs_tol", 1e-10, "Absolute Tolerance for flow rate residual equation");
21 params.addParam<Real>(
22 "resid_rel_tol", 1e-6, "Relative Tolerance for flow rate residual equation");
23 params.addParam<unsigned int>("maxiters", 50, "Maximum iteration for flow rate update");
24 params.addParam<unsigned int>("max_substep_iteration", 1, "Maximum number of substep iteration");
25 params.addParam<std::vector<UserObjectName>>(
26 "flow_rate_user_objects",
27 "List of User object names that computes flow rate and derivatives");
28 params.addParam<std::vector<UserObjectName>>(
29 "strength_user_objects",
30 "List of User object names that computes strength variables and derivatives");
31 params.addParam<std::vector<UserObjectName>>(
32 "internal_var_user_objects",
33 "List of User object names that integrates internal variables and computes derivatives");
34 params.addParam<std::vector<UserObjectName>>(
35 "internal_var_rate_user_objects",
36 "List of User object names that computes internal variable rates and derivatives");
37 params.addClassDescription("Material class for hyper-elastic viscoplatic flow: Can handle "
38 "multiple flow models defined by flowratemodel type user objects");
39
40 return params;
41}
42
44 const InputParameters & parameters)
45 : ComputeStressBase(parameters),
46 _resid_abs_tol(getParam<Real>("resid_abs_tol")),
47 _resid_rel_tol(getParam<Real>("resid_rel_tol")),
48 _maxiters(getParam<unsigned int>("maxiters")),
49 _max_substep_iter(getParam<unsigned int>("max_substep_iteration")),
50 _flow_rate_uo_names(isParamValid("flow_rate_user_objects")
51 ? getParam<std::vector<UserObjectName>>("flow_rate_user_objects")
52 : std::vector<UserObjectName>(0)),
53 _strength_uo_names(isParamValid("strength_user_objects")
54 ? getParam<std::vector<UserObjectName>>("strength_user_objects")
55 : std::vector<UserObjectName>(0)),
56 _int_var_uo_names(isParamValid("internal_var_user_objects")
57 ? getParam<std::vector<UserObjectName>>("internal_var_user_objects")
58 : std::vector<UserObjectName>(0)),
59 _int_var_rate_uo_names(
60 isParamValid("internal_var_rate_user_objects")
61 ? getParam<std::vector<UserObjectName>>("internal_var_rate_user_objects")
62 : std::vector<UserObjectName>(0)),
63 _pk2_prop_name(_base_name + "pk2"),
64 _pk2(declareProperty<RankTwoTensor>(_pk2_prop_name)),
65 _fp(declareProperty<RankTwoTensor>(_base_name + "fp")),
66 _fp_old(getMaterialPropertyOld<RankTwoTensor>(_base_name + "fp")),
67 _ce(declareProperty<RankTwoTensor>(_base_name + "ce")),
68 _elasticity_tensor_name(_base_name + "elasticity_tensor"),
69 _elasticity_tensor(getMaterialPropertyByName<RankFourTensor>(_elasticity_tensor_name)),
70 _deformation_gradient(getMaterialProperty<RankTwoTensor>(_base_name + "deformation_gradient")),
71 _deformation_gradient_old(
72 getMaterialPropertyOld<RankTwoTensor>(_base_name + "deformation_gradient")),
73 _rotation_increment(getMaterialProperty<RankTwoTensor>(_base_name + "rotation_increment"))
74{
76
78
82
84}
85
86void
108
109void
111 const std::vector<UserObjectName> & uo_names, unsigned int & uo_num)
112{
113 uo_num = uo_names.size();
114}
115
116template <typename T>
117void
118FiniteStrainHyperElasticViscoPlastic::initProp(const std::vector<UserObjectName> & uo_names,
119 unsigned int uo_num,
120 std::vector<MaterialProperty<T> *> & uo_prop)
121{
122 uo_prop.resize(uo_num);
123 for (unsigned int i = 0; i < uo_num; ++i)
124 uo_prop[i] = &declareProperty<T>(uo_names[i]);
125}
126
127template <typename T>
128void
130 const std::vector<UserObjectName> & uo_names,
131 unsigned int uo_num,
132 std::vector<const MaterialProperty<T> *> & uo_prop_old)
133{
134 uo_prop_old.resize(uo_num);
135 for (unsigned int i = 0; i < uo_num; ++i)
136 uo_prop_old[i] = &getMaterialPropertyOld<T>(uo_names[i]);
137}
138
139template <typename T>
140void
141FiniteStrainHyperElasticViscoPlastic::initUserObjects(const std::vector<UserObjectName> & uo_names,
142 unsigned int uo_num,
143 std::vector<const T *> & uo)
144{
145 uo.resize(uo_num);
146
147 if (uo_num == 0)
148 mooseError("Specify atleast one user object of type", typeid(T).name());
149
150 for (unsigned int i = 0; i < uo_num; ++i)
151 uo[i] = &getUserObjectByName<T>(uo_names[i]);
152}
153
154void
181
182void
184{
185 _stress[_qp].zero();
186 _ce[_qp].zero();
187 _pk2[_qp].zero();
188 _fp[_qp].setToIdentity();
189
190 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
191 (*_flow_rate_prop[i])[_qp] = 0.0;
192
193 for (unsigned int i = 0; i < _num_strength_uos; ++i)
194 (*_strength_prop[i])[_qp] = 0.0;
195
196 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
197 {
198 (*_int_var_stateful_prop[i])[_qp] = 0.0;
199 // TODO: remove this nasty const_cast if you can figure out how
200 const_cast<MaterialProperty<Real> &>(*_int_var_stateful_prop_old[i])[_qp] = 0.0;
201 }
202
203 for (unsigned int i = 0; i < _num_int_var_rate_uos; ++i)
204 (*_int_var_rate_prop[i])[_qp] = 0.0;
205}
206
207void
209{
210 bool converge;
212 unsigned int num_substep = 1;
213 unsigned int substep_iter = 1;
214
215 saveOldState();
216
217 do
218 {
219 preSolveQp();
220
221 converge = true;
222 _dt_substep = _dt / num_substep;
223
224 for (unsigned int istep = 0; istep < num_substep; ++istep)
225 {
226 _dfgrd_tmp = (istep + 1.0) * delta_dfgrd / num_substep + _deformation_gradient_old[_qp];
227 if (!solveQp())
228 {
229 converge = false;
230 substep_iter++;
231 num_substep *= 2;
232 break;
233 }
234 }
235
236 if (substep_iter > _max_substep_iter)
237 mooseError("Constitutive failure with substepping at quadrature point ",
238 _q_point[_qp](0),
239 " ",
240 _q_point[_qp](1),
241 " ",
242 _q_point[_qp](2));
243 } while (!converge);
244
245 postSolveQp();
246}
247
248void
250{
251 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
253}
254
255void
257{
259
260 // TODO: remove this nasty const_cast if you can figure out how
261 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
262 (*_int_var_stateful_prop[i])[_qp] =
264
266}
267
268bool
270{
272 if (!solveFlowrate())
273 return false;
275
276 return true;
277}
278
279void
281{
283
284 _stress[_qp] = _fe * _pk2[_qp] * _fe.transpose() / _fe.det();
285 _fp[_qp] = _fp_tmp_inv.inverse();
286
288}
289
290void
292{
293 // TODO: remove this nasty const_cast if you can figure out how
294 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
296}
297
298void
300{
301 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
302 {
303 _flow_rate(i) = 0.0;
304 (*_flow_rate_prop[i])[_qp] = 0.0;
305 }
306
307 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
309
312}
313
314bool
316{
317 Real resid0, rnorm;
318 unsigned int iter = 0;
319
320#ifdef DEBUG
321 std::vector<Real> rnormst(_maxiters + 1), flowratest(_maxiters + 1);
322#endif
323
325 return false;
326
327 rnorm = computeNorm(_resid.get_values());
328 resid0 = rnorm;
329
330#ifdef DEBUG
331 rnormst[iter] = rnorm;
332 flowratest[iter] = computeNorm(_flow_rate.get_values());
333#endif
334
335 while (rnorm > _resid_abs_tol && rnorm > _resid_rel_tol * resid0 && iter < _maxiters)
336 {
338
340
342
344 return false;
345
346 rnorm = computeNorm(_resid.get_values());
347 iter++;
348
349#ifdef DEBUG
350 rnormst[iter] = rnorm;
351 flowratest[iter] = computeNorm(_flow_rate.get_values());
352#endif
353 }
354
355 if (iter == _maxiters && rnorm > _resid_abs_tol && rnorm > _resid_rel_tol * resid0)
356 return false;
357
358 return true;
359}
360
361void
363{
365
366 // TODO: remove this nasty const_cast if you can figure out how
367 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
368 const_cast<MaterialProperty<Real> &>(*_int_var_stateful_prop_old[i])[_qp] =
369 (*_int_var_stateful_prop[i])[_qp];
370}
371
372bool
374{
375 if (!computeIntVarRates())
376 return false;
377
378 if (!computeIntVar())
379 return false;
380
381 if (!computeStrength())
382 return false;
383
386
388 return false;
389
391 return false;
392
394
395 return true;
396}
397
398void
400{
404
405 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
406 for (unsigned int j = 0; j < _num_strength_uos; ++j)
407 _flow_rate_uo[i]->computeDerivative(_qp, _strength_uo_names[j], _dflowrate_dstrength(i, j));
408
409 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
410 _flow_rate_uo[i]->computeTensorDerivative(_qp, _pk2_prop_name, _dflowrate_dpk2[i]);
411
413
414 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
415 {
418 }
419
420 DenseMatrix<Real> dflowrate_dflowrate;
421 dflowrate_dflowrate = _dflowrate_dstrength;
422 dflowrate_dflowrate.right_multiply(_dstrength_dintvar);
423 dflowrate_dflowrate.right_multiply(_dintvar_dflowrate);
424
425 _jac.zero();
426 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
427 for (unsigned int j = 0; j < _num_flow_rate_uos; ++j)
428 {
429 if (i == j)
430 _jac(i, j) = 1;
431 _jac(i, j) -= dflowrate_dflowrate(i, j);
432 _jac(i, j) -= _dflowrate_dpk2[i].doubleContraction(_dpk2_dflowrate[j]);
433 }
434}
435
436bool
438{
439 for (unsigned i = 0; i < _num_flow_rate_uos; ++i)
440 {
441 if (!_flow_rate_uo[i]->computeDirection(_qp, _flow_dirn[i]))
442 return false;
443 }
444 return true;
445}
446
447bool
449{
450 Real val = 0;
451 for (unsigned i = 0; i < _num_flow_rate_uos; ++i)
452 {
453 if (_flow_rate_uo[i]->computeValue(_qp, val))
454 _resid(i) = -val;
455 else
456 return false;
457 }
458 return true;
459}
460
461void
463{
465 _pk2[_qp] = _elasticity_tensor[_qp] * _ee;
466
467 _dce_dfe.zero();
468 for (const auto i : make_range(Moose::dim))
469 for (const auto j : make_range(Moose::dim))
470 for (const auto k : make_range(Moose::dim))
471 {
472 _dce_dfe(i, j, k, i) = _dce_dfe(i, j, k, i) + _fe(k, j);
473 _dce_dfe(i, j, k, j) = _dce_dfe(i, j, k, j) + _fe(k, i);
474 }
475
477}
478
479void
485
486void
488{
489 _dee_dce.zero();
490
491 for (const auto i : make_range(Moose::dim))
492 for (const auto j : make_range(Moose::dim))
493 _dee_dce(i, j, i, j) = 0.5;
494}
495
496void
501
502void
504{
506
507 RankTwoTensor val;
508 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
509 val += _flow_rate(i) * _flow_dirn[i] * _dt_substep;
510
511 _fp_tmp_inv = _fp_tmp_old_inv * (iden - val);
512 _fp_tmp_inv = std::pow(_fp_tmp_inv.det(), -1.0 / 3.0) * _fp_tmp_inv;
514}
515
516void
518{
519 for (const auto i : make_range(Moose::dim))
520 for (const auto j : make_range(Moose::dim))
521 for (const auto k : make_range(Moose::dim))
522 _dfe_dfpinv(i, j, k, j) = _dfgrd_tmp(i, k);
523
525}
526
527Real
529{
530 Real val = 0.0;
531 for (unsigned int i = 0; i < var.size(); ++i)
532 val += Utility::pow<2>(var[i]);
533 return std::sqrt(val);
534}
535
536void
538{
541
542 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
543 (*_flow_rate_prop[i])[_qp] = _flow_rate(i);
544}
545
546void
548{
549 usingTensorIndices(i_, j_, k_, l_);
550 _tan_mod = _fe.times<i_, k_, j_, l_>(_fe) * _dpk2_dfe;
551 _pk2_fet = _pk2[_qp] * _fe.transpose();
552 _fe_pk2 = _fe * _pk2[_qp];
553
554 for (const auto i : make_range(Moose::dim))
555 for (const auto j : make_range(Moose::dim))
556 for (const auto l : make_range(Moose::dim))
557 {
558 _tan_mod(i, j, i, l) += _pk2_fet(l, j);
559 _tan_mod(i, j, j, l) += _fe_pk2(i, l);
560 }
561
562 _tan_mod /= _fe.det();
563
564 for (const auto i : make_range(Moose::dim))
565 for (const auto j : make_range(Moose::dim))
566 for (const auto l : make_range(Moose::dim))
567 _dfe_df(i, j, i, l) = _fp_tmp_inv(l, j);
568
569 for (const auto i : make_range(Moose::dim))
570 for (const auto j : make_range(Moose::dim))
571 for (const auto k : make_range(Moose::dim))
572 for (const auto l : make_range(Moose::dim))
573 _df_dstretch_inc(i, j, k, l) =
574 _rotation_increment[_qp](i, k) * _deformation_gradient_old[_qp](l, j);
575
577}
578
579bool
581{
582 Real val = 0;
583 for (unsigned int i = 0; i < _num_int_var_rate_uos; ++i)
584 {
585 if (_int_var_rate_uo[i]->computeValue(_qp, val))
586 (*_int_var_rate_prop[i])[_qp] = val;
587 else
588 return false;
589 }
590 return true;
591}
592
593bool
595{
596 Real val = 0;
597 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
598 {
599 if (_int_var_uo[i]->computeValue(_qp, _dt_substep, val))
600 (*_int_var_stateful_prop[i])[_qp] = val;
601 else
602 return false;
603 }
604 return true;
605}
606
607bool
609{
610 Real val = 0;
611 for (unsigned int i = 0; i < _num_strength_uos; ++i)
612 {
613 if (_strength_uo[i]->computeValue(_qp, val))
614 (*_strength_prop[i])[_qp] = val;
615 else
616 return false;
617 }
618 return true;
619}
620
621void
623{
624 Real val = 0;
625
626 for (unsigned int i = 0; i < _num_int_var_rate_uos; ++i)
627 for (unsigned int j = 0; j < _num_flow_rate_uos; ++j)
628 {
629 _int_var_rate_uo[i]->computeDerivative(_qp, _flow_rate_uo_names[j], val);
630 _dintvarrate_dflowrate[j](i) = val;
631 }
632}
633
634void
636{
637 Real val = 0;
638
639 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
640 for (unsigned int j = 0; j < _num_int_var_rate_uos; ++j)
641 {
642 _int_var_uo[i]->computeDerivative(_qp, _dt_substep, _int_var_rate_uo_names[j], val);
643 _dintvar_dintvarrate(i, j) = val;
644 }
645
647
648 for (unsigned int i = 0; i < _num_int_var_uos; ++i)
649 for (unsigned int j = 0; j < _num_int_var_uos; ++j)
650 {
651 if (i == j)
652 _dintvar_dintvar(i, j) = 1;
653 for (unsigned int k = 0; k < _num_int_var_rate_uos; ++k)
655 }
656
657 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
659
660 for (unsigned int i = 0; i < _num_flow_rate_uos; ++i)
661 {
662 _dintvar_dintvar_x.zero();
664 for (unsigned int j = 0; j < _num_int_var_uos; ++j)
666 }
667}
668
669void
671{
672 Real val = 0;
673
674 for (unsigned int i = 0; i < _num_strength_uos; ++i)
675 for (unsigned int j = 0; j < _num_int_var_uos; ++j)
676 {
677 _strength_uo[i]->computeDerivative(_qp, _int_var_uo_names[j], val);
678 _dstrength_dintvar(i, j) = val;
679 }
680}
registerMooseObject("SolidMechanicsApp", FiniteStrainHyperElasticViscoPlastic)
const double T
void mooseError(Args &&... args)
const std::string name
Definition Setup.h:21
void ErrorVector unsigned int
MaterialProperty< RankFourTensor > & _Jacobian_mult
derivative of stress w.r.t. strain (_dstress_dstrain)
MaterialProperty< RankTwoTensor > & _stress
Stress material property.
ComputeStressBase is the base class for stress tensors computed from MOOSE's strain calculators.
static InputParameters validParams()
This class solves the viscoplastic flow rate equations in the total form Involves 4 different types o...
void initNumUserObjects(const std::vector< UserObjectName > &, unsigned int &)
This function calculates the number of each user object type.
virtual void preSolveFlowrate()
Sets state for solve (Inside substepping)
std::vector< DenseVector< Real > > _dintvarrate_dflowrate
Jacobian variables.
virtual void computeElasticRightCauchyGreenTensor()
Computes elastic Right Cauchy Green Tensor.
FiniteStrainHyperElasticViscoPlastic(const InputParameters &parameters)
virtual void computeDeeDce()
Computes derivative of elastic strain w.r.t elastic Right Cauchy Green Tensor.
std::vector< MaterialProperty< Real > * > _flow_rate_prop
const MaterialProperty< RankFourTensor > & _elasticity_tensor
Elasticity tensor material property.
virtual bool computeIntVarRates()
This function call user objects to calculate rate of internal variables.
std::vector< MaterialProperty< Real > * > _strength_prop
std::vector< UserObjectName > _flow_rate_uo_names
Names of flow rate user objects.
std::vector< MaterialProperty< Real > * > _int_var_stateful_prop
virtual void computeElasticPlasticDeformGrad()
Computes elastic and plastic deformation gradients.
virtual bool computeFlowDirection()
Calls user objects to compute flow directions.
unsigned int _num_strength_uos
Number of strength user objects.
virtual void computeIntVarDerivatives()
This function call user objects to compute dintvar/dintvar_rate and dintvar/dflowrate.
virtual void initUOVariables()
This function initializes the properties, stateful properties and user objects The properties and sta...
virtual void computeElasticStrain()
Computes elastic Lagrangian strain.
unsigned int _num_int_var_uos
Number of internal variable user objects.
virtual bool computeStrength()
This function call user objects to compute strength.
std::vector< UserObjectName > _int_var_uo_names
Names of internal variable user objects.
virtual void recoverOldState()
This function restores the the old stateful properties after a successful solve.
virtual void initJacobianVariables()
This function initialize variables required for Jacobian calculation.
std::vector< const HEVPInternalVarUOBase * > _int_var_uo
Internal variable user objects.
unsigned int _num_int_var_rate_uos
Number of internal variable rate user objects.
std::vector< UserObjectName > _strength_uo_names
Names of strength user objects.
const MaterialProperty< RankTwoTensor > & _rotation_increment
virtual void computeDpk2Dfpinv()
Computes derivative of PK2 stress wrt inverse of plastic deformation gradient.
std::vector< MaterialProperty< Real > * > _int_var_rate_prop
const MaterialProperty< RankTwoTensor > & _fp_old
virtual bool computeFlowRateFunction()
Calls user objects to compute flow rates.
virtual bool computeIntVar()
This function call user objects to integrate internal variables.
virtual void computeIntVarRateDerivatives()
This function call user objects to compute dintvar_rate/dintvar and dintvarrate/dflowrate.
virtual bool computeFlowRateResidual()
Computes flow rate residual vector.
void initUserObjects(const std::vector< UserObjectName > &, unsigned int, std::vector< const T * > &)
This function initializes user objects.
virtual void computeQpJacobian()
This function computes the Jacobian.
const MaterialProperty< RankTwoTensor > & _deformation_gradient_old
virtual void computeFlowRateJacobian()
Computes flow rate Jacobian matrix.
unsigned int _num_flow_rate_uos
Number of flow rate user objects.
virtual void computeQpStress()
This function computes the Cauchy stress.
virtual void postSolveFlowrate()
Update state for output (Inside substepping)
virtual void computePK2StressAndDerivative()
Computes PK2 stress and derivative w.r.t elastic Right Cauchy Green Tensor.
std::vector< DenseVector< Real > > _dintvar_dflowrate_tmp
void initProp(const std::vector< UserObjectName > &, unsigned int, std::vector< MaterialProperty< T > * > &)
This function initializes properties for each user object.
Real _resid_rel_tol
Relative tolerance for residual convergence check.
std::vector< UserObjectName > _int_var_rate_uo_names
Names of internal variable rate user objects.
virtual void postSolveQp()
Update state for output (Outside substepping)
std::vector< const HEVPStrengthUOBase * > _strength_uo
Strength user objects.
std::vector< const MaterialProperty< Real > * > _int_var_stateful_prop_old
void computeStrengthDerivatives()
This function call user objects to compute dstrength/dintvar.
unsigned int _maxiters
Maximum number of iterations.
virtual void saveOldState()
This function saves the old stateful properties that is modified during sub stepping.
const MaterialProperty< RankTwoTensor > & _deformation_gradient
virtual bool solveFlowrate()
Solve for flow rate and state.
unsigned int _max_substep_iter
Maximum number of substep iterations.
std::vector< const HEVPFlowRateUOBase * > _flow_rate_uo
Flow rate user objects.
virtual Real computeNorm(const std::vector< Real > &)
Computes norm of residual vector.
std::vector< const HEVPInternalVarRateUOBase * > _int_var_rate_uo
Internal variable rate user objects.
void initPropOld(const std::vector< UserObjectName > &, unsigned int, std::vector< const MaterialProperty< T > * > &)
This function initializes old for stateful properties associated with user object Only user objects t...
Real _resid_abs_tol
Absolute tolerance for residual convergence check.
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)
RankFourTensorTempl< T > times(const RankTwoTensorTempl< T > &b) const
RankTwoTensorTempl< T > inverse() const
RankTwoTensorTempl< T > transpose() const
void vector_mult(DenseVector< T > &dest, const DenseVector< T > &arg) const
void resize(const unsigned int new_m, const unsigned int new_n)
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
virtual void right_multiply(const DenseMatrixBase< T > &M2) override final
virtual void zero() override final
static constexpr std::size_t dim