// --------------------------------------------------------------- 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); } }