void PETScMGSolver_UpdateMatrices( PETScMGSolver* self ) { Stream* stream; PETScMGSolver_Level* level; PC pc; KSP levelKSP; PetscErrorCode ec; unsigned l_i; assert( self && Stg_CheckType( self, PETScMGSolver ) ); //assert( self->matrix && Stg_CheckType( self->matrix, PETScMatrix ) ); stream = Journal_Register( InfoStream_Type, (Name)"general" ); assert( stream ); Journal_Printf( stream, "Updating MG matrices ...\n" ); ec = KSPGetPC( self->mgData->ksp, &pc ); CheckPETScError( ec ); for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) { level = self->levels + l_i; if( l_i == self->nLevels - 1 ) //level->A = (PETScMatrix*)self->matrix; level->A = self->mgData->matrix; else { if( level->A ) MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A ); else MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A ); //Matrix_PtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, (void**)&level->A ); /* if( self->levels[l_i + 1].P ) MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A ); else MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A ); */ } ec = PCMGGetSmootherDown( pc, l_i, &levelKSP ); CheckPETScError( ec ); //ec = Stg_KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN ); ec = Stg_KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN ); CheckPETScError( ec ); //ec = PCMGSetResidual( pc, l_i, PCMGDefaultResidual, level->A->petscMat ); ec = PCMGSetResidual( pc, l_i, Stg_PCMGDefaultResidual, level->A ); CheckPETScError( ec ); if( l_i > 0 ) { PCMGGetSmootherUp( pc, l_i, &levelKSP ); //ec = Stg_KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN ); ec = Stg_KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN ); CheckPETScError( ec ); } } Journal_Printf( stream, "done\n" ); }
PETSC_EXTERN void PETSC_STDCALL pcmggetsmootherdown_(PC pc,PetscInt *l,KSP *ksp, int *__ierr ){ *__ierr = PCMGGetSmootherDown( (PC)PetscToPointer((pc) ),*l,ksp); }
void PETScMGSolver_UpdateSolvers( PETScMGSolver* self ) { PETScMGSolver_Level* level; PC pc; KSP levelKSP; PC levelPC; PetscErrorCode ec; unsigned l_i; PetscTruth smoothers_differ, flag; PetscMPIInt size; MPI_Comm comm; assert( self && Stg_CheckType( self, PETScMGSolver ) ); ec = KSPGetPC( self->mgData->ksp, &pc ); CheckPETScError( ec ); ec = PCMGSetLevels( pc, self->nLevels, PETSC_NULL ); CheckPETScError( ec ); ec = PCMGSetType( pc, PC_MG_MULTIPLICATIVE ); CheckPETScError( ec ); ec=PetscOptionsGetTruth( PETSC_NULL, "-pc_mg_different_smoothers", &smoothers_differ, &flag ); CheckPETScError(ec); ec=PetscObjectGetComm( (PetscObject)pc, &comm ); CheckPETScError(ec); MPI_Comm_size( comm, &size ); for( l_i = 1; l_i < self->nLevels; l_i++ ) { level = self->levels + l_i; printf("Configuring MG level %d \n", l_i ); ec = PCMGGetSmootherDown( pc, l_i, &levelKSP ); CheckPETScError( ec ); if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "down_" ); CheckPETScError(ec); } ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec ); ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec ); if(size==1) { ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec ); } /* This does not work - bug with the order the operators are created I guess */ /* For parallel jobs you best bet is to use the command line args and let petsc work it out */ /* else { KSP *sub_ksp; PetscInt k, n_local, first_local; PC sub_pc; PCSetType( levelPC, PCBJACOBI ); KSPSetUp( levelKSP ); PCBJacobiGetSubKSP( levelPC, &n_local,&first_local,&sub_ksp); for(k=0;k<n_local;k++ ) { KSPSetType( sub_ksp[k], KSPFGMRES ); KSPGetPC( sub_ksp[k], &sub_pc ); PCSetType( sub_pc, PCSOR ); } } */ ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nDownIts ); CheckPETScError( ec ); if( l_i == self->nLevels - 1 ) { ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec ); } else { ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_FALSE ); CheckPETScError( ec ); } ec = PCMGGetSmootherUp( pc, l_i, &levelKSP ); CheckPETScError( ec ); if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "up_" ); CheckPETScError(ec); } ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec ); ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec ); if(size==1) { ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec ); } ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nUpIts ); CheckPETScError( ec ); ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec ); ec = PCMGSetCyclesOnLevel( pc, l_i, level->nCycles ); CheckPETScError( ec ); } }