void FACPreconditioner::FACVCycleNoPreSmoothing( SAMRAIVectorReal<NDIM,double>& u, SAMRAIVectorReal<NDIM,double>& f, int level_num) { if (level_num == d_coarsest_ln) { // Solve Au = f on the coarsest level. d_fac_strategy->solveCoarsestLevel(u, f, level_num); } else { // Restrict the residual to the next coarser level. d_fac_strategy->restrictResidual(f, f, level_num-1); // Recursively call the FAC algorithm. FACVCycleNoPreSmoothing(u, f, level_num-1); // Prolong the error from the next coarser level and correct the // solution on the current level. d_fac_strategy->prolongErrorAndCorrect(u, u, level_num); // Smooth error on the current level. if (d_num_post_sweeps > 0) { d_fac_strategy->smoothError(u, f, level_num, d_num_post_sweeps, false, true); } } return; }// FACVCycleNoPreSmoothing
bool FACPreconditioner::solveSystem( SAMRAIVectorReal<NDIM,double>& u, SAMRAIVectorReal<NDIM,double>& f) { // Initialize the solver, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(u,f); // Set the initial guess to equal zero. u.setToScalar(0.0, /*interior_only*/ false); // Keep track of whether we need to (re-)compute the residual. Because u is // initialized to equal zero, the initial residual is precisely the // right-hand-side vector f. We only need to recompute the residual once we // start modifying the solution vector u. d_recompute_residual = false; // Apply a single FAC cycle. if (d_cycle_type == V_CYCLE && d_num_pre_sweeps == 0) { // V-cycle MG without presmoothing keeps the residual equal to the // initial right-hand-side vector f, so we can simply use that vector // for the residual in the FAC algorithm. FACVCycleNoPreSmoothing(u, f, d_finest_ln); } else { d_f->copyVector(Pointer<SAMRAIVectorReal<NDIM,double> >(&f, false), false); d_r->copyVector(Pointer<SAMRAIVectorReal<NDIM,double> >(&f, false), false); switch (d_cycle_type) { case V_CYCLE: FACVCycle(u, *d_f, d_finest_ln); break; case W_CYCLE: FACWCycle(u, *d_f, d_finest_ln); break; case F_CYCLE: FACFCycle(u, *d_f, d_finest_ln); break; default: TBOX_ERROR(d_object_name << "::solveSystem():\n" << " unrecognized FAC cycle type: " << enum_to_string<MGCycleType>(d_cycle_type) << "." << std::endl); } } // Deallocate the solver, when necessary. if (deallocate_after_solve) deallocateSolverState(); return true; }// solveSystem