Real INSChorinPredictor::computeQpResidual()
{
  // Vector object for test function
  RealVectorValue test;
  test(_component) = _test[_i][_qp];

  // Tensor object for test function gradient
  RealTensorValue grad_test;
  for (unsigned k=0; k<3; ++k)
    grad_test(_component, k) = _grad_test[_i][_qp](k);

  // Decide what velocity vector, gradient to use:
  RealVectorValue U;
  RealTensorValue grad_U;

  switch (_predictor_enum)
  {
  case OLD:
  {
    U = RealVectorValue(_u_vel_old[_qp], _v_vel_old[_qp], _w_vel_old[_qp]);
    grad_U = RealTensorValue(_grad_u_vel_old[_qp], _grad_v_vel_old[_qp], _grad_w_vel_old[_qp]);
    break;
  }
  case NEW:
  {
    U = RealVectorValue(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);
    grad_U = RealTensorValue(_grad_u_vel[_qp], _grad_v_vel[_qp], _grad_w_vel[_qp]);
    break;
  }
  case STAR:
  {
    // Note: Donea and Huerta's book says you are supposed to use "star" velocity to make Chorin implicit, not U^{n+1}.
    U = RealVectorValue(_u_vel_star[_qp], _v_vel_star[_qp], _w_vel_star[_qp]);
    grad_U = RealTensorValue(_grad_u_vel_star[_qp], _grad_v_vel_star[_qp], _grad_w_vel_star[_qp]);
    break;
  }
  default:
    mooseError("Unrecognized Chorin predictor type requested.");
  }


  //
  // Compute the different parts
  //

  // Note: _u is the component'th entry of "u_star" in Chorin's method.
  RealVectorValue U_old(_u_vel_old[_qp], _v_vel_old[_qp], _w_vel_old[_qp]);
  Real symmetric_part = (_u[_qp] - U_old(_component)) * _test[_i][_qp];

  // Convective part.  Remember to multiply by _dt!
  Real convective_part = _dt * (grad_U * U) * test;

  // Viscous part - we are using the Laplacian form here for simplicity.
  // Remember to multiply by _dt!
  Real viscous_part = _dt * (_mu/_rho) * grad_U.contract(grad_test);

  return symmetric_part + convective_part + viscous_part;
}
Exemple #2
0
Real
INSSplitMomentum::computeQpResidual()
{
  // Vector object for a
  RealVectorValue a(_a1[_qp], _a2[_qp], _a3[_qp]);

  // Vector object for test function
  RealVectorValue test;
  test(_component) = _test[_i][_qp];

  // Tensor object for "grad U" = d(u_i)/d(x_j)
  RealTensorValue grad_U(_grad_u_vel[_qp], _grad_v_vel[_qp], _grad_w_vel[_qp]);

  // Vector object for U
  RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);

  // Viscous stress tensor object
  RealTensorValue tau(
      // Row 1
      2. * _grad_u_vel[_qp](0),
      _grad_u_vel[_qp](1) + _grad_v_vel[_qp](0),
      _grad_u_vel[_qp](2) + _grad_w_vel[_qp](0),
      // Row 2
      _grad_v_vel[_qp](0) + _grad_u_vel[_qp](1),
      2. * _grad_v_vel[_qp](1),
      _grad_v_vel[_qp](2) + _grad_w_vel[_qp](1),
      // Row 3
      _grad_w_vel[_qp](0) + _grad_u_vel[_qp](2),
      _grad_w_vel[_qp](1) + _grad_v_vel[_qp](2),
      2. * _grad_w_vel[_qp](2));

  // Tensor object for test function gradient
  RealTensorValue grad_test;
  for (unsigned k = 0; k < 3; ++k)
    grad_test(_component, k) = _grad_test[_i][_qp](k);

  //
  // Compute the different pieces...
  //

  // "Symmetric" part, a.test
  Real symmetric_part = a(_component) * _test[_i][_qp];

  // The convection part, (u.grad) * u_component * test_scalar.  Which can also be
  // written as (grad_U * U) * test_vec
  Real convective_part = (grad_U * U) * test;

  // The viscous part, tau : grad(v)
  Real viscous_part = (_mu[_qp] / _rho[_qp]) * tau.contract(grad_test);

  return symmetric_part + convective_part + viscous_part;
}
Exemple #3
0
Real
INSSplitMomentum::computeQpOffDiagJacobian(unsigned jvar)
{
  if ((jvar == _u_vel_var_number) || (jvar == _v_vel_var_number) || (jvar == _w_vel_var_number))
  {
    // Derivative of viscous stress tensor
    RealTensorValue dtau;

    // Initialize to invalid value, then determine correct value.
    unsigned vel_index = 99;

    // Set index and build dtau for that index
    if (jvar == _u_vel_var_number)
    {
      vel_index = 0;
      dtau(0, 0) = 2. * _grad_phi[_j][_qp](0);
      dtau(0, 1) = _grad_phi[_j][_qp](1);
      dtau(0, 2) = _grad_phi[_j][_qp](2);
      dtau(1, 0) = _grad_phi[_j][_qp](1);
      dtau(2, 0) = _grad_phi[_j][_qp](2);
    }
    else if (jvar == _v_vel_var_number)
    {
      vel_index = 1;
      /*                                 */ dtau(0, 1) = _grad_phi[_j][_qp](0);
      dtau(1, 0) = _grad_phi[_j][_qp](0);
      dtau(1, 1) = 2. * _grad_phi[_j][_qp](1);
      dtau(1, 2) = _grad_phi[_j][_qp](2);
      /*                                 */ dtau(2, 1) = _grad_phi[_j][_qp](2);
    }
    else if (jvar == _w_vel_var_number)
    {
      vel_index = 2;
      /*                                                                     */ dtau(0, 2) =
          _grad_phi[_j][_qp](0);
      /*                                                                     */ dtau(1, 2) =
          _grad_phi[_j][_qp](1);
      dtau(2, 0) = _grad_phi[_j][_qp](0);
      dtau(2, 1) = _grad_phi[_j][_qp](1);
      dtau(2, 2) = 2. * _grad_phi[_j][_qp](2);
    }

    // Vector object for test function
    RealVectorValue test;
    test(_component) = _test[_i][_qp];

    // Vector object for U
    RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);

    // Tensor object for test function gradient
    RealTensorValue grad_test;
    for (unsigned k = 0; k < 3; ++k)
      grad_test(_component, k) = _grad_test[_i][_qp](k);

    // Compute the convective part
    RealVectorValue convective_jac = _phi[_j][_qp] * RealVectorValue(_grad_u_vel[_qp](vel_index),
                                                                     _grad_v_vel[_qp](vel_index),
                                                                     _grad_w_vel[_qp](vel_index));

    // Extra contribution in vel_index component
    convective_jac(vel_index) += U * _grad_phi[_j][_qp];
    Real convective_part = convective_jac * test;

    // Compute the viscous part
    Real viscous_part = (_mu[_qp] / _rho[_qp]) * dtau.contract(grad_test);

    // Return the result
    return convective_part + viscous_part;
  }

  else
    return 0;
}
Real INSChorinPredictor::computeQpOffDiagJacobian(unsigned jvar)
{
  switch (_predictor_enum)
  {
  case OLD:
  {
    return 0.;
  }

  case NEW:
  {
    if ((jvar == _u_vel_var_number) || (jvar == _v_vel_var_number) || (jvar == _w_vel_var_number))
    {
      // Derivative of grad_U wrt the velocity component
      RealTensorValue dgrad_U;

      // Initialize to invalid value, then determine correct value.
      unsigned vel_index = 99;

      // Map jvar into the indices (0,1,2)
      if (jvar == _u_vel_var_number)
        vel_index = 0;

      else if (jvar == _v_vel_var_number)
        vel_index = 1;

      else if (jvar == _w_vel_var_number)
        vel_index = 2;

      // Fill in the vel_index'th row of dgrad_U with _grad_phi[_j][_qp]
      for (unsigned k=0; k<3; ++k)
        dgrad_U(vel_index,k) = _grad_phi[_j][_qp](k);

      // Vector object for test function
      RealVectorValue test;
      test(_component) = _test[_i][_qp];

      // Vector object for U
      RealVectorValue U(_u_vel[_qp], _v_vel[_qp], _w_vel[_qp]);

      // Tensor object for test function gradient
      RealTensorValue grad_test;
      for (unsigned k=0; k<3; ++k)
        grad_test(_component, k) = _grad_test[_i][_qp](k);

      // Compute the convective part
      RealVectorValue convective_jac = _phi[_j][_qp] * RealVectorValue(_grad_u_vel[_qp](vel_index),
                                                                       _grad_v_vel[_qp](vel_index),
                                                                       _grad_w_vel[_qp](vel_index));

      // Extra contribution in vel_index component
      convective_jac(vel_index) += U*_grad_phi[_j][_qp];

      // Be sure to scale by _dt!
      Real convective_part = _dt * (convective_jac * test);

      // Compute the viscous part, be sure to scale by _dt.  Note: the contracted
      // value should be zero unless vel_index and _component match.
      Real viscous_part = _dt * (_mu/_rho) * dgrad_U.contract(grad_test);

      // Return the result
      return convective_part + viscous_part;
    }
    else
      return 0;
  }

  case STAR:
  {
    if (jvar == _u_vel_star_var_number)
    {
      return _dt * _phi[_j][_qp] * _grad_u[_qp](0) * _test[_i][_qp];
    }

    else if (jvar == _v_vel_star_var_number)
    {
      return _dt * _phi[_j][_qp] * _grad_u[_qp](1) * _test[_i][_qp];
    }

    else if (jvar == _w_vel_star_var_number)
    {
      return _dt * _phi[_j][_qp] * _grad_u[_qp](2) * _test[_i][_qp];
    }

    else
      return 0;
  }

  default:
    mooseError("Unrecognized Chorin predictor type requested.");
  }
}