LCOV - code coverage report
Current view: top level - src/kernels - StressDivergenceRZTensors.C (source / functions) Hit Total Coverage
Test: idaholab/moose tensor_mechanics: d6b47a Lines: 147 151 97.4 %
Date: 2024-02-27 11:53:14 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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 "StressDivergenceRZTensors.h"
      11             : #include "Assembly.h"
      12             : #include "ElasticityTensorTools.h"
      13             : #include "libmesh/quadrature.h"
      14             : 
      15             : registerMooseObject("TensorMechanicsApp", StressDivergenceRZTensors);
      16             : 
      17             : InputParameters
      18         476 : StressDivergenceRZTensors::validParams()
      19             : {
      20         476 :   InputParameters params = StressDivergenceTensors::validParams();
      21         476 :   params.addClassDescription(
      22             :       "Calculate stress divergence for an axisymmetric problem in cylindrical coordinates.");
      23         952 :   params.addRequiredRangeCheckedParam<unsigned int>(
      24             :       "component",
      25             :       "component < 2",
      26             :       "An integer corresponding to the direction the variable this kernel acts in. (0 "
      27             :       "refers to the radial and 1 to the axial displacement.)");
      28         476 :   params.set<bool>("use_displaced_mesh") = true;
      29         476 :   return params;
      30           0 : }
      31             : 
      32         238 : StressDivergenceRZTensors::StressDivergenceRZTensors(const InputParameters & parameters)
      33         238 :   : StressDivergenceTensors(parameters)
      34             : {
      35         238 : }
      36             : 
      37             : void
      38         220 : StressDivergenceRZTensors::initialSetup()
      39             : {
      40             :   // check if any of the eigenstrains provide derivatives wrt variables that are not coupled
      41         494 :   for (auto eigenstrain_name : getParam<std::vector<MaterialPropertyName>>("eigenstrain_names"))
      42         162 :     validateNonlinearCoupling<RankTwoTensor>(eigenstrain_name);
      43             : 
      44         220 :   if (getBlockCoordSystem() != Moose::COORD_RZ)
      45           0 :     mooseError("The coordinate system in the Problem block must be set to RZ for axisymmetric "
      46             :                "geometries.");
      47             : 
      48         220 :   if (getBlockCoordSystem() == Moose::COORD_RZ && _fe_problem.getAxisymmetricRadialCoord() != 0)
      49           1 :     mooseError("rz_coord_axis=Y is the only supported option for StressDivergenceRZTensors");
      50         219 : }
      51             : 
      52             : Real
      53     6574524 : StressDivergenceRZTensors::computeQpResidual()
      54             : {
      55             :   Real div = 0.0;
      56     6574524 :   if (_component == 0)
      57             :   {
      58     3292446 :     div = _grad_test[_i][_qp](0) * _stress[_qp](0, 0) +
      59     3292446 :           +(_test[_i][_qp] / _q_point[_qp](0)) * _stress[_qp](2, 2) +
      60     3292446 :           +_grad_test[_i][_qp](1) * _stress[_qp](0, 1); // stress_{rz}
      61             : 
      62             :     // volumetric locking correction
      63     3292446 :     if (_volumetric_locking_correction)
      64      719168 :       div += (_avg_grad_test[_i][0] - _grad_test[_i][_qp](0) - _test[_i][_qp] / _q_point[_qp](0)) *
      65      359584 :              (_stress[_qp].trace()) / 3.0;
      66             :   }
      67     3282078 :   else if (_component == 1)
      68             :   {
      69     3282078 :     div = _grad_test[_i][_qp](1) * _stress[_qp](1, 1) +
      70     3282078 :           +_grad_test[_i][_qp](0) * _stress[_qp](1, 0); // stress_{zr}
      71             : 
      72             :     // volumetric locking correction
      73     3282078 :     if (_volumetric_locking_correction)
      74      359584 :       div += (_avg_grad_test[_i][1] - _grad_test[_i][_qp](1)) * (_stress[_qp].trace()) / 3.0;
      75             :   }
      76             :   else
      77           0 :     mooseError("Invalid component for this AxisymmetricRZ problem.");
      78             : 
      79     6574524 :   return div;
      80             : }
      81             : 
      82             : Real
      83     6433068 : StressDivergenceRZTensors::computeQpJacobian()
      84             : {
      85     6433068 :   return calculateJacobian(_component, _component);
      86             : }
      87             : 
      88             : Real
      89     1659296 : StressDivergenceRZTensors::computeQpOffDiagJacobian(unsigned int jvar)
      90             : {
      91     2542896 :   for (unsigned int i = 0; i < _ndisp; ++i)
      92     2506928 :     if (jvar == _disp_var[i])
      93     1623328 :       return calculateJacobian(_component, i);
      94             : 
      95             :   // bail out if jvar is not coupled
      96       35968 :   if (getJvarMap()[jvar] < 0)
      97             :     return 0.0;
      98             : 
      99             :   // off-diagonal Jacobian with respect to any other coupled variable
     100             :   const unsigned int cvar = mapJvarToCvar(jvar);
     101       23296 :   RankTwoTensor total_deigenstrain;
     102       46592 :   for (const auto deigenstrain_darg : _deigenstrain_dargs[cvar])
     103       23296 :     total_deigenstrain += (*deigenstrain_darg)[_qp];
     104             : 
     105             :   Real jac = 0.0;
     106       23296 :   if (_component == 0)
     107             :   {
     108       46592 :     for (unsigned k = 0; k < LIBMESH_DIM; ++k)
     109      139776 :       for (unsigned l = 0; l < LIBMESH_DIM; ++l)
     110      104832 :         jac -= (_grad_test[_i][_qp](0) * _Jacobian_mult[_qp](0, 0, k, l) +
     111      104832 :                 _test[_i][_qp] / _q_point[_qp](0) * _Jacobian_mult[_qp](2, 2, k, l) +
     112      104832 :                 _grad_test[_i][_qp](1) * _Jacobian_mult[_qp](0, 1, k, l)) *
     113      104832 :                total_deigenstrain(k, l);
     114       11648 :     return jac * _phi[_j][_qp];
     115             :   }
     116       11648 :   else if (_component == 1)
     117             :   {
     118       46592 :     for (unsigned k = 0; k < LIBMESH_DIM; ++k)
     119      139776 :       for (unsigned l = 0; l < LIBMESH_DIM; ++l)
     120      104832 :         jac -= (_grad_test[_i][_qp](1) * _Jacobian_mult[_qp](1, 1, k, l) +
     121      104832 :                 _grad_test[_i][_qp](0) * _Jacobian_mult[_qp](1, 0, k, l)) *
     122      104832 :                total_deigenstrain(k, l);
     123       11648 :     return jac * _phi[_j][_qp];
     124             :   }
     125             : 
     126             :   return 0.0;
     127             : }
     128             : 
     129             : Real
     130     8056396 : StressDivergenceRZTensors::calculateJacobian(unsigned int ivar, unsigned int jvar)
     131             : {
     132             :   // B^T_i * C * B_j
     133             :   RealGradient test, test_z, phi, phi_z;
     134             :   Real first_term = 0.0;
     135     8056396 :   if (ivar == 0) // Case grad_test for x, requires contributions from stress_xx, stress_xy, and
     136             :                  // stress_zz
     137             :   {
     138     4030470 :     test(0) = _grad_test[_i][_qp](0);
     139     4030470 :     test(1) = _grad_test[_i][_qp](1);
     140     4030470 :     test_z(2) = _test[_i][_qp] / _q_point[_qp](0);
     141             :   }
     142             :   else // Case grad_test for y
     143             :   {
     144     4025926 :     test(0) = _grad_test[_i][_qp](0);
     145     4025926 :     test(1) = _grad_test[_i][_qp](1);
     146             :   }
     147             : 
     148     8056396 :   if (jvar == 0)
     149             :   {
     150     4030470 :     phi(0) = _grad_phi[_j][_qp](0);
     151     4030470 :     phi(1) = _grad_phi[_j][_qp](1);
     152     4030470 :     phi_z(2) = _phi[_j][_qp] / _q_point[_qp](0);
     153             :   }
     154             :   else
     155             :   {
     156     4025926 :     phi(0) = _grad_phi[_j][_qp](0);
     157     4025926 :     phi(1) = _grad_phi[_j][_qp](1);
     158             :   }
     159             : 
     160     8056396 :   if (ivar == 0 &&
     161             :       jvar == 0) // Case when both phi and test are functions of x and z; requires four terms
     162             :   {
     163     3218806 :     const Real first_sum = ElasticityTensorTools::elasticJacobian(
     164     3218806 :         _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_x and phi_x
     165     3218806 :     const Real second_sum = ElasticityTensorTools::elasticJacobian(
     166     3218806 :         _Jacobian_mult[_qp], 2, 2, test_z, phi_z); // test_z and phi_z
     167     3218806 :     const Real mixed_sum1 = ElasticityTensorTools::elasticJacobian(
     168     3218806 :         _Jacobian_mult[_qp], ivar, 2, test, phi_z); // test_x and phi_z
     169     3218806 :     const Real mixed_sum2 = ElasticityTensorTools::elasticJacobian(
     170     3218806 :         _Jacobian_mult[_qp], 2, jvar, test_z, phi); // test_z and phi_x
     171             : 
     172     3218806 :     first_term = first_sum + second_sum + mixed_sum1 + mixed_sum2;
     173             :   }
     174     4837590 :   else if (ivar == 0 && jvar == 1)
     175             :   {
     176      811664 :     const Real first_sum = ElasticityTensorTools::elasticJacobian(
     177      811664 :         _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_x and phi_y
     178      811664 :     const Real mixed_sum2 = ElasticityTensorTools::elasticJacobian(
     179      811664 :         _Jacobian_mult[_qp], 2, jvar, test_z, phi); // test_z and phi_y
     180             : 
     181      811664 :     first_term = first_sum + mixed_sum2;
     182             :   }
     183     4025926 :   else if (ivar == 1 && jvar == 0)
     184             :   {
     185      811664 :     const Real second_sum = ElasticityTensorTools::elasticJacobian(
     186      811664 :         _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_y and phi_x
     187      811664 :     const Real mixed_sum1 = ElasticityTensorTools::elasticJacobian(
     188      811664 :         _Jacobian_mult[_qp], ivar, 2, test, phi_z); // test_y and phi_z
     189             : 
     190      811664 :     first_term = second_sum + mixed_sum1;
     191             :   }
     192     3214262 :   else if (ivar == 1 && jvar == 1)
     193     3214262 :     first_term = ElasticityTensorTools::elasticJacobian(
     194     3214262 :         _Jacobian_mult[_qp], ivar, jvar, test, phi); // test_y and phi_y
     195             :   else
     196           0 :     mooseError("Invalid component in Jacobian Calculation");
     197             : 
     198             :   Real val = 0.0;
     199             :   // volumetric locking correction
     200             :   // K = Bbar^T_i * C * Bbar^T_j where Bbar = B + Bvol
     201             :   // K = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j + B^T_i * C * Bvol_j + Bvol^T_i * C * B_j
     202     8056396 :   if (_volumetric_locking_correction)
     203             :   {
     204             :     RealGradient new_test(2, 0.0);
     205             :     RealGradient new_phi(2, 0.0);
     206             : 
     207     2545152 :     new_test(0) = _grad_test[_i][_qp](0) + _test[_i][_qp] / _q_point[_qp](0);
     208     2545152 :     new_test(1) = _grad_test[_i][_qp](1);
     209     2545152 :     new_phi(0) = _grad_phi[_j][_qp](0) + _phi[_j][_qp] / _q_point[_qp](0);
     210     2545152 :     new_phi(1) = _grad_phi[_j][_qp](1);
     211             : 
     212             :     // Bvol^T_i * C * Bvol_j
     213     2545152 :     val += _Jacobian_mult[_qp].sum3x3() * (_avg_grad_test[_i][ivar] - new_test(ivar)) *
     214     2545152 :            (_avg_grad_phi[_j][jvar] - new_phi(jvar)) / 3.0;
     215             : 
     216             :     // B^T_i * C * Bvol_j
     217     2545152 :     RealGradient sum_3x1 = _Jacobian_mult[_qp].sum3x1();
     218     2545152 :     if (ivar == 0 && jvar == 0)
     219      684672 :       val += (sum_3x1(0) * test(0) + sum_3x1(2) * test_z(2)) * (_avg_grad_phi[_j][0] - new_phi(0));
     220     1860480 :     else if (ivar == 0 && jvar == 1)
     221      587904 :       val += (sum_3x1(0) * test(0) + sum_3x1(2) * test_z(2)) * (_avg_grad_phi[_j][1] - new_phi(1));
     222     1272576 :     else if (ivar == 1 && jvar == 0)
     223      587904 :       val += sum_3x1(1) * test(1) * (_avg_grad_phi[_j][0] - new_phi(0));
     224             :     else
     225      684672 :       val += sum_3x1(1) * test(1) * (_avg_grad_phi[_j][1] - new_phi(1));
     226             : 
     227             :     // Bvol^T_i * C * B_j
     228             :     // val = trace (C * B_j) *(avg_grad_test[_i][ivar] - new_test(ivar))
     229     2545152 :     if (jvar == 0)
     230     5090304 :       for (unsigned int i = 0; i < 3; ++i)
     231     3817728 :         val +=
     232     3817728 :             (_Jacobian_mult[_qp](i, i, 0, 0) * phi(0) + _Jacobian_mult[_qp](i, i, 0, 1) * phi(1) +
     233     3817728 :              _Jacobian_mult[_qp](i, i, 2, 2) * phi_z(2)) *
     234     3817728 :             (_avg_grad_test[_i][ivar] - new_test(ivar));
     235     1272576 :     else if (jvar == 1)
     236     5090304 :       for (unsigned int i = 0; i < 3; ++i)
     237     3817728 :         val +=
     238     3817728 :             (_Jacobian_mult[_qp](i, i, 0, 1) * phi(0) + _Jacobian_mult[_qp](i, i, 1, 1) * phi(1)) *
     239     3817728 :             (_avg_grad_test[_i][ivar] - new_test(ivar));
     240             :   }
     241             : 
     242     8056396 :   return val / 3.0 + first_term;
     243             : }
     244             : 
     245             : void
     246      103088 : StressDivergenceRZTensors::computeAverageGradientTest()
     247             : {
     248             :   // calculate volume averaged value of shape function derivative
     249      103088 :   _avg_grad_test.resize(_test.size());
     250      515440 :   for (_i = 0; _i < _test.size(); ++_i)
     251             :   {
     252      412352 :     _avg_grad_test[_i].resize(2);
     253      412352 :     _avg_grad_test[_i][_component] = 0.0;
     254     2061760 :     for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     255             :     {
     256     1649408 :       if (_component == 0)
     257      824704 :         _avg_grad_test[_i][_component] +=
     258      824704 :             (_grad_test[_i][_qp](_component) + _test[_i][_qp] / _q_point[_qp](0)) * _JxW[_qp] *
     259      824704 :             _coord[_qp];
     260             :       else
     261      824704 :         _avg_grad_test[_i][_component] += _grad_test[_i][_qp](_component) * _JxW[_qp] * _coord[_qp];
     262             :     }
     263      412352 :     _avg_grad_test[_i][_component] /= _current_elem_volume;
     264             :   }
     265      103088 : }
     266             : 
     267             : void
     268       58140 : StressDivergenceRZTensors::computeAverageGradientPhi()
     269             : {
     270       58140 :   _avg_grad_phi.resize(_phi.size());
     271      290700 :   for (_i = 0; _i < _phi.size(); ++_i)
     272             :   {
     273      232560 :     _avg_grad_phi[_i].resize(2);
     274      697680 :     for (unsigned int component = 0; component < 2; ++component)
     275             :     {
     276      465120 :       _avg_grad_phi[_i][component] = 0.0;
     277     2325600 :       for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     278             :       {
     279     1860480 :         if (component == 0)
     280      930240 :           _avg_grad_phi[_i][component] +=
     281      930240 :               (_grad_phi[_i][_qp](component) + _phi[_i][_qp] / _q_point[_qp](0)) * _JxW[_qp] *
     282      930240 :               _coord[_qp];
     283             :         else
     284      930240 :           _avg_grad_phi[_i][component] += _grad_phi[_i][_qp](component) * _JxW[_qp] * _coord[_qp];
     285             :       }
     286      465120 :       _avg_grad_phi[_i][component] /= _current_elem_volume;
     287             :     }
     288             :   }
     289       58140 : }

Generated by: LCOV version 1.14