예제 #1
0
//
// Test the LCM mini minimizer.
//
TEST(AlbanyResidual, NewtonBanana)
{
  bool const print_output = ::testing::GTEST_FLAG(print_time);

  // outputs nothing
  Teuchos::oblackholestream bhs;

  std::ostream& os = (print_output == true) ? std::cout : bhs;

  using EvalT   = PHAL::AlbanyTraits::Residual;
  using ScalarT = typename EvalT::ScalarT;
  using ValueT  = typename Sacado::ValueType<ScalarT>::type;

  constexpr minitensor::Index DIM{2};

  using MIN  = minitensor::Minimizer<ValueT, DIM>;
  using FN   = LCM::Banana<ValueT>;
  using STEP = minitensor::StepBase<FN, ValueT, DIM>;

  MIN minimizer;

  std::unique_ptr<STEP> pstep =
      minitensor::stepFactory<FN, ValueT, DIM>(minitensor::StepType::NEWTON);

  assert(pstep->name() != nullptr);

  STEP& step = *pstep;

  FN banana;

  minitensor::Vector<ScalarT, DIM> x;

  x(0) = 0.0;
  x(1) = 3.0;

  LCM::MiniSolver<MIN, STEP, FN, EvalT, DIM> mini_solver(
      minimizer, step, banana, x);

  minimizer.printReport(os);

  ASSERT_EQ(minimizer.converged, true);
}
예제 #2
0
//
// Test the LCM mini minimizer.
//
TEST(AlbanyJacobian, NewtonBanana)
{
  bool const print_output = ::testing::GTEST_FLAG(print_time);

  // outputs nothing
  Teuchos::oblackholestream bhs;

  std::ostream& os = (print_output == true) ? std::cout : bhs;

  using EvalT   = PHAL::AlbanyTraits::Jacobian;
  using ScalarT = typename EvalT::ScalarT;
  using ValueT  = typename Sacado::ValueType<ScalarT>::type;

  constexpr minitensor::Index DIM{2};

  using MIN  = minitensor::Minimizer<ValueT, DIM>;
  using FN   = LCM::Banana<ValueT>;
  using STEP = minitensor::NewtonStep<FN, ValueT, DIM>;

  MIN minimizer;

  STEP step;

  FN banana;

  minitensor::Vector<ScalarT, DIM> x;

  x(0) = 0.0;
  x(1) = 3.0;

  LCM::MiniSolver<MIN, STEP, FN, EvalT, DIM> mini_solver(
      minimizer, step, banana, x);

  minimizer.printReport(os);

  ASSERT_EQ(minimizer.converged, true);
}
예제 #3
0
KOKKOS_INLINE_FUNCTION void
J2MiniKernel<EvalT, Traits>::operator()(int cell, int pt) const
{
  constexpr minitensor::Index MAX_DIM{3};

  using Tensor = minitensor::Tensor<ScalarT, MAX_DIM>;

  Tensor        F(num_dims_);
  Tensor const  I(minitensor::eye<ScalarT, MAX_DIM>(num_dims_));
  Tensor        sigma(num_dims_);
  ScalarT const E     = elastic_modulus_(cell, pt);
  ScalarT const nu    = poissons_ratio_(cell, pt);
  ScalarT const kappa = E / (3.0 * (1.0 - 2.0 * nu));
  ScalarT const mu    = E / (2.0 * (1.0 + nu));
  ScalarT const K     = hardening_modulus_(cell, pt);
  ScalarT const Y     = yield_strength_(cell, pt);
  ScalarT const J1    = J_(cell, pt);
  ScalarT const Jm23  = 1.0 / std::cbrt(J1 * J1);

  // fill local tensors
  F.fill(def_grad_, cell, pt, 0, 0);

  // Mechanical deformation gradient
  auto Fm = Tensor(F);
  if (have_temperature_) {
    // Compute the mechanical deformation gradient Fm based on the
    // multiplicative decomposition of the deformation gradient
    //
    //            F = Fm.Ft => Fm = F.inv(Ft)
    //
    // where Ft is the thermal part of F, given as
    //
    //     Ft = Le * I = exp(alpha * dtemp) * I
    //
    // Le = exp(alpha*dtemp) is the thermal stretch and alpha the
    // coefficient of thermal expansion.
    ScalarT dtemp           = temperature_(cell, pt) - ref_temperature_;
    ScalarT thermal_stretch = std::exp(expansion_coeff_ * dtemp);
    Fm /= thermal_stretch;
  }

  Tensor Fpn(num_dims_);

  for (int i{0}; i < num_dims_; ++i) {
    for (int j{0}; j < num_dims_; ++j) {
      Fpn(i, j) = ScalarT(Fp_old_(cell, pt, i, j));
    }
  }

  // compute trial state
  Tensor const  Fpinv = minitensor::inverse(Fpn);
  Tensor const  Cpinv = Fpinv * minitensor::transpose(Fpinv);
  Tensor const  be    = Jm23 * Fm * Cpinv * minitensor::transpose(Fm);
  Tensor        s     = mu * minitensor::dev(be);
  ScalarT const mubar = minitensor::trace(be) * mu / (num_dims_);

  // check yield condition
  ScalarT const smag = minitensor::norm(s);
  ScalarT const f =
      smag -
      SQ23 * (Y + K * eqps_old_(cell, pt) +
              sat_mod_ * (1.0 - std::exp(-sat_exp_ * eqps_old_(cell, pt))));

  RealType constexpr yield_tolerance = 1.0e-12;

  if (f > yield_tolerance) {
    // Use minimization equivalent to return mapping
    using ValueT = typename Sacado::ValueType<ScalarT>::type;
    using NLS    = J2NLS<EvalT>;

    constexpr minitensor::Index nls_dim{NLS::DIMENSION};

    using MIN  = minitensor::Minimizer<ValueT, nls_dim>;
    using STEP = minitensor::NewtonStep<NLS, ValueT, nls_dim>;

    MIN  minimizer;
    STEP step;
    NLS  j2nls(sat_mod_, sat_exp_, eqps_old_(cell, pt), K, smag, mubar, Y);

    minitensor::Vector<ScalarT, nls_dim> x;

    x(0) = 0.0;

    LCM::MiniSolver<MIN, STEP, NLS, EvalT, nls_dim> mini_solver(
        minimizer, step, j2nls, x);

    ScalarT const alpha = eqps_old_(cell, pt) + SQ23 * x(0);
    ScalarT const H     = K * alpha + sat_mod_ * (1.0 - exp(-sat_exp_ * alpha));
    ScalarT const dgam  = x(0);

    // plastic direction
    Tensor const N = (1 / smag) * s;

    // update s
    s -= 2 * mubar * dgam * N;

    // update eqps
    eqps_(cell, pt) = alpha;

    // mechanical source
    if (have_temperature_ == true && delta_time_(0) > 0) {
      source_(cell, pt) =
          (SQ23 * dgam / delta_time_(0) * (Y + H + temperature_(cell, pt))) /
          (density_ * heat_capacity_);
    }

    // exponential map to get Fpnew
    Tensor const A     = dgam * N;
    Tensor const expA  = minitensor::exp(A);
    Tensor const Fpnew = expA * Fpn;

    for (int i{0}; i < num_dims_; ++i) {
      for (int j{0}; j < num_dims_; ++j) { Fp_(cell, pt, i, j) = Fpnew(i, j); }
    }
  } else {
    eqps_(cell, pt) = eqps_old_(cell, pt);

    if (have_temperature_ == true) source_(cell, pt) = 0.0;

    for (int i{0}; i < num_dims_; ++i) {
      for (int j{0}; j < num_dims_; ++j) { Fp_(cell, pt, i, j) = Fpn(i, j); }
    }
  }

  // update yield surface
  yield_surf_(cell, pt) =
      Y + K * eqps_(cell, pt) +
      sat_mod_ * (1. - std::exp(-sat_exp_ * eqps_(cell, pt)));

  // compute pressure
  ScalarT const p = 0.5 * kappa * (J_(cell, pt) - 1. / (J_(cell, pt)));

  // compute stress
  sigma = p * I + s / J_(cell, pt);

  for (int i(0); i < num_dims_; ++i) {
    for (int j(0); j < num_dims_; ++j) {
      stress_(cell, pt, i, j) = sigma(i, j);
    }
  }
}
예제 #4
0
void FerroicModel<EvalT>::
computeState(
      const Intrepid2::Tensor<ScalarT, FM::THREE_D>& x,
      const Intrepid2::Vector<ScalarT, FM::THREE_D>& E,
      const Teuchos::Array<RealType>& oldfractions,
            Intrepid2::Tensor<ScalarT, FM::THREE_D>& X,
            Intrepid2::Vector<ScalarT, FM::THREE_D>& D,
            Teuchos::Array<ScalarT>& newfractions)
