void ReactingLowMachNavierStokesStabilizationBase<Mixture,Evaluator>::compute_res_transient( AssemblyContext& context,
                                                                                               unsigned int qp,
                                                                                               libMesh::Real& RP_t,
                                                                                               libMesh::RealGradient& RM_t,
                                                                                               libMesh::Real& RE_t,
                                                                                               std::vector<libMesh::Real>& Rs_t )
  {
    libMesh::Real T = context.interior_value( this->_temp_vars.T(), qp );

    std::vector<libMesh::Real> ws(this->n_species());
    for(unsigned int s=0; s < this->_n_species; s++ )
      {
        ws[s] = context.interior_value(this->_species_vars.species(s), qp);
      }

    Evaluator gas_evaluator( this->_gas_mixture );
    const libMesh::Real R_mix = gas_evaluator.R_mix(ws);
    const libMesh::Real p0 = this->get_p0_transient(context,qp);
    const libMesh::Real rho = this->rho(T, p0, R_mix);
    const libMesh::Real cp = gas_evaluator.cp(T,p0,ws);
    const libMesh::Real M = gas_evaluator.M_mix( ws );

    // M_dot = -M^2 \sum_s w_dot[s]/Ms
    libMesh::Real M_dot = 0.0;
    std::vector<libMesh::Real> ws_dot(this->n_species());
    for(unsigned int s=0; s < this->n_species(); s++)
      {
        context.interior_rate(this->_species_vars.species(s), qp, ws_dot[s]);

        // Start accumulating M_dot
        M_dot += ws_dot[s]/this->_gas_mixture.M(s);
      }
    libMesh::Real M_dot_over_M = M_dot*(-M);

    libMesh::RealGradient u_dot;
    context.interior_rate(this->_flow_vars.u(), qp, u_dot(0));
    context.interior_rate(this->_flow_vars.v(), qp, u_dot(1));
    if(this->mesh_dim(context) == 3)
      context.interior_rate(this->_flow_vars.w(), qp, u_dot(2));

    libMesh::Real T_dot;
    context.interior_rate(this->_temp_vars.T(), qp, T_dot);

    RP_t = -T_dot/T + M_dot_over_M;
    RM_t = rho*u_dot;
    RE_t = rho*cp*T_dot;
    for(unsigned int s=0; s < this->n_species(); s++)
      {
        Rs_t[s] = rho*ws_dot[s];
      }

    return;
  }
