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 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
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 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 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
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 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 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 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 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