void BJacobiPreconditioner::initializeSolverState( const SAMRAIVectorReal<NDIM,double>& x, const SAMRAIVectorReal<NDIM,double>& 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(hierarchy == b.getPatchHierarchy()); TBOX_ASSERT(coarsest_ln == b.getCoarsestLevelNumber()); TBOX_ASSERT(finest_ln == b.getFinestLevelNumber()); TBOX_ASSERT(x.getNumberOfComponents() == b.getNumberOfComponents()); #endif // Initialize the component preconditioners. const std::string& x_name = x.getName(); const std::string& b_name = b.getName(); for (std::map<unsigned int,Pointer<LinearSolver> >::iterator it = d_pc_map.begin(); it != d_pc_map.end(); ++it) { const int comp = it->first; SAMRAIVectorReal<NDIM,double> x_comp(x_name+"_component", 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", hierarchy, coarsest_ln, finest_ln); b_comp.addComponent(b.getComponentVariable(comp), b.getComponentDescriptorIndex(comp), b.getControlVolumeIndex(comp)); d_pc_map[comp]->initializeSolverState(x_comp, b_comp); } // Indicate that the preconditioner is initialized. d_is_initialized = true; return; }// initializeSolverState
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
void INSStaggeredCenteredConvectiveOperator::initializeOperatorState( const SAMRAIVectorReal<NDIM, double>& in, const SAMRAIVectorReal<NDIM, double>& out) { IBAMR_TIMER_START(t_initialize_operator_state); if (d_is_initialized) deallocateOperatorState(); // Get the hierarchy configuration. d_hierarchy = in.getPatchHierarchy(); d_coarsest_ln = in.getCoarsestLevelNumber(); d_finest_ln = in.getFinestLevelNumber(); #if !defined(NDEBUG) TBOX_ASSERT(d_hierarchy == out.getPatchHierarchy()); TBOX_ASSERT(d_coarsest_ln == out.getCoarsestLevelNumber()); TBOX_ASSERT(d_finest_ln == out.getFinestLevelNumber()); #else NULL_USE(out); #endif // Setup the interpolation transaction information. typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; d_transaction_comps.resize(1); d_transaction_comps[0] = InterpolationTransactionComponent(d_U_scratch_idx, in.getComponentDescriptorIndex(0), "CONSERVATIVE_LINEAR_REFINE", false, "CONSERVATIVE_COARSEN", d_bdry_extrap_type, false, d_bc_coefs); // Initialize the interpolation operators. d_hier_bdry_fill = new HierarchyGhostCellInterpolation(); d_hier_bdry_fill->initializeOperatorState(d_transaction_comps, d_hierarchy); // Initialize the BC helper. d_bc_helper = new StaggeredStokesPhysicalBoundaryHelper(); d_bc_helper->cacheBcCoefData(d_bc_coefs, d_solution_time, d_hierarchy); // Allocate scratch data. for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); if (!level->checkAllocated(d_U_scratch_idx)) { level->allocatePatchData(d_U_scratch_idx); } } d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_operator_state); return; } // initializeOperatorState
void AdvDiffCenteredConvectiveOperator::initializeOperatorState(const SAMRAIVectorReal<NDIM, double>& in, const SAMRAIVectorReal<NDIM, double>& out) { IBAMR_TIMER_START(t_initialize_operator_state); if (d_is_initialized) deallocateOperatorState(); // Get the hierarchy configuration. d_hierarchy = in.getPatchHierarchy(); d_coarsest_ln = in.getCoarsestLevelNumber(); d_finest_ln = in.getFinestLevelNumber(); #if !defined(NDEBUG) TBOX_ASSERT(d_hierarchy == out.getPatchHierarchy()); TBOX_ASSERT(d_coarsest_ln == out.getCoarsestLevelNumber()); TBOX_ASSERT(d_finest_ln == out.getFinestLevelNumber()); #else NULL_USE(out); #endif Pointer<CartesianGridGeometry<NDIM> > grid_geom = d_hierarchy->getGridGeometry(); // Setup the coarsen algorithm, operator, and schedules. Pointer<CoarsenOperator<NDIM> > coarsen_op = grid_geom->lookupCoarsenOperator(d_q_flux_var, "CONSERVATIVE_COARSEN"); d_coarsen_alg = new CoarsenAlgorithm<NDIM>(); if (d_difference_form == ADVECTIVE || d_difference_form == SKEW_SYMMETRIC) d_coarsen_alg->registerCoarsen(d_q_extrap_idx, d_q_extrap_idx, coarsen_op); if (d_difference_form == CONSERVATIVE || d_difference_form == SKEW_SYMMETRIC) d_coarsen_alg->registerCoarsen(d_q_flux_idx, d_q_flux_idx, coarsen_op); d_coarsen_scheds.resize(d_finest_ln + 1); for (int ln = d_coarsest_ln + 1; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); Pointer<PatchLevel<NDIM> > coarser_level = d_hierarchy->getPatchLevel(ln - 1); d_coarsen_scheds[ln] = d_coarsen_alg->createSchedule(coarser_level, level); } // Setup the refine algorithm, operator, patch strategy, and schedules. Pointer<RefineOperator<NDIM> > refine_op = grid_geom->lookupRefineOperator(d_Q_var, "CONSERVATIVE_LINEAR_REFINE"); d_ghostfill_alg = new RefineAlgorithm<NDIM>(); d_ghostfill_alg->registerRefine(d_Q_scratch_idx, in.getComponentDescriptorIndex(0), d_Q_scratch_idx, refine_op); if (d_outflow_bdry_extrap_type != "NONE") d_ghostfill_strategy = new CartExtrapPhysBdryOp(d_Q_scratch_idx, d_outflow_bdry_extrap_type); d_ghostfill_scheds.resize(d_finest_ln + 1); for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(ln); d_ghostfill_scheds[ln] = d_ghostfill_alg->createSchedule(level, ln - 1, d_hierarchy, d_ghostfill_strategy); } d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_operator_state); return; } // initializeOperatorState
void FACPreconditioner::initializeSolverState( const SAMRAIVectorReal<NDIM,double>& solution, const SAMRAIVectorReal<NDIM,double>& rhs) { // Deallocate the solver state if the solver is already initialized. if (d_is_initialized) { deallocateSolverState(); } // Setup operator state. d_hierarchy = solution.getPatchHierarchy(); d_coarsest_ln = solution.getCoarsestLevelNumber(); d_finest_ln = solution.getFinestLevelNumber(); #ifdef DEBUG_CHECK_ASSERTIONS TBOX_ASSERT(d_hierarchy == rhs.getPatchHierarchy()); TBOX_ASSERT(d_coarsest_ln == rhs.getCoarsestLevelNumber()); TBOX_ASSERT(d_finest_ln == rhs.getFinestLevelNumber()); #endif d_fac_strategy->initializeOperatorState(solution, rhs); // Create temporary vectors. if (!(d_cycle_type == V_CYCLE && d_num_pre_sweeps == 0)) { d_f = rhs.cloneVector(""); d_f->allocateVectorData(); d_r = rhs.cloneVector(""); d_r->allocateVectorData(); } // Indicate the operator is initialized. d_is_initialized = true; return; }// initializeSolverState
bool FACPreconditioner::checkVectorStateCompatibility( const SAMRAIVectorReal<double>& solution, const SAMRAIVectorReal<double>& rhs) const { /* * It is an error when the state is not initialized. */ if (!d_patch_hierarchy) { TBOX_ERROR( d_object_name << ": cannot check vector-state\n" << "compatibility when the state is uninitialized.\n"); } bool rvalue = true; const SAMRAIVectorReal<double>& error = *d_error_vector; if (solution.getPatchHierarchy() != d_patch_hierarchy || rhs.getPatchHierarchy() != d_patch_hierarchy) { rvalue = false; } if (rvalue == true) { if (solution.getCoarsestLevelNumber() != d_coarsest_ln || rhs.getCoarsestLevelNumber() != d_coarsest_ln || solution.getFinestLevelNumber() != d_finest_ln || rhs.getFinestLevelNumber() != d_finest_ln) { rvalue = false; } } if (rvalue == true) { const int ncomp = error.getNumberOfComponents(); if (solution.getNumberOfComponents() != ncomp || rhs.getNumberOfComponents() != ncomp) { rvalue = false; } } return rvalue; }
void BGaussSeidelPreconditioner::initializeSolverState(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& b) { #if !defined(NDEBUG) Pointer<PatchHierarchy<NDIM> > hierarchy = x.getPatchHierarchy(); const int coarsest_ln = x.getCoarsestLevelNumber(); const int finest_ln = x.getFinestLevelNumber(); TBOX_ASSERT(hierarchy == b.getPatchHierarchy()); TBOX_ASSERT(coarsest_ln == b.getCoarsestLevelNumber()); TBOX_ASSERT(finest_ln == b.getFinestLevelNumber()); TBOX_ASSERT(x.getNumberOfComponents() == b.getNumberOfComponents()); #endif // Setup SAMRAIVectorReal objects to correspond to the individual vector // components. std::vector<Pointer<SAMRAIVectorReal<NDIM, double> > > x_comps = getComponentVectors(ConstPointer<SAMRAIVectorReal<NDIM, double> >(&x, false)); std::vector<Pointer<SAMRAIVectorReal<NDIM, double> > > b_comps = getComponentVectors(ConstPointer<SAMRAIVectorReal<NDIM, double> >(&b, false)); // Initialize the component operators and preconditioners. const int ncomps = x.getNumberOfComponents(); for (int comp = 0; comp < ncomps; ++comp) { for (int c = 0; c < ncomps; ++c) { // Skip the diagonal operators. if (c == comp) continue; d_linear_ops_map[comp][c]->initializeOperatorState(*x_comps[comp], *b_comps[comp]); } d_pc_map[comp]->initializeSolverState(*x_comps[comp], *b_comps[comp]); } // Indicate that the preconditioner is initialized. d_is_initialized = true; return; } // initializeSolverState
void StaggeredStokesOperator::initializeOperatorState(const SAMRAIVectorReal<NDIM, double>& in, const SAMRAIVectorReal<NDIM, double>& out) { IBAMR_TIMER_START(t_initialize_operator_state); // Deallocate the operator state if the operator is already initialized. if (d_is_initialized) deallocateOperatorState(); // Setup solution and rhs vectors. d_x = in.cloneVector(in.getName()); d_b = out.cloneVector(out.getName()); d_x->allocateVectorData(); // Setup the interpolation transaction information. d_U_fill_pattern = new SideNoCornersFillPattern(SIDEG, false, false, true); d_P_fill_pattern = new CellNoCornersFillPattern(CELLG, false, false, true); typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; d_transaction_comps.resize(2); d_transaction_comps[0] = InterpolationTransactionComponent(d_x->getComponentDescriptorIndex(0), in.getComponentDescriptorIndex(0), DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_U_bc_coefs, d_U_fill_pattern); d_transaction_comps[1] = InterpolationTransactionComponent(in.getComponentDescriptorIndex(1), DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_P_bc_coef, d_P_fill_pattern); // Initialize the interpolation operators. d_hier_bdry_fill = new HierarchyGhostCellInterpolation(); d_hier_bdry_fill->initializeOperatorState(d_transaction_comps, d_x->getPatchHierarchy()); // Initialize hierarchy math ops object. if (!d_hier_math_ops_external) { d_hier_math_ops = new HierarchyMathOps(d_object_name + "::HierarchyMathOps", in.getPatchHierarchy(), in.getCoarsestLevelNumber(), in.getFinestLevelNumber()); } #if !defined(NDEBUG) else { TBOX_ASSERT(d_hier_math_ops); } #endif // Indicate the operator is initialized. d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_operator_state); return; } // initializeOperatorState
void IBImplicitModHelmholtzOperator::apply( SAMRAIVectorReal<NDIM,double>& x, SAMRAIVectorReal<NDIM,double>& y) { IBAMR_TIMER_START(t_apply); SAMRAIVectorReal<NDIM,double> x_u(x.getName(), x.getPatchHierarchy(), x.getCoarsestLevelNumber(), x.getFinestLevelNumber()); x_u.addComponent(x.getComponentVariable(0), x.getComponentDescriptorIndex(0), x.getControlVolumeIndex(0)); SAMRAIVectorReal<NDIM,double> y_u(y.getName(), y.getPatchHierarchy(), y.getCoarsestLevelNumber(), y.getFinestLevelNumber()); y_u.addComponent(y.getComponentVariable(0), y.getComponentDescriptorIndex(0), y.getControlVolumeIndex(0)); // Apply the linear part of the operator with homogeneous boundary // conditions. d_helmholtz_op->apply(x_u, y_u); // Apply the nonlinear part of the operator. d_ib_SJSstar_op->applyAdd(x_u, y_u, y_u); IBAMR_TIMER_STOP(t_apply); return; }// apply
void IBImplicitModHelmholtzOperator::initializeOperatorState( const SAMRAIVectorReal<NDIM,double>& in, const SAMRAIVectorReal<NDIM,double>& out) { IBAMR_TIMER_START(t_initialize_operator_state); if (d_is_initialized) deallocateOperatorState(); SAMRAIVectorReal<NDIM,double> in_u(in.getName(), in.getPatchHierarchy(), in.getCoarsestLevelNumber(), in.getFinestLevelNumber()); in_u.addComponent(in.getComponentVariable(0), in.getComponentDescriptorIndex(0), in.getControlVolumeIndex(0)); SAMRAIVectorReal<NDIM,double> out_u(out.getName(), out.getPatchHierarchy(), out.getCoarsestLevelNumber(), out.getFinestLevelNumber()); out_u.addComponent(out.getComponentVariable(0), out.getComponentDescriptorIndex(0), out.getControlVolumeIndex(0)); d_helmholtz_op->initializeOperatorState(in_u, out_u); // d_ib_SJSstar_op->initializeOperatorState(in_u, out_u); d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_operator_state); return; }// initializeOperatorState
void IBImplicitModHelmholtzPETScLevelSolver::initializeSolverState( const SAMRAIVectorReal<NDIM,double>& x, const SAMRAIVectorReal<NDIM,double>& b) { IBAMR_TIMER_START(t_initialize_solver_state); // Rudimentary error checking. #ifdef DEBUG_CHECK_ASSERTIONS if (x.getNumberOfComponents() != b.getNumberOfComponents()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same number of components" << std::endl); } const Pointer<PatchHierarchy<NDIM> >& patch_hierarchy = x.getPatchHierarchy(); if (patch_hierarchy != b.getPatchHierarchy()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same hierarchy" << std::endl); } const int coarsest_ln = x.getCoarsestLevelNumber(); if (coarsest_ln < 0) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest level number must not be negative" << std::endl); } if (coarsest_ln != b.getCoarsestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same coarsest level number" << std::endl); } const int finest_ln = x.getFinestLevelNumber(); if (finest_ln < coarsest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " finest level number must be >= coarsest level number" << std::endl); } if (finest_ln != b.getFinestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same finest level number" << std::endl); } for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { if (patch_hierarchy->getPatchLevel(ln).isNull()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " hierarchy level " << ln << " does not exist" << std::endl); } } if (coarsest_ln != finest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest_ln != finest_ln in IBImplicitModHelmholtzPETScLevelSolver" << std::endl); } #endif // Deallocate the solver state if the solver is already initialized. if (d_is_initialized) deallocateSolverState(); // Get the hierarchy information. d_hierarchy = x.getPatchHierarchy(); d_level_num = x.getCoarsestLevelNumber(); #ifdef DEBUG_CHECK_ASSERTIONS TBOX_ASSERT(d_level_num == x.getFinestLevelNumber()); #endif const int x_idx = x.getComponentDescriptorIndex(0); Pointer<SideVariable<NDIM,double> > x_var = x.getComponentVariable(0); const int b_idx = b.getComponentDescriptorIndex(0); Pointer<SideVariable<NDIM,double> > b_var = b.getComponentVariable(0); // Allocate DOF index data. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); Pointer<SideDataFactory<NDIM,double> > x_fac = var_db->getPatchDescriptor()->getPatchDataFactory(x_idx); const int depth = x_fac->getDefaultDepth(); Pointer<SideDataFactory<NDIM,int> > dof_index_fac = var_db->getPatchDescriptor()->getPatchDataFactory(d_dof_index_idx); dof_index_fac->setDefaultDepth(depth); Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(d_level_num); if (!level->checkAllocated(d_dof_index_idx)) level->allocatePatchData(d_dof_index_idx); // Setup PETSc objects. int ierr; PETScVecUtilities::constructPatchLevelVec(d_petsc_x, x_idx, x_var, level); PETScVecUtilities::constructPatchLevelVec(d_petsc_b, b_idx, b_var, level); PETScVecUtilities::constructPatchLevelDOFIndices(d_dof_index_idx, d_dof_index_var, x_idx, x_var, level); const double C = d_poisson_spec.cIsZero() ? 0.0 : d_poisson_spec.getCConstant(); const double D = d_poisson_spec.getDConstant(); PETScMatUtilities::constructPatchLevelLaplaceOp(d_petsc_mat, C, D, x_idx, x_var, d_dof_index_idx, d_dof_index_var, level, d_dof_index_fill); if (d_SJR_mat != PETSC_NULL) { ierr = PETScMatOps::MatAXPY(d_petsc_mat, 1.0, d_SJR_mat); IBTK_CHKERRQ(ierr); } ierr = MatSetBlockSize(d_petsc_mat, NDIM); IBTK_CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD, &d_petsc_ksp); IBTK_CHKERRQ(ierr); ierr = KSPSetOperators(d_petsc_ksp, d_petsc_mat, d_petsc_mat, SAME_PRECONDITIONER); IBTK_CHKERRQ(ierr); if (!d_options_prefix.empty()) { ierr = KSPSetOptionsPrefix(d_petsc_ksp, d_options_prefix.c_str()); IBTK_CHKERRQ(ierr); } ierr = KSPSetFromOptions(d_petsc_ksp); IBTK_CHKERRQ(ierr); // Indicate that the solver is initialized. d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_solver_state); return; }// initializeSolverState
void FACPreconditioner::initializeSolverState( const SAMRAIVectorReal<double>& solution, const SAMRAIVectorReal<double>& rhs) { /* * First get rid of current data. */ deallocateSolverState(); /* * Set hierarchy and levels to solve. */ d_patch_hierarchy = solution.getPatchHierarchy(); d_coarsest_ln = solution.getCoarsestLevelNumber(); d_finest_ln = solution.getFinestLevelNumber(); /* * Set the solution-vector-dependent scratch space. */ d_error_vector = solution.cloneVector(d_object_name + "::error"); d_error_vector->allocateVectorData(); if (d_algorithm_choice == "mccormick-s4.3") { d_tmp_error = solution.cloneVector(d_object_name + "::temporary_error"); d_tmp_error->allocateVectorData(); } d_residual_vector = rhs.cloneVector(d_object_name + "::residual"); d_residual_vector->allocateVectorData(); d_tmp_residual = rhs.cloneVector(d_object_name + "::FAC coarser residual"); d_tmp_residual->allocateVectorData(); /* * Set the controlled level operators, which depend on the number * of components in the solution vector. */ math::HierarchyDataOpsManager* ops_manager = math::HierarchyDataOpsManager::getManager(); int num_components = solution.getNumberOfComponents(); d_controlled_level_ops.resize(num_components); for (int i = 0; i < num_components; ++i) { d_controlled_level_ops[i] = ops_manager->getOperationsDouble( solution.getComponentVariable(i), d_patch_hierarchy, true); /* * Note: the variable used above is only for the purpose of determining * the variable alignment on the grid. It is not specific to any * instance. */ } /* * Error checking. */ #ifdef DEBUG_CHECK_ASSERTIONS if (d_patch_hierarchy != rhs.getPatchHierarchy()) { TBOX_ERROR(d_object_name << ": vectors must have the same hierarchy.\n"); } if (d_coarsest_ln < 0) { TBOX_ERROR(d_object_name << ": coarsest level must not be negative.\n"); } if (d_coarsest_ln > d_finest_ln) { TBOX_ERROR(d_object_name << ": coarsest level must be <= finest" << "level.\n"); } #endif for (int ln = d_coarsest_ln; ln <= d_finest_ln; ++ln) { if (!d_patch_hierarchy->getPatchLevel(ln)) { TBOX_ERROR("FACPreconditioner::initializeSolverState error ..." << "\n object name = " << d_object_name << "\n hierarchy level " << ln << " does not exist" << std::endl); } } d_fac_operator->initializeOperatorState(solution, rhs); }
void PETScNewtonKrylovSolver::initializeSolverState(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& b) { IBTK_TIMER_START(t_initialize_solver_state); int ierr; // Rudimentary error checking. #if !defined(NDEBUG) if (x.getNumberOfComponents() != b.getNumberOfComponents()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same number of components" << std::endl); } const Pointer<PatchHierarchy<NDIM> >& patch_hierarchy = x.getPatchHierarchy(); if (patch_hierarchy != b.getPatchHierarchy()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same hierarchy" << std::endl); } const int coarsest_ln = x.getCoarsestLevelNumber(); if (coarsest_ln < 0) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest level number must not be negative" << std::endl); } if (coarsest_ln != b.getCoarsestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same coarsest level number" << std::endl); } const int finest_ln = x.getFinestLevelNumber(); if (finest_ln < coarsest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " finest level number must be >= coarsest level number" << std::endl); } if (finest_ln != b.getFinestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same finest level number" << std::endl); } for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { if (!patch_hierarchy->getPatchLevel(ln)) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " hierarchy level " << ln << " does not exist" << std::endl); } } #endif // Deallocate the solver state if the solver is already initialized. if (d_is_initialized) { d_reinitializing_solver = true; deallocateSolverState(); } // Create the SNES solver. if (d_managing_petsc_snes) { ierr = SNESCreate(d_petsc_comm, &d_petsc_snes); IBTK_CHKERRQ(ierr); resetSNESOptions(); } else if (!d_petsc_snes) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " cannot initialize solver state for wrapped PETSc SNES " "object if the wrapped object is NULL" << std::endl); } // Setup solution and rhs vectors. d_x = x.cloneVector(x.getName()); d_petsc_x = PETScSAMRAIVectorReal::createPETScVector(d_x, d_petsc_comm); d_b = b.cloneVector(b.getName()); d_petsc_b = PETScSAMRAIVectorReal::createPETScVector(d_b, d_petsc_comm); d_r = b.cloneVector(b.getName()); d_petsc_r = PETScSAMRAIVectorReal::createPETScVector(d_r, d_petsc_comm); // Setup the nonlinear operator. if (d_F) d_F->initializeOperatorState(*d_x, *d_b); if (d_managing_petsc_snes || d_user_provided_function) resetSNESFunction(); // Setup the Jacobian. if (d_J) d_J->initializeOperatorState(*d_x, *d_b); if (d_managing_petsc_snes || d_user_provided_jacobian) resetSNESJacobian(); // Set the SNES options from the PETSc options database. if (d_options_prefix != "") { ierr = SNESSetOptionsPrefix(d_petsc_snes, d_options_prefix.c_str()); IBTK_CHKERRQ(ierr); } ierr = SNESSetFromOptions(d_petsc_snes); IBTK_CHKERRQ(ierr); // Reset the member state variables to correspond to the values used by the // SNES object. (Command-line options always take precedence.) ierr = SNESGetTolerances(d_petsc_snes, &d_abs_residual_tol, &d_rel_residual_tol, &d_solution_tol, &d_max_iterations, &d_max_evaluations); IBTK_CHKERRQ(ierr); // Setup the KrylovLinearSolver wrapper to correspond to the KSP employed by // the SNES solver. KSP petsc_ksp; ierr = SNESGetKSP(d_petsc_snes, &petsc_ksp); IBTK_CHKERRQ(ierr); Pointer<PETScKrylovLinearSolver> p_krylov_solver = d_krylov_solver; if (p_krylov_solver) p_krylov_solver->resetWrappedKSP(petsc_ksp); // Setup the Krylov solver. if (d_krylov_solver) d_krylov_solver->initializeSolverState(*d_x, *d_b); // Indicate that the solver is initialized. d_reinitializing_solver = false; d_is_initialized = true; IBTK_TIMER_STOP(t_initialize_solver_state); return; } // initializeSolverState
void CCDivGradHypreLevelSolver::initializeSolverState( const SAMRAIVectorReal<NDIM,double>& x, const SAMRAIVectorReal<NDIM,double>& b) { IBTK_TIMER_START(t_initialize_solver_state); // Rudimentary error checking. #ifdef DEBUG_CHECK_ASSERTIONS if (x.getNumberOfComponents() != b.getNumberOfComponents()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same number of components" << std::endl); } const Pointer<PatchHierarchy<NDIM> >& patch_hierarchy = x.getPatchHierarchy(); if (patch_hierarchy != b.getPatchHierarchy()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same hierarchy" << std::endl); } const int coarsest_ln = x.getCoarsestLevelNumber(); if (coarsest_ln < 0) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest level number must not be negative" << std::endl); } if (coarsest_ln != b.getCoarsestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same coarsest level number" << std::endl); } const int finest_ln = x.getFinestLevelNumber(); if (finest_ln < coarsest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " finest level number must be >= coarsest level number" << std::endl); } if (finest_ln != b.getFinestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same finest level number" << std::endl); } for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { if (patch_hierarchy->getPatchLevel(ln).isNull()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " hierarchy level " << ln << " does not exist" << std::endl); } } if (coarsest_ln != finest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest_ln != finest_ln in CCDivGradHypreLevelSolver" << std::endl); } #else NULL_USE(b); #endif // Deallocate the solver state if the solver is already initialized. if (d_is_initialized) deallocateSolverState(); // Get the hierarchy information. d_hierarchy = x.getPatchHierarchy(); d_level_num = x.getCoarsestLevelNumber(); // Allocate and initialize the hypre data structures. allocateHypreData(); setMatrixCoefficients(); setupHypreSolver(); // Indicate that the solver is initialized. d_is_initialized = true; IBTK_TIMER_STOP(t_initialize_solver_state); return; }// initializeSolverState
void PETScKrylovLinearSolver::initializeSolverState(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& b) { IBTK_TIMER_START(t_initialize_solver_state); int ierr; // Rudimentary error checking. #if !defined(NDEBUG) if (x.getNumberOfComponents() != b.getNumberOfComponents()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same number of components" << std::endl); } const Pointer<PatchHierarchy<NDIM> >& patch_hierarchy = x.getPatchHierarchy(); if (patch_hierarchy != b.getPatchHierarchy()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have the same hierarchy" << std::endl); } const int coarsest_ln = x.getCoarsestLevelNumber(); if (coarsest_ln < 0) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " coarsest level number must not be negative" << std::endl); } if (coarsest_ln != b.getCoarsestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same coarsest level number" << std::endl); } const int finest_ln = x.getFinestLevelNumber(); if (finest_ln < coarsest_ln) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " finest level number must be >= coarsest level number" << std::endl); } if (finest_ln != b.getFinestLevelNumber()) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " vectors must have same finest level number" << std::endl); } for (int ln = coarsest_ln; ln <= finest_ln; ++ln) { if (!patch_hierarchy->getPatchLevel(ln)) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " hierarchy level " << ln << " does not exist" << std::endl); } } #endif // Deallocate the solver state if the solver is already initialized. if (d_is_initialized) { d_reinitializing_solver = true; deallocateSolverState(); } // Create the KSP solver. if (d_managing_petsc_ksp) { ierr = KSPCreate(d_petsc_comm, &d_petsc_ksp); IBTK_CHKERRQ(ierr); resetKSPOptions(); } else if (!d_petsc_ksp) { TBOX_ERROR(d_object_name << "::initializeSolverState()\n" << " cannot initialize solver state for wrapped PETSc KSP object " "if the wrapped object is NULL" << std::endl); } // Setup solution and rhs vectors. d_x = x.cloneVector(x.getName()); d_petsc_x = PETScSAMRAIVectorReal::createPETScVector(d_x, d_petsc_comm); d_b = b.cloneVector(b.getName()); d_petsc_b = PETScSAMRAIVectorReal::createPETScVector(d_b, d_petsc_comm); // Initialize the linear operator and preconditioner objects. if (d_A) d_A->initializeOperatorState(*d_x, *d_b); if (d_managing_petsc_ksp || d_user_provided_mat) resetKSPOperators(); if (d_pc_solver) d_pc_solver->initializeSolverState(*d_x, *d_b); if (d_managing_petsc_ksp || d_user_provided_pc) resetKSPPC(); // Set the KSP options from the PETSc options database. if (d_options_prefix != "") { ierr = KSPSetOptionsPrefix(d_petsc_ksp, d_options_prefix.c_str()); IBTK_CHKERRQ(ierr); } ierr = KSPSetFromOptions(d_petsc_ksp); IBTK_CHKERRQ(ierr); // Reset the member state variables to correspond to the values used by the // KSP object. (Command-line options always take precedence.) const char* ksp_type; ierr = KSPGetType(d_petsc_ksp, &ksp_type); IBTK_CHKERRQ(ierr); d_ksp_type = ksp_type; PetscBool initial_guess_nonzero; ierr = KSPGetInitialGuessNonzero(d_petsc_ksp, &initial_guess_nonzero); IBTK_CHKERRQ(ierr); d_initial_guess_nonzero = (initial_guess_nonzero == PETSC_TRUE); ierr = KSPGetTolerances( d_petsc_ksp, &d_rel_residual_tol, &d_abs_residual_tol, NULL, &d_max_iterations); IBTK_CHKERRQ(ierr); // Configure the nullspace object. resetKSPNullspace(); // Indicate that the solver is initialized. d_reinitializing_solver = false; d_is_initialized = true; IBTK_TIMER_STOP(t_initialize_solver_state); return; } // initializeSolverState
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