bool BJacobiPreconditioner::solveSystem( SAMRAIVectorReal<NDIM,double>& x, SAMRAIVectorReal<NDIM,double>& b) { // Initialize the preconditioner, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(x,b); Pointer<PatchHierarchy<NDIM> > hierarchy = x.getPatchHierarchy(); const int coarsest_ln = x.getCoarsestLevelNumber(); const int finest_ln = x.getFinestLevelNumber() ; #ifdef DEBUG_CHECK_ASSERTIONS TBOX_ASSERT(x.getNumberOfComponents() == b.getNumberOfComponents()); TBOX_ASSERT(hierarchy == b.getPatchHierarchy()); TBOX_ASSERT(coarsest_ln == b.getCoarsestLevelNumber()); TBOX_ASSERT( finest_ln == b.getFinestLevelNumber() ); #endif const std::string& x_name = x.getName(); const std::string& b_name = b.getName(); bool ret_val = true; // Zero out the initial guess. #ifdef DEBUG_CHECK_ASSERTIONS TBOX_ASSERT(d_initial_guess_nonzero == false); #endif x.setToScalar(0.0, /*interior_only*/ false); for (int comp = 0; comp < x.getNumberOfComponents(); ++comp) { // Setup a SAMRAIVectorReal to correspond to the individual vector // component. std::ostringstream str; str << comp; SAMRAIVectorReal<NDIM,double> x_comp(x_name+"_component_"+str.str(), hierarchy, coarsest_ln, finest_ln); x_comp.addComponent(x.getComponentVariable(comp), x.getComponentDescriptorIndex(comp), x.getControlVolumeIndex(comp)); SAMRAIVectorReal<NDIM,double> b_comp(b_name+"_component_"+str.str(), hierarchy, coarsest_ln, finest_ln); b_comp.addComponent(b.getComponentVariable(comp), b.getComponentDescriptorIndex(comp), b.getControlVolumeIndex(comp)); // Configure the component preconditioner. Pointer<LinearSolver> pc_comp = d_pc_map[comp]; pc_comp->setInitialGuessNonzero(d_initial_guess_nonzero); pc_comp->setMaxIterations(d_max_iterations); pc_comp->setAbsoluteTolerance(d_abs_residual_tol); pc_comp->setRelativeTolerance(d_rel_residual_tol); // Apply the component preconditioner. const bool ret_val_comp = pc_comp->solveSystem(x_comp, b_comp); ret_val = ret_val && ret_val_comp; } // Deallocate the preconditioner, when necessary. if (deallocate_after_solve) deallocateSolverState(); return ret_val; }// solveSystem
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
bool BGaussSeidelPreconditioner::solveSystem(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& b) { // Initialize the preconditioner, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(x, b); #if !defined(NDEBUG) Pointer<PatchHierarchy<NDIM> > hierarchy = x.getPatchHierarchy(); const int coarsest_ln = x.getCoarsestLevelNumber(); const int finest_ln = x.getFinestLevelNumber(); TBOX_ASSERT(x.getNumberOfComponents() == b.getNumberOfComponents()); TBOX_ASSERT(hierarchy == b.getPatchHierarchy()); TBOX_ASSERT(coarsest_ln == b.getCoarsestLevelNumber()); TBOX_ASSERT(finest_ln == b.getFinestLevelNumber()); #endif bool ret_val = true; // Zero out the initial guess. #if !defined(NDEBUG) TBOX_ASSERT(d_initial_guess_nonzero == false); #endif x.setToScalar(0.0, /*interior_only*/ false); // Setup SAMRAIVectorReal objects to correspond to the individual vector // components. std::vector<Pointer<SAMRAIVectorReal<NDIM, double> > > x_comps = getComponentVectors(Pointer<SAMRAIVectorReal<NDIM, double> >(&x, false)); std::vector<Pointer<SAMRAIVectorReal<NDIM, double> > > b_comps = getComponentVectors(Pointer<SAMRAIVectorReal<NDIM, double> >(&b, false)); // Clone the right-hand-side vector to avoid modifying it during the // preconditioning operation. Pointer<SAMRAIVectorReal<NDIM, double> > f = b.cloneVector(b.getName()); f->allocateVectorData(); f->copyVector(Pointer<SAMRAIVectorReal<NDIM, double> >(&b, false), false); std::vector<Pointer<SAMRAIVectorReal<NDIM, double> > > f_comps = getComponentVectors(f); // Setup the order in which the component preconditioner are to be applied. const int ncomps = x.getNumberOfComponents(); std::vector<int> comps; comps.reserve(2 * ncomps - 1); if (!d_reverse_order) { // Standard order: Run from comp = 0 to comp = ncomp-1. for (int comp = 0; comp < ncomps; ++comp) { comps.push_back(comp); } if (d_symmetric_preconditioner) { for (int comp = ncomps - 2; comp >= 0; --comp) { comps.push_back(comp); } } } else { // Reversed order: Run from comp = ncomp-1 to comp = 0. for (int comp = ncomps - 1; comp >= 0; --comp) { comps.push_back(comp); } if (d_symmetric_preconditioner) { for (int comp = 1; comp < ncomps; ++comp) { comps.push_back(comp); } } } // Apply the component preconditioners. int count = 0; for (std::vector<int>::const_iterator it = comps.begin(); it != comps.end(); ++it, ++count) { const int comp = (*it); Pointer<SAMRAIVectorReal<NDIM, double> > x_comp = x_comps[comp]; Pointer<SAMRAIVectorReal<NDIM, double> > b_comp = b_comps[comp]; Pointer<SAMRAIVectorReal<NDIM, double> > f_comp = f_comps[comp]; // Update the right-hand-side vector. f_comp->setToScalar(0.0); for (int c = 0; c < ncomps; ++c) { if (c == comp) continue; d_linear_ops_map[comp][c]->applyAdd(*x_comps[c], *f_comp, *f_comp); } f_comp->subtract(b_comp, f_comp); // Configure the component preconditioner. Pointer<LinearSolver> pc_comp = d_pc_map[comp]; pc_comp->setInitialGuessNonzero(count >= ncomps); pc_comp->setMaxIterations(d_max_iterations); pc_comp->setAbsoluteTolerance(d_abs_residual_tol); pc_comp->setRelativeTolerance(d_rel_residual_tol); // Apply the component preconditioner. const bool ret_val_comp = pc_comp->solveSystem(*x_comp, *f_comp); ret_val = ret_val && ret_val_comp; } // Free the copied right-hand-side vector data. f->deallocateVectorData(); f->freeVectorComponents(); // Deallocate the preconditioner, when necessary. if (deallocate_after_solve) deallocateSolverState(); return ret_val; } // solveSystem