LCOV - code coverage report
Current view: top level - src/materials - ConcreteExpansionEigenstrainBase.C (source / functions) Hit Total Coverage
Test: idaholab/blackbear: 75f23c Lines: 102 103 99.0 %
Date: 2025-07-17 04:05:57 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /****************************************************************/
       2             : /*               DO NOT MODIFY THIS HEADER                      */
       3             : /*                       BlackBear                              */
       4             : /*                                                              */
       5             : /*           (c) 2017 Battelle Energy Alliance, LLC             */
       6             : /*                   ALL RIGHTS RESERVED                        */
       7             : /*                                                              */
       8             : /*          Prepared by Battelle Energy Alliance, LLC           */
       9             : /*            Under Contract No. DE-AC07-05ID14517              */
      10             : /*            With the U. S. Department of Energy               */
      11             : /*                                                              */
      12             : /*            See COPYRIGHT for full restrictions               */
      13             : /****************************************************************/
      14             : 
      15             : #include "ConcreteExpansionEigenstrainBase.h"
      16             : #include "RankTwoTensor.h"
      17             : 
      18             : InputParameters
      19        1996 : ConcreteExpansionEigenstrainBase::validParams()
      20             : {
      21        1996 :   InputParameters params = ComputeEigenstrainBase::validParams();
      22        3992 :   MooseEnum expansion_type("Isotropic Anisotropic");
      23        3992 :   params.addParam<MooseEnum>(
      24             :       "expansion_type", expansion_type, "Type of expansion resulting from volumetric strain");
      25        3992 :   params.addRangeCheckedParam<Real>(
      26             :       "compressive_strength", "compressive_strength > 0", "Compressive strength of concrete");
      27        3992 :   params.addRangeCheckedParam<Real>(
      28             :       "expansion_stress_limit",
      29             :       "expansion_stress_limit > 0",
      30             :       "Upper bound compressive stress beyond which no expansion occurs");
      31        3992 :   params.addRangeCheckedParam<Real>(
      32             :       "tensile_strength", "tensile_strength > 0", "Tensile strength of concrete");
      33        1996 :   return params;
      34        1996 : }
      35             : 
      36        1527 : ConcreteExpansionEigenstrainBase::ConcreteExpansionEigenstrainBase(
      37        1527 :     const InputParameters & parameters, const std::string volumetric_expansion_name)
      38             :   : ComputeEigenstrainBase(parameters),
      39        1527 :     _expansion_type(getParam<MooseEnum>("expansion_type").getEnum<ExpansionType>()),
      40        5238 :     _f_compress(isParamValid("compressive_strength") ? getParam<Real>("compressive_strength")
      41             :                                                      : 0.0),
      42        4986 :     _sigma_u(isParamValid("expansion_stress_limit") ? getParam<Real>("expansion_stress_limit")
      43             :                                                     : 0.0),
      44        5238 :     _f_tensile(isParamValid("tensile_strength") ? getParam<Real>("tensile_strength") : 0.0),
      45        1527 :     _eigenstrain_old(getMaterialPropertyOld<RankTwoTensor>(_eigenstrain_name)),
      46        1527 :     _volumetric_strain(declareProperty<Real>(volumetric_expansion_name + "_volumetric_strain")),
      47        1527 :     _volumetric_strain_old(
      48        1527 :         getMaterialPropertyOld<Real>(volumetric_expansion_name + "_volumetric_strain")),
      49        6108 :     _stress(getMaterialPropertyOld<RankTwoTensor>("stress"))
      50             : {
      51        1527 :   if (_expansion_type == ExpansionType::Anisotropic)
      52             :   {
      53        1854 :     if (!parameters.isParamSetByUser("compressive_strength"))
      54           3 :       paramError("compressive_strength",
      55             :                  "compressive_strength is required for expansion_type = Anisotropic");
      56        1848 :     if (!parameters.isParamSetByUser("expansion_stress_limit"))
      57           3 :       paramError("expansion_stress_limit",
      58             :                  "expansion_stress_limit is required for expansion_type = Anisotropic");
      59        1842 :     if (!parameters.isParamSetByUser("tensile_strength"))
      60           3 :       paramError("tensile_strength",
      61             :                  "tensile_strength is required for expansion_type = Anisotropic");
      62             :   }
      63             : 
      64             :   // Initialize triaxial weight table
      65             :   const Real third = 1.0 / 3.0;
      66        1518 :   _triaxial_weights = {{{{third, third, 0.0, 0.0}}, //  0 -> 13
      67             :                         {{third, third, 0.0, 0.0}}, //  1 -> 14
      68             :                         {{0.5, 0.5, 0.0, 0.0}},     //  2 -> 15
      69             :                         {{0.5, 0.5, 0.0, 0.0}},     //  3 -> 16
      70             :                         {{third, third, 0.0, 0.0}}, //  4 -> 12
      71             :                         {{third, third, 0.0, 0.0}}, //  5 ->  1
      72             :                         {{0.5, 0.5, 0.0, 0.0}},     //  6 ->  2
      73             :                         {{0.5, 0.5, 0.0, 0.0}},     //  7 ->  5
      74             :                         {{0.5, 0.5, 0.0, 0.0}},     //  8 -> 11
      75             :                         {{0.5, 0.5, 0.0, 0.0}},     //  9 ->  4
      76             :                         {{1.0, 1.0, third, 0.0}},   // 10 ->  3
      77             :                         {{1.0, 1.0, 0.5, 0.0}},     // 11 ->  6
      78             :                         {{0.5, 0.5, 0.0, 0.0}},     // 12 -> 10
      79             :                         {{0.5, 0.5, 0.0, 0.0}},     // 13 ->  9
      80             :                         {{1.0, 1.0, 0.5, 0.0}},     // 14 ->  8
      81             :                         {{1.0, 1.0, 1.0, third}}}}; // 15 ->  7
      82        1518 : }
      83             : 
      84             : void
      85       13136 : ConcreteExpansionEigenstrainBase::initQpStatefulProperties()
      86             : {
      87       13136 :   _volumetric_strain[_qp] = 0.0;
      88       13136 : }
      89             : 
      90             : void
      91      967034 : ConcreteExpansionEigenstrainBase::computeQpEigenstrain()
      92             : {
      93      967034 :   if (_expansion_type == ExpansionType::Anisotropic || needStressEigenvalues())
      94      816954 :     _stress[_qp].symmetricEigenvaluesEigenvectors(_stress_eigenvalues, _stress_eigenvectors);
      95             : 
      96      967034 :   _volumetric_strain[_qp] = computeQpVolumetricStrain();
      97             : 
      98      967032 :   if (_expansion_type == ExpansionType::Isotropic)
      99             :   {
     100      514502 :     const Real eigenstrain_comp = computeVolumetricStrainComponent(_volumetric_strain[_qp]);
     101      514502 :     _eigenstrain[_qp].zero();
     102      514502 :     _eigenstrain[_qp].addIa(eigenstrain_comp);
     103             :   }
     104      452530 :   else if (_expansion_type == ExpansionType::Anisotropic)
     105             :   {
     106      452530 :     const Real inc_volumetric_strain = _volumetric_strain[_qp] - _volumetric_strain_old[_qp];
     107             : 
     108      452530 :     RankTwoTensor inc_weighted_strain;
     109             : 
     110      452530 :     Real sig_l = _stress_eigenvalues[0];
     111      452530 :     Real sig_m = _stress_eigenvalues[1];
     112      452530 :     Real sig_k = _stress_eigenvalues[2];
     113             : 
     114             :     // Weights
     115             :     // W_k
     116      452530 :     Real W_3 = weight(sig_l, sig_m, sig_k);
     117             :     // W_m
     118      452530 :     Real W_2 = weight(sig_k, sig_l, sig_m);
     119             :     // W_l
     120      452530 :     Real W_1 = weight(sig_m, sig_k, sig_l);
     121             : 
     122      452530 :     inc_weighted_strain(0, 0) = inc_volumetric_strain * W_1;
     123      452530 :     inc_weighted_strain(1, 1) = inc_volumetric_strain * W_2;
     124      452530 :     inc_weighted_strain(2, 2) = inc_volumetric_strain * W_3;
     125             : 
     126             :     // Rotate from principal coordinate system to Cartesian coordinate system
     127      452530 :     inc_weighted_strain.rotate(_stress_eigenvectors);
     128             : 
     129      452530 :     _eigenstrain[_qp] = _eigenstrain_old[_qp] + inc_weighted_strain;
     130             :   }
     131             :   else
     132           0 :     mooseError("Invalid expansion type");
     133      967032 : }
     134             : 
     135             : Real
     136     1357590 : ConcreteExpansionEigenstrainBase::weight(Real sig_l, Real sig_m, Real sig_k)
     137             : {
     138             :   // Inputs
     139     1357590 :   const Real a1 = _f_tensile, a2 = -_sigma_u, a3 = -_f_compress + _sigma_u;
     140             :   const Real b1 = _f_tensile, b2 = -_sigma_u, b3 = -_f_compress + _sigma_u;
     141             : 
     142             :   // Lower and upper bound for l
     143     1357590 :   const unsigned int pbound_l = findNeighborIndex(sig_l);
     144             : 
     145             :   // Lower and upper bound for m
     146     1357590 :   const unsigned int pbound_m = findNeighborIndex(sig_m);
     147             : 
     148             :   // Neighboring nodes of k
     149     1357590 :   const unsigned int pbound_k = findNeighborIndex(sig_k);
     150             : 
     151             :   // Neighboring nodes of l, m, k
     152     1357590 :   const unsigned int N1 = (pbound_m)*4 + pbound_l;
     153     1357590 :   const unsigned int N2 = (pbound_m)*4 + (pbound_l + 1);
     154     1357590 :   const unsigned int N3 = (pbound_m + 1) * 4 + pbound_l;
     155     1357590 :   const unsigned int N4 = (pbound_m + 1) * 4 + (pbound_l + 1);
     156             : 
     157             :   const unsigned int N5 = pbound_k;
     158     1357590 :   const unsigned int N6 = pbound_k + 1;
     159             : 
     160             :   // Calculate a, b, sig_l, sig_m
     161     1357590 :   const Real a = computeAB(a1, a2, a3, pbound_l);
     162     1357590 :   const Real b = computeAB(b1, b2, b3, pbound_m);
     163     1357590 :   sig_l = computeSigma(sig_l, pbound_l);
     164     1357590 :   sig_m = computeSigma(sig_m, pbound_m);
     165             : 
     166             :   // Calculate weights
     167     1357590 :   return computeW(N1, N2, N3, N4, N5, N6, a, b, sig_l, sig_m, sig_k);
     168             : }
     169             : 
     170             : unsigned int
     171     4072770 : ConcreteExpansionEigenstrainBase::findNeighborIndex(Real sig)
     172             : {
     173     4072770 :   if (sig <= -_sigma_u)
     174             :     return 2;
     175     3345162 :   else if (sig > -_sigma_u && sig <= 0)
     176             :     return 1;
     177             :   else
     178      666057 :     return 0;
     179             : }
     180             : 
     181             : Real
     182     2715180 : ConcreteExpansionEigenstrainBase::computeAB(const Real ab1,
     183             :                                             const Real ab2,
     184             :                                             const Real ab3,
     185             :                                             const unsigned int pbound)
     186             : {
     187             :   mooseAssert("pbound <= 2", "pbound outside allowed range");
     188     2715180 :   if (pbound == 0)
     189             :     return ab1;
     190     2271142 :   else if (pbound == 1)
     191             :     return ab2;
     192             :   else
     193      485072 :     return ab3;
     194             : }
     195             : 
     196             : Real
     197     2715180 : ConcreteExpansionEigenstrainBase::computeSigma(const Real sig, const unsigned int pbound)
     198             : {
     199     2715180 :   if (pbound == 2)
     200             :   {
     201      485072 :     if (sig < -_f_compress) // stress conditions beyond _f_compress
     202       30240 :       return -_f_compress + _sigma_u;
     203             :     else
     204      454832 :       return sig + _sigma_u;
     205             :   }
     206             :   else
     207             :   {
     208     2230108 :     if (sig > _f_tensile)
     209             :       return _f_tensile; // stress conditions beyond _f_tensile
     210             :     else
     211     2081916 :       return sig;
     212             :   }
     213             : }
     214             : 
     215             : Real
     216     1357590 : ConcreteExpansionEigenstrainBase::computeW(const unsigned int N1,
     217             :                                            const unsigned int N2,
     218             :                                            const unsigned int N3,
     219             :                                            const unsigned int N4,
     220             :                                            const unsigned int N5,
     221             :                                            const unsigned int N6,
     222             :                                            const Real a,
     223             :                                            const Real b,
     224             :                                            const Real sig_l,
     225             :                                            const Real sig_m,
     226             :                                            Real sig_k)
     227             : {
     228     1357590 :   if (sig_k < -_f_compress)
     229             :     sig_k = -_f_compress;
     230     1342470 :   else if (sig_k > _f_tensile)
     231             :     sig_k = _f_tensile;
     232             : 
     233             :   // Calculate weights
     234             :   // N1
     235     1357590 :   const Real W1 = computeWi(N1, N5, N6, sig_k);
     236             :   // N2
     237     1357590 :   const Real W2 = computeWi(N2, N5, N6, sig_k);
     238             :   // N3
     239     1357590 :   const Real W3 = computeWi(N3, N5, N6, sig_k);
     240             :   // N4
     241     1357590 :   const Real W4 = computeWi(N4, N5, N6, sig_k);
     242             : 
     243             :   //   local node numebers
     244             :   //   3-----4
     245             :   //   |     |
     246             :   //   |     |
     247             :   //   1-----2
     248     1357590 :   const Real WN1 = (1.0 / (a * b)) * (a - sig_l) * (b - sig_m);
     249     1357590 :   const Real WN2 = (1.0 / (a * b)) * sig_l * (b - sig_m);
     250     1357590 :   const Real WN3 = (1.0 / (a * b)) * (a - sig_l) * sig_m;
     251     1357590 :   const Real WN4 = (1.0 / (a * b)) * sig_l * sig_m;
     252             : 
     253     1357590 :   return W1 * WN1 + W2 * WN2 + W3 * WN3 + W4 * WN4;
     254             : }
     255             : 
     256             : Real
     257     5430360 : ConcreteExpansionEigenstrainBase::computeWi(const unsigned int N,
     258             :                                             const unsigned int N5,
     259             :                                             const unsigned int N6,
     260             :                                             const Real sig_k)
     261             : {
     262     5430360 :   const Real farr[4] = {_f_tensile, 0, -_sigma_u, -_f_compress};
     263     5430360 :   const Real W_1 = _triaxial_weights[N][N5];
     264     5430360 :   const Real W_2 = _triaxial_weights[N][N6];
     265     5430360 :   return W_1 + (W_2 - W_1) * (sig_k - farr[N5]) / (farr[N6] - farr[N5]);
     266             : }

Generated by: LCOV version 1.14