// ----------------------------------------------------------------------------- // 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); } }
// --------------------------------------------------------------- // advance solution by one timestep // return max safe timestep Real AMRNavierStokes::advance() { if (s_verbosity >= 2) { pout () << "AMRNavierStokes::advance " << m_level << ", starting time = " << setiosflags(ios::fixed) << setprecision(6) << setw(12) << m_time << ", dt = " << setiosflags(ios::fixed) << setprecision(6) << setw(12) << dt() << endl; } #ifdef DEBUG // if we're at the beginning of a composite timestep, // save current multilevel state if (m_level == 0) { AMRNavierStokes* levelPtr = this; // figure out finest level while (!levelPtr->finestLevel()) { levelPtr = levelPtr->finerNSPtr(); } int finest_level = levelPtr->m_level; levelPtr = this; for (int lev=0; lev<= finest_level; lev++) { levelPtr->m_saved_time = m_time; levelPtr->newVel().copyTo(levelPtr->newVel().interval(), *levelPtr->m_vel_save_ptr, levelPtr->m_vel_save_ptr->interval()); levelPtr->newLambda().copyTo(levelPtr->newLambda().interval(), *levelPtr->m_lambda_save_ptr, levelPtr->m_lambda_save_ptr->interval()); for (int comp=0; comp<s_num_scal_comps; comp++) { levelPtr->newScal(comp).copyTo(levelPtr->newScal(comp).interval(), *levelPtr->m_scal_save[comp], levelPtr->m_scal_save[comp]->interval()); } levelPtr = levelPtr->finerNSPtr(); } } #endif Real old_time = m_time; Real new_time = m_time + m_dt; m_dt_save = m_dt; swapOldAndNewStates(); const DisjointBoxLayout levelGrids = newVel().getBoxes(); // initialize flux registers if (!finestLevel()) { m_flux_register.setToZero(); for (int comp=0; comp<s_num_scal_comps; comp++) { m_scal_fluxreg_ptrs[comp]->setToZero(); } m_lambda_flux_reg.setToZero(); } // compute advection velocities -- if we're using the // patchGodunov approach, these will have ghost cells. IntVect advVelGhost(IntVect::Unit); LevelData<FluxBox> advectionVel(levelGrids, 1, advVelGhost); if (s_set_bogus_values) { setValLevel(advectionVel, s_bogus_value); } computeAdvectionVelocities(advectionVel); // now that advection velocities have been computed, // update advected scalars // do scalar boundary conditions on lambda // (also grow to appropriate size) LevelData<FArrayBox> lambdaTemp; fillLambda(lambdaTemp, old_time); LevelFluxRegister* crseLambdaFluxRegPtr = NULL; if (m_level > 0) { crseLambdaFluxRegPtr = &(crseNSPtr()->m_lambda_flux_reg); } advectScalar(newLambda(), lambdaTemp, advectionVel, crseLambdaFluxRegPtr, m_lambda_flux_reg, m_patchGodLambda, m_dt); // now do advected-diffused scalars if (s_num_scal_comps > 0) { // loop over scalar components for (int comp=0; comp<s_num_scal_comps; comp++) { BCHolder scalPhysBCs = m_physBCPtr->scalarTraceFuncBC(comp); LevelData<FArrayBox> scalarTemp; fillScalars(scalarTemp, old_time,comp); // now get coarse-level scalars for BC's if necessary LevelData<FArrayBox>* newCrseScalPtr = NULL; LevelData<FArrayBox>* oldCrseScalPtr = NULL; Real oldCrseTime = -s_bogus_value; Real newCrseTime = s_bogus_value; LevelFluxRegister* crseScalFluxRegPtr = NULL; if (m_level > 0) { newCrseScalPtr = &(crseNSPtr()->newScal(comp)); oldCrseScalPtr = &(crseNSPtr()->oldScal(comp)); newCrseTime = crseNSPtr()->time(); oldCrseTime = newCrseTime - crseNSPtr()->dt(); crseScalFluxRegPtr = (crseNSPtr()->m_scal_fluxreg_ptrs[comp]); } advectDiffuseScalar(newScal(comp), scalarTemp, advectionVel, s_scal_coeffs[comp], oldCrseScalPtr, newCrseScalPtr, oldCrseTime, newCrseTime, crseScalFluxRegPtr, *(m_scal_fluxreg_ptrs[comp]), *(m_patchGodScalars[comp]), scalPhysBCs, m_dt, comp); } // end loop over components } // end advected-diffused scalars // now predict velocities -- this returns the advection term // put this in "new_vel" LevelData<FArrayBox>& uStar = newVel(); predictVelocities(uStar, advectionVel); computeUStar(uStar); // if a coarser level exists, will need coarse-level data for proj LevelData<FArrayBox>* crseVelPtr = NULL; if (m_level > 0) { const DisjointBoxLayout& crseGrids = crseNSPtr()->newVel().getBoxes(); crseVelPtr = new LevelData<FArrayBox>(crseGrids, SpaceDim); // coarse velocity BC data is interpolated in time crseNSPtr()->fillVelocity(*crseVelPtr, new_time); } // need to do physical boundary conditions and exchanges bool isViscous = (s_nu > 0); VelBCHolder velBC(m_physBCPtr->uStarFuncBC(isViscous)); velBC.applyBCs(uStar, levelGrids, m_problem_domain, m_dx, false); // inhomogeneous // noel -- all time in level project m_projection.LevelProject(uStar, crseVelPtr, new_time, m_dt); // as things stand now, physical BC's are re-set in LevelProjection // compute maximum safe timestep for next iteration Real newDt = computeDt(); // clean up temp storage if (crseVelPtr != NULL) { delete crseVelPtr; crseVelPtr = NULL; } ++m_level_steps; if (s_verbosity >= 2) { pout () << "AMRNavierStokes::advance " << m_level << ", end time = " << setiosflags(ios::fixed) << setprecision(6) << setw(12) << m_time << ", dt = " << setiosflags(ios::fixed) << setprecision(6) << setw(12) << dt() << endl; } return newDt; }
sExpression *eval(sExpression *exp, sEnvironment *env){ /* ------------------atom-----------------------*/ /* 1, 10, false, null, "abc" */ if(isSelfEval(exp)) { return exp; } /* a symbol */ else if(isVariable(exp, env)) { return lookupVariable(toSymb(exp), env); } /* ------------------list-----------------------*/ /* (quote blur blur) */ else if(isQuoted(exp)) { return textOfQuoted(exp); } /* (set! name value) */ else if(isAssignment(exp)) { return evalAssignment(exp, env); } /* (define name value) */ else if(isDefinition(exp)) { return evalDefine(exp, env); } /* (define-syntax name ...) */ else if(isDefinitionSyntax(exp)) { return evalDefineSyntax(exp, env); } /* (if blur blur blur) */ else if(isIf(exp)) { return evalIf(toList(exp), env); } /* (lambda (args) (body)) */ else if(isLambdaConst(exp)) { sList *body; sList *param = toList( cadr(toList(exp))); sExpression *temp = cdr(toList( cdr(toList(exp)))); if(isList(temp)){ body = toList(temp); }else{ body = toList(cons(temp, &sNull)); } return newLambda(param, body, env); } /* (syntax blur blur) syntax rule */ else if(isSymbol(car(toList(exp))) && isSyntaxRule(eval(car(toList(exp)), env))) { sExpression *exp2 = evalSyntaxRule(toSyntax(eval(car(toList(exp)), env)), exp); return eval(exp2, env); } /* the other list (x . y) */ else if(isApplication(exp)) { if(LAZY_EVAL){ sExpression *proexp = actualValue(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); return applyLazly(proexp, operand, env); } }else{ sExpression *proexp = eval(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); sExpression *arguments = listOfValues(operand, env); return apply(proexp, arguments, env); } } } return &sError; }