Пример #1
0
// ---------------------------------------------------------------
void
AMRNavierStokes::computeAdvectionVelocities(LevelData<FluxBox>& a_advVel)
{
  if (s_verbosity >= 3)
    {
      pout() << "AMRNavierStokes::computeAdvectionVelocities: "
             << m_level << endl;
    }

  bool isViscous = (s_nu > 0.0);

  const DisjointBoxLayout& levelGrids = newVel().getBoxes();

  /// need to build grown grids to get be able to do all of
  /// tracing properly
  IntVect advect_grow(D_DECL(ADVECT_GROW, ADVECT_GROW, ADVECT_GROW));

  LevelData<FArrayBox> old_vel(levelGrids, SpaceDim, advect_grow);
  LevelData<FArrayBox> viscousSource(levelGrids, SpaceDim, advect_grow);
  LevelData<FArrayBox>* crseVelPtr = NULL;

  if (s_set_bogus_values)
    {
      setValLevel(old_vel, s_bogus_value);
      setValLevel(viscousSource, s_bogus_value);
    }

  // m_time contains the time at which the new state is centered
  Real old_time = m_time - m_dt;
  fillVelocity(old_vel, old_time);

  // set physical boundary conditions here
  // set physical boundary conditions on velocity

  if (isViscous)
    {
      LevelData<FArrayBox> viscousVel(levelGrids, SpaceDim, advect_grow);
      DataIterator dit = viscousVel.dataIterator();
      // rather than resetting BC's on old_vel, and then setting them
      // back, just copy old_vel to a temporary holder, and set
      // BCs on that one.
      for (dit.begin(); dit.ok(); ++dit)
        {
          viscousVel[dit].copy(old_vel[dit]);
        }
      VelBCHolder velBC(m_physBCPtr->viscousVelFuncBC());
      velBC.applyBCs(viscousVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

      // if crse level exists, fill coarse velocity BC
      if (m_level > 0)
        {
          const DisjointBoxLayout& crseGrids = crseNSPtr()->newVel().getBoxes();
          crseVelPtr = new LevelData<FArrayBox>(crseGrids, SpaceDim);
          crseNSPtr()->fillVelocity(*crseVelPtr, old_time);
        }

      computeLapVel(viscousSource, viscousVel, crseVelPtr);

      for (dit.reset(); dit.ok(); ++dit)
        {
          viscousSource[dit].mult(s_nu);
        }
    }
  else
    {
      setValLevel(viscousSource, 0.0);
    }

  // tracing will use inviscid BC's
  {
    VelBCHolder velBC(m_physBCPtr->tracingVelFuncBC());
    velBC.applyBCs(old_vel, levelGrids,
                   m_problem_domain, m_dx,
                   false); // inhomogeneous
  }

  // call utility function to do tracing
  traceAdvectionVel(a_advVel, old_vel, viscousSource,
                    m_patchGodVelocity, old_time, m_dt);

  EdgeVelBCHolder edgeVelBC(m_physBCPtr->advectionVelFuncBC(isViscous));
  edgeVelBC.applyBCs(a_advVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

  // noel  levelMacProject is big guy
  // now MAC project
  m_projection.levelMacProject(a_advVel, old_time, m_dt);

  // finally, add volume discrepancy correction
  if (m_projection.etaLambda() > 0 && s_applyFreestreamCorrection)
    {
      LevelData<FluxBox>& grad_e_Lambda = m_projection.grad_eLambda();

      DataIterator dit = levelGrids.dataIterator();
      for (dit.reset(); dit.ok(); ++dit)
        {
          FluxBox& thisGrad_eLambda = grad_e_Lambda[dit];
          FluxBox& thisAdvVel = a_advVel[dit];
          for (int dir=0; dir<SpaceDim; dir++)
            {
              thisAdvVel[dir] += thisGrad_eLambda[dir];
            }
        }
    }

  edgeVelBC.applyBCs(a_advVel, levelGrids,
                     m_problem_domain, m_dx,
                     false); // inhomogeneous

  // clean up storage
  if (crseVelPtr != NULL)
    {
      delete crseVelPtr;
      crseVelPtr = NULL;
    }
}
// -----------------------------------------------------------------------------
// This does the actual computation to update the state variables.
// I've included this function since the initializeGlobalPressure() and advance()
// functions are, for the most part, the same piece of code.
// -----------------------------------------------------------------------------
void AMRNavierStokes::PPMIGTimeStep (const Real a_oldTime,
                                     const Real a_dt,
                                     const bool a_updatePassiveScalars,
                                     const bool a_doLevelProj)
{
    CH_TIME("AMRNavierStokes::PPMIGTimeStep");
    pout() << setiosflags(ios::scientific) << setprecision(8) << flush;

    // Set up some basic values
    const RealVect& dx = m_levGeoPtr->getDx();
    const DisjointBoxLayout& grids = newVel().getBoxes();
    DataIterator dit = grids.dataIterator();
    const Box domainBox = m_problem_domain.domainBox();
    const bool isViscous = (s_nu > 0.0);

    // Initialize all flux registers
    if (!finestLevel()) {
        m_vel_flux_reg.setToZero();
        for (int comp = 0; comp < s_num_scal_comps; ++comp) {
            m_scal_fluxreg_ptrs[comp]->setToZero();
        }
        m_lambda_flux_reg.setToZero();
    }

    // Sanity checks
    CH_assert(m_levGeoPtr->getBoxes() == grids);
    CH_assert(m_levGeoPtr->getDomain() == m_problem_domain);
    CH_assert(Abs(a_oldTime - (m_time - a_dt)) < TIME_EPS);
    CH_assert(s_num_scal_comps <= 1);
    CH_assert(s_num_scal_comps > 0 || s_gravityMethod == ProblemContext::GravityMethod::NONE);

    // Reference new holders
    LevelData<FArrayBox>& new_vel = newVel();
    LevelData<FArrayBox>& new_lambda = newLambda();
    LevelData<FArrayBox> new_b;
    if (s_num_scal_comps > 0) {
        aliasLevelData(new_b, &(newScal(0)), Interval(0,0));
    }


    // Compute advecting velocities
    LevelData<FArrayBox> old_vel(grids, SpaceDim, m_tracingGhosts);
    fillVelocity(old_vel, a_oldTime);
    old_vel.exchange(m_tracingExCopier);

    LevelData<FluxBox> adv_vel(grids, 1, IntVect::Unit); // Changed from m_tracingGhosts to 1
    computeAdvectingVelocities(adv_vel, old_vel, a_oldTime, a_dt);

    if (a_updatePassiveScalars) {
        // Lambda update
        LevelData<FArrayBox> old_lambda;
        fillLambda(old_lambda, a_oldTime);
        old_lambda.exchange(m_tracingExCopier);

        LevelData<FArrayBox> dLdt(grids, 1);
        getNewLambda(dLdt, new_lambda, old_lambda, old_vel, adv_vel, a_oldTime, a_dt, a_dt);
    }

    LevelData<FArrayBox> old_b;
    if (s_num_scal_comps > 0) {
        // Scalar update
        fillScalars(old_b, a_oldTime, 0);
        old_b.exchange(m_tracingExCopier);

        LevelData<FArrayBox> dSdt(grids, 1);
        getNewScalar(dSdt, new_b, old_b, old_vel, adv_vel, a_oldTime, a_dt, a_dt, 0);
    }

    for (int comp = 1; comp < s_num_scal_comps; ++comp) {
        // Scalar update
        LevelData<FArrayBox> old_scal;
        fillScalars(old_scal, a_oldTime, comp);
        old_scal.exchange(m_tracingExCopier);

        LevelData<FArrayBox> dSdt(grids, 1);
        getNewScalar(dSdt, newScal(comp), old_scal, old_vel, adv_vel, a_oldTime, a_dt, a_dt, comp);
    }

    {   // Update CC velocities
        LevelData<FArrayBox> dUdt(grids, SpaceDim);
        getNewVelocity(dUdt, new_vel, old_vel, adv_vel, a_oldTime, a_dt, a_dt);
    }

    if (s_num_scal_comps > 0) {
        // Do implicit gravity update and CC projection.
        doCCIGProjection(new_vel, new_b, old_vel, old_b, adv_vel, a_oldTime, a_dt, a_doLevelProj);
    } else {
        // Do a standard CC projection.
        doCCProjection(new_vel, a_oldTime + a_dt, a_dt, a_doLevelProj);
    }
}