예제 #2
0
void
MooseVariable::computeElemValuesFace()
{
  bool is_transient = _subproblem.isTransient();
  unsigned int nqp = _qrule_face->n_points();
  _u.resize(nqp);
  _grad_u.resize(nqp);

  if (_need_second)
    _second_u.resize(nqp);

  if (is_transient)
  {
    _u_dot.resize(nqp);
    _du_dot_du.resize(nqp);

    if (_need_u_old)
      _u_old.resize(nqp);

    if (_need_u_older)
      _u_older.resize(nqp);

    if (_need_grad_old)
      _grad_u_old.resize(nqp);

    if (_need_grad_older)
      _grad_u_older.resize(nqp);

    if (_need_second_old)
      _second_u_old.resize(nqp);

    if (_need_second_older)
      _second_u_older.resize(nqp);
  }

  for (unsigned int i = 0; i < nqp; ++i)
  {
    _u[i] = 0;
    _grad_u[i] = 0;

    if (_subproblem.isTransient())
    {
      _u_dot[i] = 0;
      _du_dot_du[i] = 0;

      if (_need_u_old)
        _u_old[i] = 0;

      if (_need_u_older)
        _u_older[i] = 0;

      if (_need_grad_old)
        _grad_u_old[i] = 0;

      if (_need_grad_older)
        _grad_u_older[i] = 0;

      if (_need_second)
        _second_u[i] = 0;

      if (_need_second_old)
        _second_u_old[i] = 0;

      if (_need_second_older)
        _second_u_older[i] = 0;
    }
  }

  unsigned int num_dofs = _dof_indices.size();

  const NumericVector<Real> & current_solution = *_sys.currentSolution();
  const NumericVector<Real> & solution_old     = _sys.solutionOld();
  const NumericVector<Real> & solution_older   = _sys.solutionOlder();
  const NumericVector<Real> & u_dot            = _sys.solutionUDot();
  const Real & du_dot_du                       = _sys.duDotDu();

  dof_id_type idx;
  Real soln_local;
  Real soln_old_local = 0;
  Real soln_older_local = 0;
  Real u_dot_local = 0;

  Real phi_local;
  RealGradient dphi_local;
  RealTensor d2phi_local;

  for (unsigned int i=0; i < num_dofs; ++i)
  {
    idx = _dof_indices[i];
    soln_local = current_solution(idx);

    if (is_transient)
    {
      if (_need_u_old || _need_grad_old || _need_second_old)
        soln_old_local = solution_old(idx);

      if (_need_u_older || _need_grad_older || _need_second_older)
        soln_older_local = solution_older(idx);

      u_dot_local = u_dot(idx);
    }

    for (unsigned int qp=0; qp < nqp; ++qp)
    {
      phi_local = _phi_face[i][qp];
      dphi_local = _grad_phi_face[i][qp];

      if (_need_second || _need_second_old || _need_second_older)
        d2phi_local = (*_second_phi_face)[i][qp];

      _u[qp]      += phi_local * soln_local;
      _grad_u[qp] += dphi_local * soln_local;

      if (_need_second)
        _second_u[qp] += d2phi_local * soln_local;

      if (is_transient)
      {
        _u_dot[qp]        += phi_local * u_dot_local;
        _du_dot_du[qp]    = du_dot_du;

        if (_need_u_old)
          _u_old[qp]        += phi_local * soln_old_local;

        if (_need_u_older)
          _u_older[qp]      += phi_local * soln_older_local;

        if (_need_grad_old)
          _grad_u_old[qp]   += dphi_local * soln_old_local;

        if (_need_grad_older)
          _grad_u_older[qp] += dphi_local * soln_older_local;

        if (_need_second_old)
          _second_u_old[qp] += d2phi_local * soln_old_local;

        if (_need_second_older)
          _second_u_older[qp] += d2phi_local * soln_older_local;
      }
    }
  }
}
예제 #3
0
// FIXME: this and computeElemeValues() could be refactored to reuse most of
//        the common code, instead of duplicating it.
void
MooseVariable::computePerturbedElemValues(unsigned int perturbation_idx, Real perturbation_scale, Real& perturbation)
{

  bool is_transient = _subproblem.isTransient();
  unsigned int nqp = _qrule->n_points();

  _u_bak = _u;
  _grad_u_bak = _grad_u;
  _u.resize(nqp);
  _grad_u.resize(nqp);

  if (_need_second)
    _second_u_bak = _second_u;
    _second_u.resize(nqp);

  if (is_transient)
  {
    _u_dot_bak = _u_dot;
    _u_dot.resize(nqp);
    _du_dot_du_bak = _du_dot_du;
    _du_dot_du.resize(nqp);

    if (_need_u_old)
      _u_old_bak = _u_old;
      _u_old.resize(nqp);

    if (_need_u_older)
      _u_older_bak = _u_older;
      _u_older.resize(nqp);

    if (_need_grad_old)
      _grad_u_old_bak = _grad_u_old;
      _grad_u_old.resize(nqp);

    if (_need_grad_older)
      _grad_u_older_bak = _grad_u_older;
      _grad_u_older.resize(nqp);

    if (_need_second_old)
      _second_u_old_bak = _second_u_old;
      _second_u_old.resize(nqp);

    if (_need_second_older)
      _second_u_older_bak = _second_u_older;
      _second_u_older.resize(nqp);
  }

  for (unsigned int i = 0; i < nqp; ++i)
  {
    _u[i] = 0;
    _grad_u[i] = 0;

    if (_need_second)
      _second_u[i] = 0;

    if (is_transient)
    {
      _u_dot[i] = 0;
      _du_dot_du[i] = 0;

      if (_need_u_old)
        _u_old[i] = 0;

      if (_need_u_older)
        _u_older[i] = 0;

      if (_need_grad_old)
        _grad_u_old[i] = 0;

      if (_need_grad_older)
        _grad_u_older[i] = 0;

      if (_need_second_old)
        _second_u_old[i] = 0;

      if (_need_second_older)
        _second_u_older[i] = 0;
    }
  }

  unsigned int num_dofs = _dof_indices.size();

  const NumericVector<Real> & current_solution = *_sys.currentSolution();
  const NumericVector<Real> & solution_old     = _sys.solutionOld();
  const NumericVector<Real> & solution_older   = _sys.solutionOlder();
  const NumericVector<Real> & u_dot            = _sys.solutionUDot();
  const Real & du_dot_du                       = _sys.duDotDu();

  dof_id_type idx = 0;
  Real soln_local = 0;
  Real soln_old_local = 0;
  Real soln_older_local = 0;
  Real u_dot_local = 0;

  Real phi_local = 0;
  const RealGradient * dphi_qp = NULL;
  const RealTensor * d2phi_local = NULL;

  RealGradient * grad_u_qp = NULL;

  RealGradient * grad_u_old_qp = NULL;
  RealGradient * grad_u_older_qp = NULL;

  RealTensor * second_u_qp = NULL;

  RealTensor * second_u_old_qp = NULL;
  RealTensor * second_u_older_qp = NULL;

  for (unsigned int i=0; i < num_dofs; i++)
  {
    idx = _dof_indices[i];
    soln_local = current_solution(idx);
    if (i == perturbation_idx) {
      // Compute the size of the perturbation.
      // For the PETSc DS differencing method we use the magnitude of the variable at the "node"
      // to determine the differencing parameters.  The WP method could use the element L2 norm of
      // the variable  instead.
      perturbation = soln_local;
      // HACK: the use of fabs() and < assume Real is double or similar. Otherwise need to use PetscAbsScalar, PetscRealPart, etc.
      if (fabs(perturbation) < 1.0e-16) perturbation = (perturbation < 0. ? -1.0: 1.0)*0.1;
      perturbation *= perturbation_scale;
      soln_local += perturbation;
    }
    if (is_transient)
    {
      if (_need_u_old || _need_grad_old || _need_second_old)
        soln_old_local = solution_old(idx);

      if (_need_u_older || _need_grad_older || _need_second_older)
        soln_older_local = solution_older(idx);

      u_dot_local        = u_dot(idx);
    }

    for (unsigned int qp=0; qp < nqp; qp++)
    {
      phi_local = _phi[i][qp];
      dphi_qp = &_grad_phi[i][qp];

      grad_u_qp = &_grad_u[qp];

      if (is_transient)
      {
        if (_need_grad_old)
          grad_u_old_qp = &_grad_u_old[qp];

        if (_need_grad_older)
          grad_u_older_qp = &_grad_u_older[qp];
      }

      if (_need_second || _need_second_old || _need_second_older)
      {
        d2phi_local = &(*_second_phi)[i][qp];

        if (_need_second)
          second_u_qp = &_second_u[qp];

        if (is_transient)
        {
          if (_need_second_old)
            second_u_old_qp = &_second_u_old[qp];

          if (_need_second_older)
            second_u_older_qp = &_second_u_older[qp];
        }
      }

      _u[qp]     += phi_local * soln_local;

      grad_u_qp->add_scaled(*dphi_qp, soln_local);

      if (_need_second)
        second_u_qp->add_scaled(*d2phi_local, soln_local);

      if (is_transient)
      {
        _u_dot[qp]        += phi_local * u_dot_local;
        _du_dot_du[qp]    = du_dot_du;

        if (_need_u_old)
          _u_old[qp]        += phi_local * soln_old_local;

        if (_need_u_older)
          _u_older[qp]      += phi_local * soln_older_local;

        if (_need_grad_old)
          grad_u_old_qp->add_scaled(*dphi_qp, soln_old_local);

        if (_need_grad_older)
          grad_u_older_qp->add_scaled(*dphi_qp, soln_older_local);

        if (_need_second_old)
          second_u_old_qp->add_scaled(*d2phi_local, soln_old_local);

        if (_need_second_older)
          second_u_older_qp->add_scaled(*d2phi_local, soln_older_local);
      }
    }
  }
}
예제 #4
0
void
MooseVariable::computeElemValues()
{

  bool is_transient = _subproblem.isTransient();
  unsigned int nqp = _qrule->n_points();

  _u.resize(nqp);
  _grad_u.resize(nqp);

  if (_need_second)
    _second_u.resize(nqp);

  if (is_transient)
  {
    _u_dot.resize(nqp);
    _du_dot_du.resize(nqp);

    if (_need_u_old)
      _u_old.resize(nqp);

    if (_need_u_older)
      _u_older.resize(nqp);

    if (_need_grad_old)
      _grad_u_old.resize(nqp);

    if (_need_grad_older)
      _grad_u_older.resize(nqp);

    if (_need_second_old)
      _second_u_old.resize(nqp);

    if (_need_second_older)
      _second_u_older.resize(nqp);
  }

  for (unsigned int i = 0; i < nqp; ++i)
  {
    _u[i] = 0;
    _grad_u[i] = 0;

    if (_need_second)
      _second_u[i] = 0;

    if (is_transient)
    {
      _u_dot[i] = 0;
      _du_dot_du[i] = 0;

      if (_need_u_old)
        _u_old[i] = 0;

      if (_need_u_older)
        _u_older[i] = 0;

      if (_need_grad_old)
        _grad_u_old[i] = 0;

      if (_need_grad_older)
        _grad_u_older[i] = 0;

      if (_need_second_old)
        _second_u_old[i] = 0;

      if (_need_second_older)
        _second_u_older[i] = 0;
    }
  }

  unsigned int num_dofs = _dof_indices.size();

  const NumericVector<Real> & current_solution = *_sys.currentSolution();
  const NumericVector<Real> & solution_old     = _sys.solutionOld();
  const NumericVector<Real> & solution_older   = _sys.solutionOlder();
  const NumericVector<Real> & u_dot            = _sys.solutionUDot();
  const Real & du_dot_du                       = _sys.duDotDu();

  dof_id_type idx = 0;
  Real soln_local = 0;
  Real soln_old_local = 0;
  Real soln_older_local = 0;
  Real u_dot_local = 0;

  Real phi_local = 0;
  const RealGradient * dphi_qp = NULL;
  const RealTensor * d2phi_local = NULL;

  RealGradient * grad_u_qp = NULL;

  RealGradient * grad_u_old_qp = NULL;
  RealGradient * grad_u_older_qp = NULL;

  RealTensor * second_u_qp = NULL;

  RealTensor * second_u_old_qp = NULL;
  RealTensor * second_u_older_qp = NULL;

  for (unsigned int i=0; i < num_dofs; i++)
  {
    idx = _dof_indices[i];
    soln_local = current_solution(idx);

    if (is_transient)
    {
      if (_need_u_old || _need_grad_old || _need_second_old)
        soln_old_local = solution_old(idx);

      if (_need_u_older || _need_grad_older || _need_second_older)
        soln_older_local = solution_older(idx);

      u_dot_local        = u_dot(idx);
    }

    for (unsigned int qp=0; qp < nqp; qp++)
    {
      phi_local = _phi[i][qp];
      dphi_qp = &_grad_phi[i][qp];

      grad_u_qp = &_grad_u[qp];

      if (is_transient)
      {
        if (_need_grad_old)
          grad_u_old_qp = &_grad_u_old[qp];

        if (_need_grad_older)
          grad_u_older_qp = &_grad_u_older[qp];
      }

      if (_need_second || _need_second_old || _need_second_older)
      {
        d2phi_local = &(*_second_phi)[i][qp];

        if (_need_second)
          second_u_qp = &_second_u[qp];

        if (is_transient)
        {
          if (_need_second_old)
            second_u_old_qp = &_second_u_old[qp];

          if (_need_second_older)
            second_u_older_qp = &_second_u_older[qp];
        }
      }

      _u[qp] += phi_local * soln_local;

      grad_u_qp->add_scaled(*dphi_qp, soln_local);

      if (_need_second)
        second_u_qp->add_scaled(*d2phi_local, soln_local);

      if (is_transient)
      {
        _u_dot[qp]        += phi_local * u_dot_local;
        _du_dot_du[qp]    = du_dot_du;

        if (_need_u_old)
          _u_old[qp]        += phi_local * soln_old_local;

        if (_need_u_older)
          _u_older[qp]      += phi_local * soln_older_local;

        if (_need_grad_old)
          grad_u_old_qp->add_scaled(*dphi_qp, soln_old_local);

        if (_need_grad_older)
          grad_u_older_qp->add_scaled(*dphi_qp, soln_older_local);

        if (_need_second_old)
          second_u_old_qp->add_scaled(*d2phi_local, soln_old_local);

        if (_need_second_older)
          second_u_older_qp->add_scaled(*d2phi_local, soln_older_local);
      }
    }
  }
}
예제 #5
0
void
MooseVariable::computeNeighborValues()
{
  bool is_transient = _subproblem.isTransient();
  unsigned int nqp = _qrule_neighbor->n_points();

  _u_neighbor.resize(nqp);
  _grad_u_neighbor.resize(nqp);

  if (_need_second_neighbor)
    _second_u_neighbor.resize(nqp);

  if (is_transient)
  {
    if (_need_u_old_neighbor)
      _u_old_neighbor.resize(nqp);

    if (_need_u_older_neighbor)
      _u_older_neighbor.resize(nqp);

    if (_need_grad_old_neighbor)
      _grad_u_old_neighbor.resize(nqp);

    if (_need_grad_older_neighbor)
      _grad_u_older_neighbor.resize(nqp);

    if (_need_second_old_neighbor)
      _second_u_old_neighbor.resize(nqp);

    if (_need_second_older_neighbor)
      _second_u_older_neighbor.resize(nqp);
  }

  for (unsigned int i = 0; i < nqp; ++i)
  {
    _u_neighbor[i] = 0;
    _grad_u_neighbor[i] = 0;

    if (_need_second_neighbor)
      _second_u_neighbor[i] = 0;

    if (_subproblem.isTransient())
    {
      if (_need_u_old_neighbor)
        _u_old_neighbor[i] = 0;

      if (_need_u_older_neighbor)
        _u_older_neighbor[i] = 0;

      if (_need_grad_old_neighbor)
        _grad_u_old_neighbor[i] = 0;

      if (_need_grad_older_neighbor)
        _grad_u_older_neighbor[i] = 0;

      if (_need_second_old_neighbor)
        _second_u_old_neighbor[i] = 0;

      if (_need_second_older_neighbor)
        _second_u_older_neighbor[i] = 0;
    }
  }

  unsigned int num_dofs = _dof_indices_neighbor.size();

  if (_need_nodal_u_neighbor)
    _nodal_u_neighbor.resize(num_dofs);
  if (is_transient)
  {
    if (_need_nodal_u_old_neighbor)
      _nodal_u_old_neighbor.resize(num_dofs);
    if (_need_nodal_u_older_neighbor)
      _nodal_u_older_neighbor.resize(num_dofs);
    if (_need_nodal_u_dot_neighbor)
      _nodal_u_dot_neighbor.resize(num_dofs);
  }

  const NumericVector<Real> & current_solution = *_sys.currentSolution();
  const NumericVector<Real> & solution_old = _sys.solutionOld();
  const NumericVector<Real> & solution_older = _sys.solutionOlder();
  const NumericVector<Real> & u_dot = _sys.solutionUDot();

  dof_id_type idx;
  Real soln_local;
  Real soln_old_local = 0;
  Real soln_older_local = 0;
  Real u_dot_local = 0;

  Real phi_local;
  RealGradient dphi_local;
  RealTensor d2phi_local;

  for (unsigned int i = 0; i < num_dofs; ++i)
  {
    idx = _dof_indices_neighbor[i];
    soln_local = current_solution(idx);

    if (is_transient)
    {
      if (_need_u_old_neighbor)
        soln_old_local = solution_old(idx);

      if (_need_u_older_neighbor)
        soln_older_local = solution_older(idx);

      if (_need_nodal_u_old_neighbor)
        _nodal_u_old_neighbor[i] = soln_old_local;
      if (_need_nodal_u_older_neighbor)
        _nodal_u_older_neighbor[i] = soln_older_local;

      u_dot_local = u_dot(idx);
      if (_need_nodal_u_dot_neighbor)
        _nodal_u_dot_neighbor[i] = u_dot_local;
    }

    for (unsigned int qp = 0; qp < nqp; ++qp)
    {
      phi_local = _phi_neighbor[i][qp];
      dphi_local = _grad_phi_neighbor[i][qp];

      if (_need_second_neighbor || _need_second_old_neighbor || _need_second_older_neighbor)
        d2phi_local = (*_second_phi_neighbor)[i][qp];

      _u_neighbor[qp] += phi_local * soln_local;
      _grad_u_neighbor[qp] += dphi_local * soln_local;

      if (_need_second_neighbor)
        _second_u_neighbor[qp] += d2phi_local * soln_local;

      if (is_transient)
      {
        if (_need_u_old_neighbor)
          _u_old_neighbor[qp] += phi_local * soln_old_local;

        if (_need_u_older_neighbor)
          _u_older_neighbor[qp] += phi_local * soln_older_local;

        if (_need_grad_old_neighbor)
          _grad_u_old_neighbor[qp] += dphi_local * soln_old_local;

        if (_need_grad_older_neighbor)
          _grad_u_older_neighbor[qp] += dphi_local * soln_older_local;

        if (_need_second_old_neighbor)
          _second_u_old_neighbor[qp] += d2phi_local * soln_old_local;

        if (_need_second_older_neighbor)
          _second_u_older_neighbor[qp] += d2phi_local * soln_older_local;
      }
    }
  }
}