PETSC_EXTERN void PETSC_STDCALL pcbjacobisetlocalblocks_(PC pc,PetscInt *blocks, PetscInt lens[], int *__ierr ){ *__ierr = PCBJacobiSetLocalBlocks( (PC)PetscToPointer((pc) ),*blocks,lens); }
/*! \brief solve complex use Krylov solver in combination with Block-Jacobi + Nested * * * Solve the system using block-jacobi preconditioner + nested solver for each block * */ void solve_complex(Mat & A_, const Vec & b_, Vec & x_) { // We get the size of the Matrix A PetscInt row; PetscInt col; PetscInt row_loc; PetscInt col_loc; PetscInt * blks; PetscInt nlocal; PetscInt first; KSP *subksp; PC subpc; PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); // Set the preconditioner to Block-jacobi PC pc; KSPGetPC(ksp,&pc); PCSetType(pc,PCBJACOBI); PETSC_SAFE_CALL(KSPSetType(ksp,KSPGMRES)); PetscInt m = 1; PetscMalloc1(m,&blks); for (size_t i = 0 ; i < m ; i++) blks[i] = row_loc; PCBJacobiSetLocalBlocks(pc,m,blks); PetscFree(blks); KSPSetUp(ksp); PCSetUp(pc); PCBJacobiGetSubKSP(pc,&nlocal,&first,&subksp); for (size_t i = 0; i < nlocal; i++) { KSPGetPC(subksp[i],&subpc); PCSetType(subpc,PCLU); // PCSetType(subpc,PCJACOBI); KSPSetType(subksp[i],KSPPREONLY); // PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedDefault,NULL,NULL)); // KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); /* if (!rank) { if (i%2) { PCSetType(subpc,PCILU); } else { PCSetType(subpc,PCNONE); KSPSetType(subksp[i],KSPBCGS); KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); } } else { PCSetType(subpc,PCJACOBI); KSPSetType(subksp[i],KSPGMRES); KSPSetTolerances(subksp[i],1.e-6,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT); }*/ } KSPSolve(ksp,b_,x_); 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; } } }