/******************************************************************************/
{

  // create non-linear system
  //
  using NLS = FM::DomainSwitching<EvalT>;
  NLS domainSwitching(crystalVariants, transitions, tBarriers, 
                      oldfractions, aMatrix, x, E, /* dt= */ 1.0);
  
  // solution variable
  //
  Intrepid2::Vector<ScalarT,FM::MAX_TRNS> xi;

  // solve for xi
  //
  switch (m_integrationType){
        
    default:
    break;

    case FM::IntegrationType::EXPLICIT:
    {

      switch (m_explicitMethod){
  
        default:
        break;

        case FM::ExplicitMethod::SCALED_DESCENT:
        {
          FM::ScaledDescent(domainSwitching, xi);
        }
        case FM::ExplicitMethod::DESCENT_NORM:
        {
          FM::DescentNorm(domainSwitching, xi);
        }
      }
    }
 
    case FM::IntegrationType::IMPLICIT:
    {

      // create minimizer
      using ValueT = typename Sacado::ValueType<ScalarT>::type;
      using MIN = Intrepid2::Minimizer<ValueT, MAX_TRNS>;
      MIN minimizer;

      // create stepper
      using STEP = Intrepid2::StepBase<NLS, ValueT, MAX_TRNS>;
      std::unique_ptr<STEP> 
        pstep = Intrepid2::stepFactory<NLS, ValueT, MAX_TRNS>(m_step_type);
      STEP &step = *pstep;

      // create solution vector with initial guess
      int ntrans = domainSwitching.getNumStates();
      xi.set_dimension(ntrans);
      for(int itrans=0; itrans<ntrans; itrans++)
        xi(itrans) = Sacado::ScalarValue<ScalarT>::eval(0.0);

      // solve
      LCM::MiniSolver<MIN, STEP, NLS, EvalT, MAX_TRNS>
        mini_solver(minimizer, step, domainSwitching, xi);
    }
  }

  // update based on new xi values
  //

}