Ejemplo n.º 1
0
Real
secondInvariant(const SymmTensor & symm_tensor)
{
    Real value = symm_tensor.xx() * symm_tensor.yy() +
                 symm_tensor.yy() * symm_tensor.zz() +
                 symm_tensor.zz() * symm_tensor.xx() -
                 symm_tensor.xy() * symm_tensor.xy() -
                 symm_tensor.yz() * symm_tensor.yz() -
                 symm_tensor.zx() * symm_tensor.zx();

    return value;
}
Ejemplo n.º 2
0
Real
StressDivergenceRZ::computeQpOffDiagJacobian(unsigned int jvar)
{

  if ( _rdisp_coupled && jvar == _rdisp_var )
  {
    return calculateJacobian( _component, 0 );
  }
  else if ( _zdisp_coupled && jvar == _zdisp_var )
  {
    return calculateJacobian( _component, 1 );
  }
  else if ( _temp_coupled && jvar == _temp_var )
  {
    SymmTensor test;
    if (_component == 0)
    {
      test.xx() = _grad_test[_i][_qp](0);
      test.xy() = 0.5*_grad_test[_i][_qp](1);
      test.zz() = _test[_i][_qp] / _q_point[_qp](0);
    }
    else
    {
      test.xy() = 0.5*_grad_test[_i][_qp](0);
      test.yy() = _grad_test[_i][_qp](1);
    }
    return _d_stress_dT[_qp].doubleContraction(test) * _phi[_j][_qp];
  }

  return 0;
}
Ejemplo n.º 3
0
void
Nonlinear::computeStrainIncrement( const ColumnMajorMatrix & Fhat,
                                   SymmTensor & strain_increment )
{

  //
  // A calculation of the strain at the mid-interval is probably more
  // accurate (second vs. first order).  This would require the
  // incremental deformation gradient at the mid-step, which we
  // currently don't have.  We would then have to calculate the
  // rotation for the whole step.
  //
  //
  // We are looking for:
  //     log( Uhat )
  //  =  log( sqrt( Fhat^T*Fhat ) )
  //  =  log( sqrt( Chat ) )
  // A Taylor series expansion gives:
  //     ( Chat - 0.25 * Chat^T*Chat - 0.75 * I )
  //  =  ( - 0.25 * Chat^T*Chat + Chat - 0.75 * I )
  //  =  ( (0.25*Chat - 0.75*I) * (Chat - I) )
  //  =  ( B * A )
  //    B
  //  = 0.25*Chat - 0.75*I
  //  = 0.25*(Chat - I) - 0.5*I
  //  = 0.25*A - 0.5*I
  //

  const Real Uxx = Fhat(0,0);
  const Real Uxy = Fhat(0,1);
  const Real Uxz = Fhat(0,2);
  const Real Uyx = Fhat(1,0);
  const Real Uyy = Fhat(1,1);
  const Real Uyz = Fhat(1,2);
  const Real Uzx = Fhat(2,0);
  const Real Uzy = Fhat(2,1);
  const Real Uzz = Fhat(2,2);

  const Real Axx = Uxx*Uxx + Uyx*Uyx + Uzx*Uzx - 1.0;
  const Real Axy = Uxx*Uxy + Uyx*Uyy + Uzx*Uzy;
  const Real Axz = Uxx*Uxz + Uyx*Uyz + Uzx*Uzz;
  const Real Ayy = Uxy*Uxy + Uyy*Uyy + Uzy*Uzy - 1.0;
  const Real Ayz = Uxy*Uxz + Uyy*Uyz + Uzy*Uzz;
  const Real Azz = Uxz*Uxz + Uyz*Uyz + Uzz*Uzz - 1.0;

  const Real Bxx = 0.25 * Axx - 0.5;
  const Real Bxy = 0.25 * Axy;
  const Real Bxz = 0.25 * Axz;
  const Real Byy = 0.25 * Ayy - 0.5;
  const Real Byz = 0.25 * Ayz;
  const Real Bzz = 0.25 * Azz - 0.5;

  strain_increment.xx( -(Bxx*Axx + Bxy*Axy + Bxz*Axz) );
  strain_increment.xy( -(Bxx*Axy + Bxy*Ayy + Bxz*Ayz) );
  strain_increment.zx( -(Bxx*Axz + Bxy*Ayz + Bxz*Azz) );
  strain_increment.yy( -(Bxy*Axy + Byy*Ayy + Byz*Ayz) );
  strain_increment.yz( -(Bxy*Axz + Byy*Ayz + Byz*Azz) );
  strain_increment.zz( -(Bxz*Axz + Byz*Ayz + Bzz*Azz) );

}
Ejemplo n.º 4
0
void
SymmIsotropicElasticityTensor::multiply( const SymmTensor & x, SymmTensor & b ) const
{
  const Real xx = x.xx();
  const Real yy = x.yy();
  const Real zz = x.zz();
  const Real xy = x.xy();
  const Real yz = x.yz();
  const Real zx = x.zx();

  b.xx() = _val[ 0]*xx + _val[ 1]*yy + _val[ 2]*zz;
  b.yy() = _val[ 1]*xx + _val[ 6]*yy + _val[ 7]*zz;
  b.zz() = _val[ 2]*xx + _val[ 7]*yy + _val[11]*zz;
  b.xy() = 2*_val[15]*xy;
  b.yz() = 2*_val[18]*yz;
  b.zx() = 2*_val[20]*zx;
}
Ejemplo n.º 5
0
Real
StressDivergence::computeQpJacobian()
{
  Real sum_C3x3 = _Jacobian_mult[_qp].sum_3x3();
  RealGradient sum_C3x1 = _Jacobian_mult[_qp].sum_3x1();

  Real jacobian = 0.0;
  // B^T_i * C * B_j
  jacobian += _Jacobian_mult[_qp].stiffness(
      _component, _component, _grad_test[_i][_qp], _grad_phi[_j][_qp]); // B^T_i * C *B_j

  if (_volumetric_locking_correction)
  {
    // jacobian = Bbar^T_i * C * Bbar_j where Bbar = B + Bvol
    // jacobian = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j +  Bvol^T_i * C * B_j + B^T_i * C * Bvol_j

    // Bvol^T_i * C * Bvol_j
    jacobian += sum_C3x3 * (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) *
                (_avg_grad_phi[_j][_component] - _grad_phi[_j][_qp](_component)) / 9.0;

    // B^T_i * C * Bvol_j
    jacobian += sum_C3x1(_component) * _grad_test[_i][_qp](_component) *
                (_avg_grad_phi[_j][_component] - _grad_phi[_j][_qp](_component)) / 3.0;

    // Bvol^T_i * C * B_j
    SymmTensor phi;
    if (_component == 0)
    {
      phi.xx() = _grad_phi[_j][_qp](0);
      phi.xy() = _grad_phi[_j][_qp](1);
      phi.xz() = _grad_phi[_j][_qp](2);
    }
    else if (_component == 1)
    {
      phi.yy() = _grad_phi[_j][_qp](1);
      phi.xy() = _grad_phi[_j][_qp](0);
      phi.yz() = _grad_phi[_j][_qp](2);
    }
    else if (_component == 2)
    {
      phi.zz() = _grad_phi[_j][_qp](2);
      phi.xz() = _grad_phi[_j][_qp](0);
      phi.yz() = _grad_phi[_j][_qp](1);
    }

    SymmTensor tmp(_Jacobian_mult[_qp] * phi);

    jacobian += (tmp.xx() + tmp.yy() + tmp.zz()) *
                (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) / 3.0;
  }

  if (_dt > 0)
    return jacobian * (1 + _alpha + _zeta / _dt);
  else
    return jacobian;
}
Ejemplo n.º 6
0
void
SphericalR::computeStrain(const unsigned qp,
                          const SymmTensor & total_strain_old,
                          SymmTensor & total_strain_new,
                          SymmTensor & strain_increment)
{
  strain_increment.xx() = _grad_disp_r[qp](0);
  strain_increment.yy() =
      (_solid_model.q_point(qp)(0) != 0.0 ? _disp_r[qp] / _solid_model.q_point(qp)(0) : 0.0);
  strain_increment.zz() = strain_increment.yy();
  if (_large_strain)
  {
    strain_increment.xx() += 0.5 * (_grad_disp_r[qp](0) * _grad_disp_r[qp](0));
    strain_increment.yy() += 0.5 * (strain_increment.yy() * strain_increment.yy());
    strain_increment.zz() += 0.5 * (strain_increment.zz() * strain_increment.zz());
  }

  total_strain_new = strain_increment;

  strain_increment -= total_strain_old;
}
Ejemplo n.º 7
0
Real
thirdInvariant(const SymmTensor & symm_tensor)
{
    Real val = 0.0;
    val = symm_tensor.xx() * symm_tensor.yy() * symm_tensor.zz() -
          symm_tensor.xx() * symm_tensor.yz() * symm_tensor.yz() +
          symm_tensor.xy() * symm_tensor.yz() * symm_tensor.zx() -
          symm_tensor.xy() * symm_tensor.xy() * symm_tensor.zz() +
          symm_tensor.zx() * symm_tensor.xy() * symm_tensor.yz() -
          symm_tensor.zx() * symm_tensor.yy() * symm_tensor.zx();

    return val;
}
Ejemplo n.º 8
0
void
SymmElasticityTensor::multiply(const SymmTensor & x, SymmTensor & b) const
{
  const Real xx = x.xx();
  const Real yy = x.yy();
  const Real zz = x.zz();
  const Real xy = x.xy();
  const Real yz = x.yz();
  const Real zx = x.zx();

  b.xx() =
      _val[0] * xx + _val[1] * yy + _val[2] * zz + 2 * (_val[3] * xy + _val[4] * yz + _val[5] * zx);
  b.yy() = _val[1] * xx + _val[6] * yy + _val[7] * zz +
           2 * (_val[8] * xy + _val[9] * yz + _val[10] * zx);
  b.zz() = _val[2] * xx + _val[7] * yy + _val[11] * zz +
           2 * (_val[12] * xy + _val[13] * yz + _val[14] * zx);
  b.xy() = _val[3] * xx + _val[8] * yy + _val[12] * zz +
           2 * (_val[15] * xy + _val[16] * yz + _val[17] * zx);
  b.yz() = _val[4] * xx + _val[9] * yy + _val[13] * zz +
           2 * (_val[16] * xy + _val[18] * yz + _val[19] * zx);
  b.zx() = _val[5] * xx + _val[10] * yy + _val[14] * zz +
           2 * (_val[17] * xy + _val[19] * yz + _val[20] * zx);
}
Ejemplo n.º 9
0
Real
StressDivergenceRSpherical::computeQpOffDiagJacobian(unsigned int jvar)
{

  if ( _temp_coupled && jvar == _temp_var )
  {
    SymmTensor test;
    test.xx() = _grad_test[_i][_qp](0);
    test.yy() = _test[_i][_qp] / _q_point[_qp](0);
    test.zz() = test.yy();
    return _d_stress_dT[_qp].doubleContraction(test) * _phi[_j][_qp];
  }

  return 0;
}
Ejemplo n.º 10
0
ColumnMajorMatrix
CrackFrontDefinition::rotateToCrackFrontCoords(const SymmTensor tensor, const unsigned int node_index) const
{
  ColumnMajorMatrix tensor_CMM;
  tensor_CMM(0,0) = tensor.xx();
  tensor_CMM(0,1) = tensor.xy();
  tensor_CMM(0,2) = tensor.xz();
  tensor_CMM(1,0) = tensor.xy();
  tensor_CMM(1,1) = tensor.yy();
  tensor_CMM(1,2) = tensor.yz();
  tensor_CMM(2,0) = tensor.xz();
  tensor_CMM(2,1) = tensor.yz();
  tensor_CMM(2,2) = tensor.zz();

  ColumnMajorMatrix tmp = _rot_matrix[node_index] * tensor_CMM;
  ColumnMajorMatrix rotT = _rot_matrix[node_index].transpose();
  ColumnMajorMatrix rotated_tensor = tmp * rotT;

  return rotated_tensor;
}
Ejemplo n.º 11
0
void
Linear::computeStrain( const unsigned qp,
                       const SymmTensor & total_strain_old,
                       SymmTensor & total_strain_new,
                       SymmTensor & strain_increment )
{
  strain_increment.xx( _grad_disp_x[qp](0) );
  strain_increment.yy( _grad_disp_y[qp](1) );
  strain_increment.zz( _grad_disp_z[qp](2) );
  strain_increment.xy( 0.5*(_grad_disp_x[qp](1)+_grad_disp_y[qp](0)) );
  strain_increment.yz( 0.5*(_grad_disp_y[qp](2)+_grad_disp_z[qp](1)) );
  strain_increment.zx( 0.5*(_grad_disp_z[qp](0)+_grad_disp_x[qp](2)) );
  if (_large_strain)
  {
    strain_increment.xx() += 0.5*(_grad_disp_x[qp](0)*_grad_disp_x[qp](0) +
                                  _grad_disp_y[qp](0)*_grad_disp_y[qp](0) +
                                  _grad_disp_z[qp](0)*_grad_disp_z[qp](0));
    strain_increment.yy() += 0.5*(_grad_disp_x[qp](1)*_grad_disp_x[qp](1) +
                                  _grad_disp_y[qp](1)*_grad_disp_y[qp](1) +
                                  _grad_disp_z[qp](1)*_grad_disp_z[qp](1));
    strain_increment.zz() += 0.5*(_grad_disp_x[qp](2)*_grad_disp_x[qp](2) +
                                  _grad_disp_y[qp](2)*_grad_disp_y[qp](2) +
                                  _grad_disp_z[qp](2)*_grad_disp_z[qp](2));
    strain_increment.xy() += 0.5*(_grad_disp_x[qp](0)*_grad_disp_x[qp](1) +
                                  _grad_disp_y[qp](0)*_grad_disp_y[qp](1) +
                                  _grad_disp_z[qp](0)*_grad_disp_z[qp](1));
    strain_increment.yz() += 0.5*(_grad_disp_x[qp](1)*_grad_disp_x[qp](2) +
                                  _grad_disp_y[qp](1)*_grad_disp_y[qp](2) +
                                  _grad_disp_z[qp](1)*_grad_disp_z[qp](2));
    strain_increment.zx() += 0.5*(_grad_disp_x[qp](2)*_grad_disp_x[qp](0) +
                                  _grad_disp_y[qp](2)*_grad_disp_y[qp](0) +
                                  _grad_disp_z[qp](2)*_grad_disp_z[qp](0));
  }

  if (_volumetric_locking_correction)
  {
    // volumetric locking correction - averaging the volumertic strain over the element
    Real volumetric_strain = 0.0;
    Real volume = 0.0;
    for (unsigned int qp_loop = 0; qp_loop < _solid_model.qrule()->n_points(); ++qp_loop)
    {
      volumetric_strain += (_grad_disp_x[qp_loop](0) + _grad_disp_y[qp_loop](1) + _grad_disp_z[qp_loop](2)) / 3.0 * _solid_model.JxW(qp_loop);

      volume += _solid_model.JxW(qp_loop);

      if (_large_strain)
      {
        volumetric_strain += 0.5 * (_grad_disp_x[qp](0) * _grad_disp_x[qp](0) +
                                    _grad_disp_y[qp](0) * _grad_disp_y[qp](0) +
                                    _grad_disp_z[qp](0) * _grad_disp_z[qp](0)) / 3.0 * _solid_model.JxW(qp_loop);
        volumetric_strain += 0.5 * (_grad_disp_x[qp](1) * _grad_disp_x[qp](1) +
                                    _grad_disp_y[qp](1) * _grad_disp_y[qp](1) +
                                    _grad_disp_z[qp](1) * _grad_disp_z[qp](1)) / 3.0 * _solid_model.JxW(qp_loop);
        volumetric_strain += 0.5 * (_grad_disp_x[qp](2) * _grad_disp_x[qp](2) +
                                    _grad_disp_y[qp](2) * _grad_disp_y[qp](2) +
                                    _grad_disp_z[qp](2) * _grad_disp_z[qp](2)) / 3.0 * _solid_model.JxW(qp_loop);
      }
    }

    volumetric_strain /= volume; // average volumetric strain

    // strain increment at _qp
    Real trace = strain_increment.trace();
    strain_increment.xx() += volumetric_strain - trace / 3.0;
    strain_increment.yy() += volumetric_strain - trace / 3.0;
    strain_increment.zz() += volumetric_strain - trace / 3.0;
  }

  total_strain_new = strain_increment;
  strain_increment -= total_strain_old;
}
Ejemplo n.º 12
0
Real
StressDivergence::computeQpOffDiagJacobian(unsigned int jvar)
{
  unsigned int coupled_component = 0;

  bool active = false;

  if (_xdisp_coupled && jvar == _xdisp_var)
  {
    coupled_component = 0;
    active = true;
  }
  else if (_ydisp_coupled && jvar == _ydisp_var)
  {
    coupled_component = 1;
    active = true;
  }
  else if (_zdisp_coupled && jvar == _zdisp_var)
  {
    coupled_component = 2;
    active = true;
  }

  if (active)
  {
    Real sum_C3x3 = _Jacobian_mult[_qp].sum_3x3();
    RealGradient sum_C3x1 = _Jacobian_mult[_qp].sum_3x1();
    Real jacobian = 0.0;
    jacobian += _Jacobian_mult[_qp].stiffness(
        _component, coupled_component, _grad_test[_i][_qp], _grad_phi[_j][_qp]); // B^T_i * C *B_j

    if (_volumetric_locking_correction)
    {
      // jacobian = Bbar^T_i * C * Bbar_j where Bbar = B + Bvol
      // jacobian = B^T_i * C * B_j + Bvol^T_i * C * Bvol_j +  Bvol^T_i * C * B_j + B^T_i * C *
      // Bvol_j

      // Bvol^T_i * C * Bvol_j
      jacobian += sum_C3x3 * (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) *
                  (_avg_grad_phi[_j][coupled_component] - _grad_phi[_j][_qp](coupled_component)) /
                  9.0;

      // B^T_i * C * Bvol_j
      jacobian += sum_C3x1(_component) * _grad_test[_i][_qp](_component) *
                  (_avg_grad_phi[_j][coupled_component] - _grad_phi[_j][_qp](coupled_component)) /
                  3.0;

      // Bvol^T_i * C * B_i
      SymmTensor phi;
      if (coupled_component == 0)
      {
        phi.xx() = _grad_phi[_j][_qp](0);
        phi.xy() = _grad_phi[_j][_qp](1);
        phi.xz() = _grad_phi[_j][_qp](2);
      }
      else if (coupled_component == 1)
      {
        phi.yy() = _grad_phi[_j][_qp](1);
        phi.xy() = _grad_phi[_j][_qp](0);
        phi.yz() = _grad_phi[_j][_qp](2);
      }
      else if (coupled_component == 2)
      {
        phi.zz() = _grad_phi[_j][_qp](2);
        phi.xz() = _grad_phi[_j][_qp](0);
        phi.yz() = _grad_phi[_j][_qp](1);
      }

      SymmTensor tmp(_Jacobian_mult[_qp] * phi);

      jacobian += (tmp.xx() + tmp.yy() + tmp.zz()) *
                  (_avg_grad_test[_i][_component] - _grad_test[_i][_qp](_component)) / 3.0;
    }

    if (_dt > 0)
      return jacobian * (1 + _alpha + _zeta / _dt);
    else
      return jacobian;
  }

  if (_temp_coupled && jvar == _temp_var)
    return _d_stress_dT[_qp].rowDot(_component, _grad_test[_i][_qp]) * _phi[_j][_qp];

  return 0;
}
Ejemplo n.º 13
0
void
PlaneStrain::computeStrain( const unsigned qp,
                               const SymmTensor & total_strain_old,
                               SymmTensor & total_strain_new,
                               SymmTensor & strain_increment )
{
  strain_increment.xx() = _grad_disp_x[qp](0);
  strain_increment.yy() = _grad_disp_y[qp](1);

  if (_have_strain_zz)
    strain_increment.zz() = _strain_zz[qp];
  else if (_have_scalar_strain_zz && _scalar_strain_zz.size()>0)
    strain_increment.zz() = _scalar_strain_zz[0];
  else
    strain_increment.zz() = 0;

  strain_increment.xy() = 0.5*(_grad_disp_x[qp](1) + _grad_disp_y[qp](0));
  strain_increment.yz() = 0;
  strain_increment.zx() = 0;
  if (_large_strain)
  {
    strain_increment.xx() += 0.5*(_grad_disp_x[qp](0)*_grad_disp_x[qp](0) +
                                  _grad_disp_y[qp](0)*_grad_disp_y[qp](0));
    strain_increment.yy() += 0.5*(_grad_disp_x[qp](1)*_grad_disp_x[qp](1) +
                                  _grad_disp_y[qp](1)*_grad_disp_y[qp](1));
    strain_increment.xy() += 0.5*(_grad_disp_x[qp](0)*_grad_disp_x[qp](1) +
                                  _grad_disp_y[qp](0)*_grad_disp_y[qp](1));
  }

  if (_volumetric_locking_correction)
  {
    // volumetric locking correction
    Real volumetric_strain = 0.0;
    Real volume = 0.0;
    Real dim = 3.0;
    for (unsigned int qp_loop = 0; qp_loop < _solid_model.qrule()->n_points(); ++qp_loop)
    {
      if (_have_strain_zz)
        volumetric_strain += (_grad_disp_x[qp_loop](0) + _grad_disp_y[qp_loop](1) + _strain_zz[qp_loop]) / dim * _solid_model.JxW(qp_loop);
      else if (_have_scalar_strain_zz && _scalar_strain_zz.size() > 0)
        volumetric_strain += (_grad_disp_x[qp_loop](0) + _grad_disp_y[qp_loop](1) + _scalar_strain_zz[0]) / dim * _solid_model.JxW(qp_loop);
      else
        volumetric_strain += (_grad_disp_x[qp_loop](0) + _grad_disp_y[qp_loop](1)) / dim * _solid_model.JxW(qp_loop);

      volume += _solid_model.JxW(qp_loop);

      if (_large_strain)
      {
        volumetric_strain += 0.5 * (_grad_disp_x[qp_loop](0) * _grad_disp_x[qp_loop](0) +
                                    _grad_disp_y[qp_loop](0) * _grad_disp_y[qp_loop](0)) / dim * _solid_model.JxW(qp_loop);
        volumetric_strain += 0.5 * (_grad_disp_x[qp_loop](1) * _grad_disp_x[qp_loop](1) +
                                    _grad_disp_y[qp_loop](1) * _grad_disp_y[qp_loop](1)) / dim * _solid_model.JxW(qp_loop);
      }
    }

    volumetric_strain /= volume; // average volumetric strain

    // strain increment at _qp
    Real trace = strain_increment.trace();
    strain_increment.xx() += volumetric_strain - trace / dim;
    strain_increment.yy() += volumetric_strain - trace / dim;
    strain_increment.zz() += volumetric_strain - trace / dim;
  }

  total_strain_new = strain_increment;

  strain_increment -= total_strain_old;
}
Ejemplo n.º 14
0
Real
MaterialTensorAux::getTensorQuantity(const SymmTensor & tensor,
                                     const MTA_ENUM quantity,
                                     const MooseEnum & quantity_moose_enum,
                                     const int index,
                                     const Point * curr_point,
                                     const Point * p1,
                                     const Point * p2)
{
  Real value(0);
  if (quantity == MTA_COMPONENT)
  {
    value = tensor.component(index);
  }
  else if ( quantity == MTA_VONMISES )
  {
    value = std::sqrt(0.5*(
                           std::pow(tensor.xx() - tensor.yy(), 2) +
                           std::pow(tensor.yy() - tensor.zz(), 2) +
                           std::pow(tensor.zz() - tensor.xx(), 2) + 6 * (
                           std::pow(tensor.xy(), 2) +
                           std::pow(tensor.yz(), 2) +
                           std::pow(tensor.zx(), 2))));
  }
  else if ( quantity == MTA_PLASTICSTRAINMAG )
  {
    value = std::sqrt(2.0/3.0 * tensor.doubleContraction(tensor));
  }
  else if ( quantity == MTA_HYDROSTATIC )
  {
    value = tensor.trace()/3.0;
  }
  else if ( quantity == MTA_HOOP )
  {
    // This is the location of the stress.  A vector from the cylindrical axis to this point will define the x' axis.
    Point p0( *curr_point );

    // The vector p1 + t*(p2-p1) defines the cylindrical axis.  The point along this
    // axis closest to p0 is found by the following for t:
    const Point p2p1( *p2 - *p1 );
    const Point p2p0( *p2 - p0 );
    const Point p1p0( *p1 - p0 );
    const Real t( -(p1p0*p2p1)/p2p1.size_sq() );
    // The nearest point on the cylindrical axis to p0 is p.
    const Point p( *p1 + t * p2p1 );
    Point xp( p0 - p );
    xp /= xp.size();
    Point yp( p2p1/p2p1.size() );
    Point zp( xp.cross( yp ));
    //
    // The following works but does more than we need
    //
//    // Rotation matrix R
//    ColumnMajorMatrix R(3,3);
//    // Fill with direction cosines
//    R(0,0) = xp(0);
//    R(1,0) = xp(1);
//    R(2,0) = xp(2);
//    R(0,1) = yp(0);
//    R(1,1) = yp(1);
//    R(2,1) = yp(2);
//    R(0,2) = zp(0);
//    R(1,2) = zp(1);
//    R(2,2) = zp(2);
//    // Rotate
//    ColumnMajorMatrix tensor( _tensor[_qp].columnMajorMatrix() );
//    ColumnMajorMatrix tensorp( R.transpose() * ( tensor * R ));
//    // Hoop stress is the zz stress
//    value = tensorp(2,2);
    //
    // Instead, tensorp(2,2) = R^T(2,:)*tensor*R(:,2)
    //
    const Real zp0( zp(0) );
    const Real zp1( zp(1) );
    const Real zp2( zp(2) );
    value = (zp0*tensor(0,0)+zp1*tensor(1,0)+zp2*tensor(2,0))*zp0 +
            (zp0*tensor(0,1)+zp1*tensor(1,1)+zp2*tensor(2,1))*zp1 +
            (zp0*tensor(0,2)+zp1*tensor(1,2)+zp2*tensor(2,2))*zp2;
  }
  else if ( quantity == MTA_RADIAL )
  {
    // This is the location of the stress.  A vector from the cylindrical axis to this point will define the x' axis
    // which is the radial direction in which we want the stress.
    Point p0( *curr_point );

    // The vector p1 + t*(p2-p1) defines the cylindrical axis.  The point along this
    // axis closest to p0 is found by the following for t:
    const Point p2p1( *p2 - *p1 );
    const Point p2p0( *p2 - p0 );
    const Point p1p0( *p1 - p0 );
    const Real t( -(p1p0*p2p1)/p2p1.size_sq() );
    // The nearest point on the cylindrical axis to p0 is p.
    const Point p( *p1 + t * p2p1 );
    Point xp( p0 - p );
    xp /= xp.size();
    const Real xp0( xp(0) );
    const Real xp1( xp(1) );
    const Real xp2( xp(2) );
    value = (xp0*tensor(0,0)+xp1*tensor(1,0)+xp2*tensor(2,0))*xp0 +
            (xp0*tensor(0,1)+xp1*tensor(1,1)+xp2*tensor(2,1))*xp1 +
            (xp0*tensor(0,2)+xp1*tensor(1,2)+xp2*tensor(2,2))*xp2;
  }
  else if ( quantity == MTA_AXIAL )
  {
    // The vector p2p1=(p2-p1) defines the axis, which is the direction in which we want the stress.
    Point p2p1( *p2 - *p1 );
    p2p1 /= p2p1.size();

    const Real axis0( p2p1(0) );
    const Real axis1( p2p1(1) );
    const Real axis2( p2p1(2) );
    value = (axis0*tensor(0,0)+axis1*tensor(1,0)+axis2*tensor(2,0))*axis0 +
            (axis0*tensor(0,1)+axis1*tensor(1,1)+axis2*tensor(2,1))*axis1 +
            (axis0*tensor(0,2)+axis1*tensor(1,2)+axis2*tensor(2,2))*axis2;
  }
  else if ( quantity == MTA_MAXPRINCIPAL )
  {
    value = principalValue( tensor, 0 );
  }
  else if ( quantity == MTA_MEDPRINCIPAL )
  {
    value = principalValue( tensor, 1 );
  }
  else if ( quantity == MTA_MINPRINCIPAL )
  {
    value = principalValue( tensor, 2 );
  }
  else if ( quantity == MTA_FIRSTINVARIANT )
  {
    value = tensor.trace();
  }
  else if ( quantity == MTA_SECONDINVARIANT )
  {
    value =
      tensor.xx()*tensor.yy() +
      tensor.yy()*tensor.zz() +
      tensor.zz()*tensor.xx() -
      tensor.xy()*tensor.xy() -
      tensor.yz()*tensor.yz() -
      tensor.zx()*tensor.zx();
  }
  else if ( quantity == MTA_THIRDINVARIANT )
  {
    value =
      tensor.xx()*tensor.yy()*tensor.zz() -
      tensor.xx()*tensor.yz()*tensor.yz() +
      tensor.xy()*tensor.zx()*tensor.yz() -
      tensor.xy()*tensor.xy()*tensor.zz() +
      tensor.zx()*tensor.xy()*tensor.yz() -
      tensor.zx()*tensor.zx()*tensor.yy();
  }
  else if ( quantity == MTA_TRIAXIALITY )
  {
    Real hydrostatic = tensor.trace()/3.0;
    Real von_mises = std::sqrt(0.5*(
                                 std::pow(tensor.xx() - tensor.yy(), 2) +
                                 std::pow(tensor.yy() - tensor.zz(), 2) +
                                 std::pow(tensor.zz() - tensor.xx(), 2) + 6 * (
                                   std::pow(tensor.xy(), 2) +
                                   std::pow(tensor.yz(), 2) +
                                   std::pow(tensor.zx(), 2))));

    value = std::abs(hydrostatic / von_mises);
  }
  else if ( quantity == MTA_VOLUMETRICSTRAIN )
  {
    value =
      tensor.trace() +
      tensor.xx()*tensor.yy() +
      tensor.yy()*tensor.zz() +
      tensor.zz()*tensor.xx() +
      tensor.xx()*tensor.yy()*tensor.zz();
  }
  else
  {
    mooseError("Unknown quantity in MaterialTensorAux: " + quantity_moose_enum.operator std::string());
  }
  return value;
}