Example #1
0
void
Nonlinear3D::computeIncrementalDeformationGradient(std::vector<ColumnMajorMatrix> & Fhat)
{
  // A = grad(u(k+1) - u(k))
  // Fbar = 1 + grad(u(k))
  // Fhat = 1 + A*(Fbar^-1)
  ColumnMajorMatrix A;
  ColumnMajorMatrix Fbar;
  ColumnMajorMatrix Fbar_inverse;
  ColumnMajorMatrix Fhat_average;
  Real volume(0);

  _Fbar.resize(_solid_model.qrule()->n_points());

  for (unsigned qp = 0; qp < _solid_model.qrule()->n_points(); ++qp)
  {
    fillMatrix(qp, _grad_disp_x, _grad_disp_y, _grad_disp_z, A);
    fillMatrix(qp, _grad_disp_x_old, _grad_disp_y_old, _grad_disp_z_old, Fbar);

    A -= Fbar;

    Fbar.addDiag(1);

    _Fbar[qp] = Fbar;

    // Get Fbar^(-1)
    // Computing the inverse is generally a bad idea.
    // It's better to compute LU factors.   For now at least, we'll take
    // a direct route.

    invertMatrix(Fbar, Fbar_inverse);

    Fhat[qp] = A * Fbar_inverse;
    Fhat[qp].addDiag(1);

    if (_volumetric_locking_correction)
    {
      // Now include the contribution for the integration of Fhat over the element
      Fhat_average += Fhat[qp] * _solid_model.JxW(qp);

      volume += _solid_model.JxW(qp); // Accumulate original configuration volume
    }
  }

  if (_volumetric_locking_correction)
  {
    Fhat_average /= volume;
    const Real det_Fhat_average(detMatrix(Fhat_average));

    // Finalize volumetric locking correction
    for (unsigned qp = 0; qp < _solid_model.qrule()->n_points(); ++qp)
    {
      const Real det_Fhat(detMatrix(Fhat[qp]));
      const Real factor(std::cbrt(det_Fhat_average / det_Fhat));

      Fhat[qp] *= factor;
    }
  }
  //    Moose::out << "Fhat(0,0)" << Fhat[0](0,0) << std::endl;
}
void AbaqusUmatMaterial::computeStress()
{
    //Calculate deformation gradient - modeled from "solid_mechanics/src/materials/Nonlinear3D.C"
    // Fbar = 1 + grad(u(k))
    ColumnMajorMatrix Fbar;

    Fbar(0,0) = _grad_disp_x[_qp](0);
    Fbar(0,1) = _grad_disp_x[_qp](1);
    Fbar(0,2) = _grad_disp_x[_qp](2);
    Fbar(1,0) = _grad_disp_y[_qp](0);
    Fbar(1,1) = _grad_disp_y[_qp](1);
    Fbar(1,2) = _grad_disp_y[_qp](2);
    Fbar(2,0) = _grad_disp_z[_qp](0);
    Fbar(2,1) = _grad_disp_z[_qp](1);
    Fbar(2,2) = _grad_disp_z[_qp](2);

    Fbar.addDiag(1);
    _Fbar[_qp] = Fbar;

    Real myDFGRD0[9] = {_Fbar_old[_qp](0,0), _Fbar_old[_qp](1,0), _Fbar_old[_qp](2,0), _Fbar_old[_qp](0,1), _Fbar_old[_qp](1,1), _Fbar_old[_qp](2,1), _Fbar_old[_qp](0,2), _Fbar_old[_qp](1,2), _Fbar_old[_qp](2,2)};
    Real myDFGRD1[9] = {_Fbar[_qp](0,0), _Fbar[_qp](1,0), _Fbar[_qp](2,0), _Fbar[_qp](0,1), _Fbar[_qp](1,1), _Fbar[_qp](2,1), _Fbar[_qp](0,2), _Fbar[_qp](1,2), _Fbar[_qp](2,2)};

    for (unsigned int i=0; i<9; ++i)
    {
        _DFGRD0[i] = myDFGRD0[i];
        _DFGRD1[i] = myDFGRD1[i];
    }

    //Recover "old" state variables
    for (unsigned int i=0; i<_num_state_vars; ++i)
        _STATEV[i]=_state_var_old[_qp][i];

    //Pass through updated stress, total strain, and strain increment arrays
    for (int i=0; i<_NTENS; ++i)
    {
        _STRESS[i] = _stress_old.component(i);
        _STRAN[i] = _total_strain[_qp].component(i);
        _DSTRAN[i] = _strain_increment.component(i);
    }

    //Pass through step , time, and coordinate system information
    _KSTEP = _t_step;                       //Step number
    _TIME[0] = _t;                          //Value of step time at the beginning of the current increment - Check
    _TIME[1] = _t-_dt;                      //Value of total time at the beginning of the current increment - Check
    _DTIME = _dt;                           //Time increment
    for (unsigned int i=0; i<3; ++i)        //Loop current coordinates in UMAT COORDS
        _COORDS[i] = _coord[i];

    //Connection to extern statement
    _umat(_STRESS, _STATEV, _DDSDDE, &_SSE, &_SPD, &_SCD, &_RPL, _DDSDDT, _DRPLDE, &_DRPLDT, _STRAN, _DSTRAN, _TIME, &_DTIME, &_TEMP, &_DTEMP, _PREDEF, _DPRED, &_CMNAME, &_NDI, &_NSHR, &_NTENS, &_NSTATV, _PROPS, &_NPROPS, _COORDS, _DROT, &_PNEWDT, &_CELENT, _DFGRD0, _DFGRD1, &_NOEL, &_NPT, &_LAYER, &_KSPT, &_KSTEP, &_KINC);

    //Energy outputs
    _elastic_strain_energy[_qp] = _SSE;
    _plastic_dissipation[_qp] = _SPD;
    _creep_dissipation[_qp] = _SCD;

    //Update state variables
    for (unsigned int i=0; i<_num_state_vars; ++i)
        _state_var[_qp][i]=_STATEV[i];

    //Get new stress tensor - UMAT should update stress
    SymmTensor stressnew(_STRESS[0], _STRESS[1], _STRESS[2], _STRESS[3], _STRESS[4], _STRESS[5]);
    _stress[_qp] = stressnew;
}