void PetscPreconditioner::set_petsc_subpreconditioner_type(const PCType type, PC& pc) { int ierr; KSP* subksps; int nlocal; ierr = PCASMGetSubKSP(pc, &nlocal, PETSC_NULL, &subksps); CHKERRABORT(MPI_COMM_WORLD, ierr); PetscReal epsilon = 1.e-16; for(int i = 0; i < nlocal; i++) { PC subpc; ierr = KSPGetPC(subksps[i], &subpc); CHKERRABORT(MPI_COMM_WORLD, ierr); ierr = KSPSetTolerances(subksps[i], PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, 1); CHKERRABORT(MPI_COMM_WORLD, ierr); ierr = KSPSetFromOptions(subksps[i]); CHKERRABORT(MPI_COMM_WORLD, ierr); ierr = PCSetType(subpc, type); CHKERRABORT(MPI_COMM_WORLD, ierr); ierr = PCFactorSetZeroPivot(subpc, epsilon); CHKERRABORT(MPI_COMM_WORLD, ierr); ierr = PCFactorSetShiftType(subpc, MAT_SHIFT_NONZERO); CHKERRABORT(MPI_COMM_WORLD, ierr); } }
PETSC_EXTERN void PETSC_STDCALL pcasmgetsubksp_(PC *pc,PetscInt *n_local,PetscInt *first_local,KSP *ksp,PetscErrorCode *ierr) { KSP *tksp; PetscInt i,nloc; CHKFORTRANNULLINTEGER(n_local); CHKFORTRANNULLINTEGER(first_local); CHKFORTRANNULLOBJECT(ksp); *ierr = PCASMGetSubKSP(*pc,&nloc,first_local,&tksp); if (n_local) *n_local = nloc; if (ksp) { for (i=0; i<nloc; i++) ksp[i] = tksp[i]; } }
void solve_ASM(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetType(ksp,s_type)); // We set the size of x according to the Matrix A PetscInt row; PetscInt col; PetscInt row_loc; PetscInt col_loc; PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); PC pc; // We set the Matrix operators PETSC_SAFE_CALL(KSPSetOperators(ksp,A_,A_)); // We set the pre-conditioner PETSC_SAFE_CALL(KSPGetPC(ksp,&pc)); PETSC_SAFE_CALL(PCSetType(pc,PCASM)); //////////////// ///////////////////// // PCASMSetLocalSubdomains(pc); PCASMSetOverlap(pc,5); KSP *subksp; /* array of KSP contexts for local subblocks */ PetscInt nlocal,first; /* number of local subblocks, first local subblock */ PC subpc; /* PC context for subblock */ PetscBool isasm; /* Set runtime options */ // KSPSetFromOptions(ksp); /* Flag an error if PCTYPE is changed from the runtime options */ // PetscObjectTypeCompare((PetscObject)pc,PCASM,&isasm); // if (!isasm) SETERRQ(PETSC_COMM_WORLD,1,"Cannot Change the PCTYPE when manually changing the subdomain solver settings"); /* Call KSPSetUp() to set the block Jacobi data structures (including creation of an internal KSP context for each block). Note: KSPSetUp() MUST be called before PCASMGetSubKSP(). */ KSPSetUp(ksp); /* Extract the array of KSP contexts for the local blocks */ PCASMGetSubKSP(pc,&nlocal,&first,&subksp); /* Loop over the local blocks, setting various KSP options for each block. */ for (size_t i = 0 ; i < nlocal ; i++) { KSPGetPC(subksp[i],&subpc); // PCFactorSetFill(subpc,30); PCFactorSetLevels(subpc,5); PCSetType(subpc,PCILU); KSPSetType(subksp[i],KSPRICHARDSON); KSPSetTolerances(subksp[i],1.e-3,0.1,PETSC_DEFAULT,PETSC_DEFAULT); } // if we are on on best solve set-up a monitor function if (try_solve == true) { // for bench-mark we are interested in non-preconditioned norm PETSC_SAFE_CALL(KSPMonitorSet(ksp,monitor,&vres,NULL)); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); } // KSPGMRESSetRestart(ksp,100); // Solve the system PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); KSPConvergedReason reason; KSPGetConvergedReason(ksp,&reason); std::cout << "Reason: " << reason << std::endl; auto & v_cl = create_vcluster(); // if (try_solve == true) // { // calculate error statistic about the solution solError err = statSolutionError(A_,b_,x_); if (v_cl.getProcessUnitID() == 0) { std::cout << "Method: " << s_type << " " << " pre-conditoner: " << PCJACOBI << " iterations: " << err.its << std::endl; std::cout << "Norm of error: " << err.err_norm << " Norm infinity: " << err.err_inf << std::endl; } // } }