Пример #1
0
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;
			}
		}
	}