Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://www.mooseframework.org 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "CZMComputeDisplacementJumpTotalLagrangian.h" 11 : #include "CohesiveZoneModelTools.h" 12 : #include "FactorizedRankTwoTensor.h" 13 : 14 : registerMooseObject("TensorMechanicsApp", CZMComputeDisplacementJumpTotalLagrangian); 15 : registerMooseObject("TensorMechanicsApp", ADCZMComputeDisplacementJumpTotalLagrangian); 16 : 17 : template <bool is_ad> 18 : InputParameters 19 66 : CZMComputeDisplacementJumpTotalLagrangianTempl<is_ad>::validParams() 20 : { 21 66 : InputParameters params = CZMComputeDisplacementJumpBase<is_ad>::validParams(); 22 66 : params.addClassDescription( 23 : "Compute the displacement jump increment across a czm interface in local " 24 : "coordinates for the Total Lagrangian kinematic formulation"); 25 : 26 66 : return params; 27 0 : } 28 : 29 : template <bool is_ad> 30 33 : CZMComputeDisplacementJumpTotalLagrangianTempl< 31 : is_ad>::CZMComputeDisplacementJumpTotalLagrangianTempl(const InputParameters & parameters) 32 : : CZMComputeDisplacementJumpBase<is_ad>(parameters), 33 33 : _F(this->template declareGenericPropertyByName<RankTwoTensor, is_ad>(_base_name + "F_czm")), 34 33 : _R(this->template declareGenericPropertyByName<RankTwoTensor, is_ad>(_base_name + 35 : "czm_rotation")), 36 33 : _czm_reference_rotation(this->template declareGenericPropertyByName<RankTwoTensor, is_ad>( 37 33 : _base_name + "czm_reference_rotation")) 38 : { 39 : // initializing the displacement gradient vectors 40 123 : for (unsigned int i = 0; i < _ndisp; ++i) 41 : { 42 90 : _grad_disp.push_back(&this->template coupledGenericGradient<is_ad>("displacements", i)); 43 : _grad_disp_neighbor.push_back( 44 270 : &this->template coupledGenericNeighborGradient<is_ad>("displacements", i)); 45 : } 46 : 47 : // All others zero (so this will work naturally for 2D and 1D problems) 48 42 : for (unsigned int i = _ndisp; i < 3; i++) 49 : { 50 : if constexpr (is_ad) 51 : { 52 0 : _grad_disp.push_back(&_ad_grad_zero); 53 0 : _grad_disp_neighbor.push_back(&_ad_grad_zero); 54 : } 55 : else 56 : { 57 9 : _grad_disp.push_back(&_grad_zero); 58 9 : _grad_disp_neighbor.push_back(&_grad_zero); 59 : } 60 : } 61 33 : } 62 : 63 : template <bool is_ad> 64 : void 65 1232 : CZMComputeDisplacementJumpTotalLagrangianTempl<is_ad>::initQpStatefulProperties() 66 : { 67 1232 : CZMComputeDisplacementJumpBase<is_ad>::initQpStatefulProperties(); 68 1232 : _displacement_jump_global[_qp] = 0; 69 1232 : _F[_qp].setToIdentity(); 70 1232 : _R[_qp].setToIdentity(); 71 1232 : } 72 : 73 : template <bool is_ad> 74 : void 75 22066 : CZMComputeDisplacementJumpTotalLagrangianTempl<is_ad>::computeLocalDisplacementJump() 76 : { 77 26386 : _interface_displacement_jump[_qp] = 78 22066 : _czm_total_rotation[_qp].transpose() * _displacement_jump_global[_qp]; 79 22066 : } 80 : 81 : template <bool is_ad> 82 : void 83 22066 : CZMComputeDisplacementJumpTotalLagrangianTempl<is_ad>::computeRotationMatrices() 84 : { 85 22066 : _czm_reference_rotation[_qp] = CohesiveZoneModelTools::computeReferenceRotation<is_ad>( 86 22066 : _normals[_qp], this->_mesh.dimension()); 87 22066 : computeFandR(); 88 22066 : _czm_total_rotation[_qp] = _R[_qp] * _czm_reference_rotation[_qp]; 89 22066 : } 90 : 91 : template <bool is_ad> 92 : void 93 22066 : CZMComputeDisplacementJumpTotalLagrangianTempl<is_ad>::computeFandR() 94 : { 95 44132 : const auto F = (GenericRankTwoTensor<is_ad>::Identity() + 96 : GenericRankTwoTensor<is_ad>::initializeFromRows( 97 22066 : (*_grad_disp[0])[_qp], (*_grad_disp[1])[_qp], (*_grad_disp[2])[_qp])); 98 22066 : const auto F_neighbor = 99 : (GenericRankTwoTensor<is_ad>::Identity() + 100 22066 : GenericRankTwoTensor<is_ad>::initializeFromRows((*_grad_disp_neighbor[0])[_qp], 101 22066 : (*_grad_disp_neighbor[1])[_qp], 102 22066 : (*_grad_disp_neighbor[2])[_qp])); 103 : 104 26386 : _F[_qp] = 0.5 * (F + F_neighbor); 105 : // According to Cody mooseError are always fatal, so nothing we can do about 106 : // them. The norm of the tensor might work, but there is the risk of an 107 : // unwanted overflow (I tried and it happens). So checking component by 108 : // component remains the only reasonable strategy. If someone finds a better 109 : // way this could be changed in the future 110 88264 : for (unsigned int i = 0; i < 3; i++) 111 264792 : for (unsigned int j = 0; j < 3; j++) 112 198594 : if (!std::isfinite(MetaPhysicL::raw_value(_F[_qp](i, j)))) 113 0 : throw MooseException("CZMMaterialBaseIncremental _F is not finite, reducing time step"); 114 : 115 : using FR2T = std::conditional_t<is_ad, ADFactorizedRankTwoTensor, FactorizedRankTwoTensor>; 116 22066 : const FR2T C = _F[_qp].transpose() * _F[_qp]; 117 22066 : const auto Uinv = MathUtils::sqrt(C).inverse().get(); 118 22066 : _R[_qp] = _F[_qp] * Uinv; 119 22066 : } 120 : 121 : template class CZMComputeDisplacementJumpTotalLagrangianTempl<false>; 122 : template class CZMComputeDisplacementJumpTotalLagrangianTempl<true>;