void INSStaggeredVCStokesOperator::modifyRhsForInhomogeneousBc( SAMRAIVectorReal<NDIM,double>& y) { // Set y := y - A*0, i.e., shift the right-hand-side vector to account for // inhomogeneous boundary conditions. if (!d_homogeneous_bc) { d_correcting_rhs = true; Pointer<SAMRAIVectorReal<NDIM,double> > x = y.cloneVector(""); x->allocateVectorData(); x->setToScalar(0.0); Pointer<SAMRAIVectorReal<NDIM,double> > b = y.cloneVector(""); b->allocateVectorData(); b->setToScalar(0.0); apply(*x,*b); y.subtract(Pointer<SAMRAIVectorReal<NDIM,double> >(&y, false), b); x->freeVectorComponents(); x.setNull(); b->freeVectorComponents(); b.setNull(); d_correcting_rhs = false; } return; }// modifyRhsForInhomogeneousBc
void CCPoissonPETScLevelSolver::setupKSPVecs(Vec& petsc_x, Vec& petsc_b, SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& b, Pointer<PatchLevel<NDIM> > patch_level) { if (!d_initial_guess_nonzero) copyToPETScVec(petsc_x, x, patch_level); const int b_idx = b.getComponentDescriptorIndex(0); Pointer<CellVariable<NDIM, double> > b_var = b.getComponentVariable(0); VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); int b_adj_idx = var_db->registerClonedPatchDataIndex(b_var, b_idx); patch_level->allocatePatchData(b_adj_idx); for (PatchLevel<NDIM>::Iterator p(patch_level); p; p++) { Pointer<Patch<NDIM> > patch = patch_level->getPatch(p()); Pointer<CellData<NDIM, double> > b_data = patch->getPatchData(b_idx); Pointer<CellData<NDIM, double> > b_adj_data = patch->getPatchData(b_adj_idx); b_adj_data->copy(*b_data); if (!patch->getPatchGeometry()->intersectsPhysicalBoundary()) continue; PoissonUtilities::adjustCCBoundaryRhsEntries( patch, *b_adj_data, d_poisson_spec, d_bc_coefs, d_solution_time, d_homogeneous_bc); } PETScVecUtilities::copyToPatchLevelVec(petsc_b, b_adj_idx, d_dof_index_idx, patch_level); patch_level->deallocatePatchData(b_adj_idx); var_db->removePatchDataIndex(b_adj_idx); return; } // setupKSPVecs
bool IBImplicitModHelmholtzPETScLevelSolver::solveSystem( SAMRAIVectorReal<NDIM,double>& x, SAMRAIVectorReal<NDIM,double>& b) { IBAMR_TIMER_START(t_solve_system); int ierr; if (d_enable_logging) plog << d_object_name << "::solveSystem():" << std::endl; // Initialize the solver, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(x,b); #if 0 // XXXX // Configure solver. ierr = KSPSetTolerances(d_petsc_ksp, d_rel_residual_tol, d_abs_residual_tol, PETSC_DEFAULT, d_max_iterations); IBTK_CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(d_petsc_ksp, d_initial_guess_nonzero ? PETSC_TRUE : PETSC_FALSE); IBTK_CHKERRQ(ierr); #endif // Solve the system. Pointer<PatchLevel<NDIM> > patch_level = d_hierarchy->getPatchLevel(d_level_num); 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); if (d_initial_guess_nonzero) PETScVecUtilities::copyToPatchLevelVec(d_petsc_x, x_idx, x_var, patch_level); PETScVecUtilities::copyToPatchLevelVec(d_petsc_b, b_idx, b_var, patch_level); PETScVecUtilities::constrainPatchLevelVec(d_petsc_b, d_dof_index_idx, d_dof_index_var, patch_level, d_dof_index_fill); ierr = KSPSolve(d_petsc_ksp, d_petsc_b, d_petsc_x); IBTK_CHKERRQ(ierr); PETScVecUtilities::copyFromPatchLevelVec(d_petsc_x, x_idx, x_var, patch_level); typedef SideDataSynchronization::SynchronizationTransactionComponent SynchronizationTransactionComponent; // XXXX SynchronizationTransactionComponent x_synch_transaction = SynchronizationTransactionComponent(x_idx, "CONSERVATIVE_COARSEN"); Pointer<SideDataSynchronization> side_synch_op = new SideDataSynchronization(); side_synch_op->initializeOperatorState(x_synch_transaction, x.getPatchHierarchy()); side_synch_op->synchronizeData(0.0); // Log solver info. KSPConvergedReason reason; ierr = KSPGetConvergedReason(d_petsc_ksp, &reason); IBTK_CHKERRQ(ierr); const bool converged = reason > 0; if (d_enable_logging) { plog << d_object_name << "::solveSystem(): solver " << (converged ? "converged" : "diverged") << "\n" << "iterations = " << d_current_its << "\n" << "residual norm = " << d_current_residual_norm << std::endl; } // Deallocate the solver, when necessary. if (deallocate_after_solve) deallocateSolverState(); IBAMR_TIMER_STOP(t_solve_system); return converged; }// solveSystem
void ConvectiveOperator::apply(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& y) { // Get the vector components. const int Q_idx = x.getComponentDescriptorIndex(0); const int N_idx = y.getComponentDescriptorIndex(0); // Compute the action of the operator. applyConvectiveOperator(Q_idx, N_idx); return; } // apply
void PETScSNESFunctionGOWrapper::initializeOperatorState(const SAMRAIVectorReal<NDIM, double>& in, const SAMRAIVectorReal<NDIM, double>& out) { if (d_is_initialized) deallocateOperatorState(); d_x = in.cloneVector(""); d_y = out.cloneVector(""); MPI_Comm comm; int ierr = PetscObjectGetComm(reinterpret_cast<PetscObject>(d_petsc_snes), &comm); IBTK_CHKERRQ(ierr); d_petsc_x = PETScSAMRAIVectorReal::createPETScVector(d_x, comm); d_petsc_y = PETScSAMRAIVectorReal::createPETScVector(d_y, comm); d_is_initialized = true; return; } // initializeOperatorState
Pointer<SAMRAIVectorReal<NDIM,double> > FACPreconditionerStrategy::getLevelSAMRAIVectorReal( const SAMRAIVectorReal<NDIM,double>& vec, int level_num) const { std::ostringstream name_str; name_str << vec.getName() << "::level_" << level_num; Pointer<SAMRAIVectorReal<NDIM,double> > level_vec = new SAMRAIVectorReal<NDIM,double>(name_str.str(), vec.getPatchHierarchy(), level_num, level_num); for (int comp = 0; comp < vec.getNumberOfComponents(); ++comp) { level_vec->addComponent(vec.getComponentVariable(comp), vec.getComponentDescriptorIndex(comp), vec.getControlVolumeIndex(comp)); } return level_vec; }// getLevelSAMRAIVectorReal
bool CCDivGradHypreLevelSolver::solveSystem( SAMRAIVectorReal<NDIM,double>& x, SAMRAIVectorReal<NDIM,double>& b) { IBTK_TIMER_START(t_solve_system); if (d_enable_logging) plog << d_object_name << "::solveSystem():" << std::endl; // Initialize the solver, when necessary. const bool deallocate_after_solve = !d_is_initialized; if (deallocate_after_solve) initializeSolverState(x,b); // Solve the system using the hypre solver. static const int comp = 0; const int x_idx = x.getComponentDescriptorIndex(comp); const int b_idx = b.getComponentDescriptorIndex(comp); bool converged = true; IntVector<NDIM> chkbrd_mode_id; #if (NDIM > 2) for (chkbrd_mode_id(2) = 0; chkbrd_mode_id(2) < 2; ++chkbrd_mode_id(2)) { #endif for (chkbrd_mode_id(1) = 0; chkbrd_mode_id(1) < 2; ++chkbrd_mode_id(1)) { for (chkbrd_mode_id(0) = 0; chkbrd_mode_id(0) < 2; ++chkbrd_mode_id(0)) { bool converged_mode = solveSystem(x_idx, b_idx, chkbrd_mode_id); if (d_enable_logging) { plog << d_object_name << "::solveSystem(): solver " << (converged_mode ? "converged" : "diverged") << "\n" << "chkbrd_mode_id = " << chkbrd_mode_id << "\n" << "iterations = " << d_current_its << "\n" << "residual norm = " << d_current_residual_norm << std::endl; } converged = converged && converged_mode; } } #if (NDIM > 2) } #endif // Deallocate the solver, when necessary. if (deallocate_after_solve) deallocateSolverState(); IBTK_TIMER_STOP(t_solve_system); return converged; }// solveSystem
void GeneralOperator::applyAdd(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& y, SAMRAIVectorReal<NDIM, double>& z) { // Guard against the case that y == z. Pointer<SAMRAIVectorReal<NDIM, double> > zz = z.cloneVector(z.getName()); zz->allocateVectorData(); zz->copyVector(Pointer<SAMRAIVectorReal<NDIM, double> >(&z, false)); apply(x, *zz); z.add(Pointer<SAMRAIVectorReal<NDIM, double> >(&y, false), zz); zz->deallocateVectorData(); zz->freeVectorComponents(); zz.setNull(); return; } // applyAdd
void PETScPCLSWrapper::initializeSolverState(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& b) { if (d_is_initialized) deallocateSolverState(); d_x = x.cloneVector(""); d_b = b.cloneVector(""); MPI_Comm comm; int ierr = PetscObjectGetComm(reinterpret_cast<PetscObject>(d_petsc_pc), &comm); IBTK_CHKERRQ(ierr); d_petsc_x = PETScSAMRAIVectorReal::createPETScVector(d_x, comm); d_petsc_b = PETScSAMRAIVectorReal::createPETScVector(d_b, comm); d_is_initialized = true; return; } // initializeSolverState
void SCPoissonPETScLevelSolver::copyToPETScVec(Vec& petsc_x, SAMRAIVectorReal<NDIM, double>& x) { const int x_idx = x.getComponentDescriptorIndex(0); PETScVecUtilities::copyToPatchLevelVec(petsc_x, x_idx, d_dof_index_idx, d_level); return; } // copyToPETScVec
void INSStaggeredVCStokesOperator::initializeOperatorState( const SAMRAIVectorReal<NDIM,double>& in, const SAMRAIVectorReal<NDIM,double>& /*out*/) { IBAMR_TIMER_START(t_initialize_operator_state); if (d_is_initialized) deallocateOperatorState(); d_x_scratch = in.cloneVector("INSStaggeredVCStokesOperator::x_scratch"); d_x_scratch->allocateVectorData(); typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; InterpolationTransactionComponent U_scratch_component(d_x_scratch->getComponentDescriptorIndex(0), U_DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY); InterpolationTransactionComponent P_scratch_component(d_x_scratch->getComponentDescriptorIndex(1), P_DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY); InterpolationTransactionComponent mu_component(d_mu_data_idx, MU_DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY); std::vector<InterpolationTransactionComponent> U_P_MU_components(3); U_P_MU_components[0] = U_scratch_component; U_P_MU_components[1] = P_scratch_component; U_P_MU_components[2] = mu_component; d_U_P_MU_bdry_fill_op = new HierarchyGhostCellInterpolation(); d_U_P_MU_bdry_fill_op->initializeOperatorState(U_P_MU_components, d_x_scratch->getPatchHierarchy()); d_is_initialized = true; IBAMR_TIMER_STOP(t_initialize_operator_state); return; }// initializeOperatorState
void CCPoissonPETScLevelSolver::initializeSolverStateSpecialized(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& /*b*/) { // Allocate DOF index data. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const int x_idx = x.getComponentDescriptorIndex(0); Pointer<CellDataFactory<NDIM, double> > x_fac = var_db->getPatchDescriptor()->getPatchDataFactory(x_idx); const int depth = x_fac->getDefaultDepth(); Pointer<CellDataFactory<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::constructPatchLevelDOFIndices(d_num_dofs_per_proc, d_dof_index_idx, level); const int mpi_rank = SAMRAI_MPI::getRank(); ierr = VecCreateMPI(PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_x); IBTK_CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_b); IBTK_CHKERRQ(ierr); PETScMatUtilities::constructPatchLevelCCLaplaceOp( d_petsc_mat, d_poisson_spec, d_bc_coefs, d_solution_time, d_num_dofs_per_proc, d_dof_index_idx, level); d_petsc_pc = d_petsc_mat; d_petsc_ksp_ops_flag = SAME_PRECONDITIONER; d_data_synch_sched = PETScVecUtilities::constructDataSynchSchedule(x_idx, level); d_ghost_fill_sched = PETScVecUtilities::constructGhostFillSchedule(x_idx, level); return; } // initializeSolverStateSpecialized
void SCPoissonPETScLevelSolver::copyFromPETScVec(Vec& petsc_x, SAMRAIVectorReal<NDIM, double>& x) { const int x_idx = x.getComponentDescriptorIndex(0); PETScVecUtilities::copyFromPatchLevelVec( petsc_x, x_idx, d_dof_index_idx, d_level, d_data_synch_sched, d_ghost_fill_sched); return; } // copyFromPETScVec
void LinearOperator::modifyRhsForBcs(SAMRAIVectorReal<NDIM, double>& y) { if (d_homogeneous_bc) return; // Set y := y - A*0, i.e., shift the right-hand-side vector to account for // inhomogeneous boundary conditions. Pointer<SAMRAIVectorReal<NDIM, double> > x = y.cloneVector(""); Pointer<SAMRAIVectorReal<NDIM, double> > b = y.cloneVector(""); x->allocateVectorData(); b->allocateVectorData(); x->setToScalar(0.0); apply(*x, *b); y.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&y, false), b); x->freeVectorComponents(); b->freeVectorComponents(); return; } // modifyRhsForBcs
void VCSCViscousPETScLevelSolver::setupKSPVecs(Vec& petsc_x, Vec& petsc_b, SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& b) { if (d_initial_guess_nonzero) copyToPETScVec(petsc_x, x); const bool level_zero = (d_level_num == 0); const int x_idx = x.getComponentDescriptorIndex(0); const int b_idx = b.getComponentDescriptorIndex(0); const auto b_adj_idx = d_cached_eulerian_data.getCachedPatchDataIndex(b_idx); for (PatchLevel<NDIM>::Iterator p(d_level); p; p++) { Pointer<Patch<NDIM> > patch = d_level->getPatch(p()); Pointer<PatchGeometry<NDIM> > pgeom = patch->getPatchGeometry(); Pointer<SideData<NDIM, double> > x_data = patch->getPatchData(x_idx); Pointer<SideData<NDIM, double> > b_data = patch->getPatchData(b_idx); Pointer<SideData<NDIM, double> > b_adj_data = patch->getPatchData(b_adj_idx); b_adj_data->copy(*b_data); const bool at_physical_bdry = pgeom->intersectsPhysicalBoundary(); if (at_physical_bdry) { PoissonUtilities::adjustVCSCViscousOpRHSAtPhysicalBoundary(*b_adj_data, patch, d_poisson_spec, 1.0, d_bc_coefs, d_solution_time, d_homogeneous_bc, d_mu_interp_type); } const Array<BoundaryBox<NDIM> >& type_1_cf_bdry = level_zero ? Array<BoundaryBox<NDIM> >() : d_cf_boundary->getBoundaries(patch->getPatchNumber(), /* boundary type */ 1, d_mu_interp_type); const bool at_cf_bdry = type_1_cf_bdry.size() > 0; if (at_cf_bdry) { PoissonUtilities::adjustVCSCViscousOpRHSAtCoarseFineBoundary( *b_adj_data, *x_data, patch, d_poisson_spec, 1.0, type_1_cf_bdry); } } PETScVecUtilities::copyToPatchLevelVec(petsc_b, b_adj_idx, d_dof_index_idx, d_level); return; } // setupKSPVecs
void SCPoissonPETScLevelSolver::setupKSPVecs(Vec& petsc_x, Vec& petsc_b, SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& b) { if (d_initial_guess_nonzero) copyToPETScVec(petsc_x, x); const bool level_zero = (d_level_num == 0); const int x_idx = x.getComponentDescriptorIndex(0); const int b_idx = b.getComponentDescriptorIndex(0); Pointer<SideVariable<NDIM, double> > b_var = b.getComponentVariable(0); VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); int b_adj_idx = var_db->registerClonedPatchDataIndex(b_var, b_idx); d_level->allocatePatchData(b_adj_idx); for (PatchLevel<NDIM>::Iterator p(d_level); p; p++) { Pointer<Patch<NDIM> > patch = d_level->getPatch(p()); Pointer<PatchGeometry<NDIM> > pgeom = patch->getPatchGeometry(); Pointer<SideData<NDIM, double> > x_data = patch->getPatchData(x_idx); Pointer<SideData<NDIM, double> > b_data = patch->getPatchData(b_idx); Pointer<SideData<NDIM, double> > b_adj_data = patch->getPatchData(b_adj_idx); b_adj_data->copy(*b_data); const bool at_physical_bdry = pgeom->intersectsPhysicalBoundary(); if (at_physical_bdry) { PoissonUtilities::adjustRHSAtPhysicalBoundary( *b_adj_data, patch, d_poisson_spec, d_bc_coefs, d_solution_time, d_homogeneous_bc); } const Array<BoundaryBox<NDIM> >& type_1_cf_bdry = level_zero ? Array<BoundaryBox<NDIM> >() : d_cf_boundary->getBoundaries(patch->getPatchNumber(), /* boundary type */ 1); const bool at_cf_bdry = type_1_cf_bdry.size() > 0; if (at_cf_bdry) { PoissonUtilities::adjustRHSAtCoarseFineBoundary( *b_adj_data, *x_data, patch, d_poisson_spec, type_1_cf_bdry); } } PETScVecUtilities::copyToPatchLevelVec(petsc_b, b_adj_idx, d_dof_index_idx, d_level); d_level->deallocatePatchData(b_adj_idx); var_db->removePatchDataIndex(b_adj_idx); return; } // setupKSPVecs
void StaggeredStokesPETScLevelSolver::copyToPETScVec(Vec& petsc_x, SAMRAIVectorReal<NDIM, double>& x, Pointer<PatchLevel<NDIM> > patch_level) { const int u_idx = x.getComponentDescriptorIndex(0); const int p_idx = x.getComponentDescriptorIndex(1); StaggeredStokesPETScVecUtilities::copyToPatchLevelVec( petsc_x, u_idx, d_u_dof_index_idx, p_idx, d_p_dof_index_idx, patch_level); return; } // copyToPETScVec
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
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
void StaggeredStokesPETScLevelSolver::initializeSolverStateSpecialized( const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& /*b*/) { // Allocate DOF index data. Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(d_level_num); if (!level->checkAllocated(d_u_dof_index_idx)) level->allocatePatchData(d_u_dof_index_idx); if (!level->checkAllocated(d_p_dof_index_idx)) level->allocatePatchData(d_p_dof_index_idx); // Setup PETSc objects. int ierr; StaggeredStokesPETScVecUtilities::constructPatchLevelDOFIndices( d_num_dofs_per_proc, d_u_dof_index_idx, d_p_dof_index_idx, level); const int mpi_rank = SAMRAI_MPI::getRank(); ierr = VecCreateMPI( PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_x); IBTK_CHKERRQ(ierr); ierr = VecCreateMPI( PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_b); IBTK_CHKERRQ(ierr); StaggeredStokesPETScMatUtilities::constructPatchLevelMACStokesOp(d_petsc_mat, d_U_problem_coefs, d_U_bc_coefs, d_new_time, d_num_dofs_per_proc, d_u_dof_index_idx, d_p_dof_index_idx, level); ierr = MatDuplicate(d_petsc_mat, MAT_COPY_VALUES, &d_petsc_pc); IBTK_CHKERRQ(ierr); HierarchyDataOpsManager<NDIM>* hier_ops_manager = HierarchyDataOpsManager<NDIM>::getManager(); Pointer<HierarchyDataOpsInteger<NDIM> > hier_p_dof_index_ops = hier_ops_manager->getOperationsInteger(d_p_dof_index_var, d_hierarchy, true); hier_p_dof_index_ops->resetLevels(d_level_num, d_level_num); const int min_p_idx = hier_p_dof_index_ops->min( d_p_dof_index_idx); // NOTE: HierarchyDataOpsInteger::max() is broken ierr = MatZeroRowsColumns(d_petsc_pc, 1, &min_p_idx, 1.0, NULL, NULL); IBTK_CHKERRQ(ierr); d_petsc_ksp_ops_flag = SAME_PRECONDITIONER; const int u_idx = x.getComponentDescriptorIndex(0); const int p_idx = x.getComponentDescriptorIndex(1); d_data_synch_sched = StaggeredStokesPETScVecUtilities::constructDataSynchSchedule(u_idx, p_idx, level); d_ghost_fill_sched = StaggeredStokesPETScVecUtilities::constructGhostFillSchedule(u_idx, p_idx, level); return; } // initializeSolverStateSpecialized
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 VCSCViscousPETScLevelSolver::initializeSolverStateSpecialized(const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& /*b*/) { // Allocate DOF index data. VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase(); const int x_idx = x.getComponentDescriptorIndex(0); 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); if (!d_level->checkAllocated(d_dof_index_idx)) d_level->allocatePatchData(d_dof_index_idx); PETScVecUtilities::constructPatchLevelDOFIndices(d_num_dofs_per_proc, d_dof_index_idx, d_level); // Setup PETSc objects. int ierr; const int mpi_rank = SAMRAI_MPI::getRank(); ierr = VecCreateMPI(PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_x); IBTK_CHKERRQ(ierr); ierr = VecCreateMPI(PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_b); IBTK_CHKERRQ(ierr); const double alpha = 1.0; const double beta = 1.0; PETScMatUtilities::constructPatchLevelVCSCViscousOp(d_petsc_mat, d_poisson_spec, alpha, beta, d_bc_coefs, d_solution_time, d_num_dofs_per_proc, d_dof_index_idx, d_level, d_mu_interp_type); d_petsc_pc = d_petsc_mat; // Setup SAMRAI communication objects. d_data_synch_sched = PETScVecUtilities::constructDataSynchSchedule(x_idx, d_level); d_ghost_fill_sched = PETScVecUtilities::constructGhostFillSchedule(x_idx, d_level); return; } // initializeSolverStateSpecialized
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 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 StaggeredStokesOperator::apply(SAMRAIVectorReal<NDIM, double>& x, SAMRAIVectorReal<NDIM, double>& y) { IBAMR_TIMER_START(t_apply); // Get the vector components. const int U_idx = x.getComponentDescriptorIndex(0); const int P_idx = x.getComponentDescriptorIndex(1); const int A_U_idx = y.getComponentDescriptorIndex(0); const int A_P_idx = y.getComponentDescriptorIndex(1); const int U_scratch_idx = d_x->getComponentDescriptorIndex(0); Pointer<SideVariable<NDIM, double> > U_sc_var = x.getComponentVariable(0); Pointer<CellVariable<NDIM, double> > P_cc_var = x.getComponentVariable(1); Pointer<SideVariable<NDIM, double> > A_U_sc_var = y.getComponentVariable(0); Pointer<CellVariable<NDIM, double> > A_P_cc_var = y.getComponentVariable(1); // Simultaneously fill ghost cell values for all components. typedef HierarchyGhostCellInterpolation::InterpolationTransactionComponent InterpolationTransactionComponent; std::vector<InterpolationTransactionComponent> transaction_comps(2); transaction_comps[0] = InterpolationTransactionComponent(U_scratch_idx, U_idx, DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_U_bc_coefs, d_U_fill_pattern); transaction_comps[1] = InterpolationTransactionComponent(P_idx, DATA_REFINE_TYPE, USE_CF_INTERPOLATION, DATA_COARSEN_TYPE, BDRY_EXTRAP_TYPE, CONSISTENT_TYPE_2_BDRY, d_P_bc_coef, d_P_fill_pattern); d_hier_bdry_fill->resetTransactionComponents(transaction_comps); d_hier_bdry_fill->setHomogeneousBc(d_homogeneous_bc); StaggeredStokesPhysicalBoundaryHelper::setupBcCoefObjects( d_U_bc_coefs, d_P_bc_coef, U_scratch_idx, P_idx, d_homogeneous_bc); d_hier_bdry_fill->fillData(d_solution_time); StaggeredStokesPhysicalBoundaryHelper::resetBcCoefObjects(d_U_bc_coefs, d_P_bc_coef); // d_bc_helper->enforceDivergenceFreeConditionAtBoundary(U_scratch_idx); d_hier_bdry_fill->resetTransactionComponents(d_transaction_comps); // Compute the action of the operator: // // A*[U;P] := [A_U;A_P] = [(C*I+D*L)*U + Grad P; -Div U] d_hier_math_ops->grad(A_U_idx, A_U_sc_var, /*cf_bdry_synch*/ false, 1.0, P_idx, P_cc_var, d_no_fill, d_new_time); d_hier_math_ops->laplace(A_U_idx, A_U_sc_var, d_U_problem_coefs, U_scratch_idx, U_sc_var, d_no_fill, d_new_time, 1.0, A_U_idx, A_U_sc_var); d_hier_math_ops->div(A_P_idx, A_P_cc_var, -1.0, U_scratch_idx, U_sc_var, d_no_fill, d_new_time, /*cf_bdry_synch*/ true); d_bc_helper->copyDataAtDirichletBoundaries(A_U_idx, U_scratch_idx); IBAMR_TIMER_STOP(t_apply); return; } // apply
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