14b9ad928SBarry Smith /* 24b9ad928SBarry Smith Full multigrid using either additive or multiplicative V or W cycle 34b9ad928SBarry Smith */ 4af0996ceSBarry Smith #include <petsc/private/pcmgimpl.h> 54b9ad928SBarry Smith 630b0564aSStefano Zampini PetscErrorCode PCMGFCycle_Private(PC pc,PC_MG_Levels **mglevels,PetscBool transpose,PetscBool matapp) 74b9ad928SBarry Smith { 8f3fbd535SBarry Smith PetscInt i,l = mglevels[0]->levels; 94b9ad928SBarry Smith 104b9ad928SBarry Smith PetscFunctionBegin; 11fcb023d4SJed Brown if (!transpose) { 124b9ad928SBarry Smith /* restrict the RHS through all levels to coarsest. */ 134b9ad928SBarry Smith for (i=l-1; i>0; i--) { 14*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict,0,0,0,0)); 15*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i]->restrct,mglevels[i]->B,&mglevels[i-1]->B)); 16*9566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i]->restrct,mglevels[i]->b,mglevels[i-1]->b)); 17*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict,0,0,0,0)); 184b9ad928SBarry Smith } 194b9ad928SBarry Smith 204b9ad928SBarry Smith /* work our way up through the levels */ 2130b0564aSStefano Zampini if (matapp) { 2230b0564aSStefano Zampini if (!mglevels[0]->X) { 23*9566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mglevels[0]->B,MAT_DO_NOT_COPY_VALUES,&mglevels[0]->X)); 2430b0564aSStefano Zampini } else { 25*9566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(mglevels[0]->X)); 2630b0564aSStefano Zampini } 2730b0564aSStefano Zampini } else { 28*9566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(mglevels[0]->x)); 2930b0564aSStefano Zampini } 304b9ad928SBarry Smith for (i=0; i<l-1; i++) { 31*9566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc,&mglevels[i],transpose,matapp,NULL)); 32*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 33*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i+1]->interpolate,mglevels[i]->X,&mglevels[i+1]->X)); 34*9566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i+1]->interpolate,mglevels[i]->x,mglevels[i+1]->x)); 35*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 364b9ad928SBarry Smith } 37*9566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc,&mglevels[l-1],transpose,matapp,NULL)); 38fcb023d4SJed Brown } else { 39*9566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc,&mglevels[l-1],transpose,matapp,NULL)); 40fcb023d4SJed Brown for (i=l-2; i>=0; i--) { 41*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 42*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i+1]->interpolate,mglevels[i+1]->X,&mglevels[i]->X)); 43*9566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i+1]->interpolate,mglevels[i+1]->x,mglevels[i]->x)); 44*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 45*9566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc,&mglevels[i],transpose,matapp,NULL)); 46fcb023d4SJed Brown } 47fcb023d4SJed Brown for (i=1; i<l; i++) { 48*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict,0,0,0,0)); 49*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i]->restrct,mglevels[i-1]->B,&mglevels[i]->B)); 50*9566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i]->restrct,mglevels[i-1]->b,mglevels[i]->b)); 51*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict,0,0,0,0)); 52fcb023d4SJed Brown } 53fcb023d4SJed Brown } 544b9ad928SBarry Smith PetscFunctionReturn(0); 554b9ad928SBarry Smith } 564b9ad928SBarry Smith 5730b0564aSStefano Zampini PetscErrorCode PCMGKCycle_Private(PC pc,PC_MG_Levels **mglevels,PetscBool transpose,PetscBool matapp) 584b9ad928SBarry Smith { 59f3fbd535SBarry Smith PetscInt i,l = mglevels[0]->levels; 604b9ad928SBarry Smith 614b9ad928SBarry Smith PetscFunctionBegin; 624b9ad928SBarry Smith /* restrict the RHS through all levels to coarsest. */ 634b9ad928SBarry Smith for (i=l-1; i>0; i--) { 64*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict,0,0,0,0)); 65*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i]->restrct,mglevels[i]->B,&mglevels[i-1]->B)); 66*9566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i]->restrct,mglevels[i]->b,mglevels[i-1]->b)); 67*9566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict,0,0,0,0)); 684b9ad928SBarry Smith } 694b9ad928SBarry Smith 704b9ad928SBarry Smith /* work our way up through the levels */ 7130b0564aSStefano Zampini if (matapp) { 7230b0564aSStefano Zampini if (!mglevels[0]->X) { 73*9566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mglevels[0]->B,MAT_DO_NOT_COPY_VALUES,&mglevels[0]->X)); 7430b0564aSStefano Zampini } else { 75*9566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(mglevels[0]->X)); 7630b0564aSStefano Zampini } 7730b0564aSStefano Zampini } else { 78*9566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(mglevels[0]->x)); 7930b0564aSStefano Zampini } 804b9ad928SBarry Smith for (i=0; i<l-1; i++) { 81*9566063dSJacob Faibussowitsch if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventBegin(mglevels[i]->eventsmoothsolve,0,0,0,0)); 8230b0564aSStefano Zampini if (matapp) { 83*9566063dSJacob Faibussowitsch PetscCall(KSPMatSolve(mglevels[i]->smoothd,mglevels[i]->B,mglevels[i]->X)); 84*9566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[i]->smoothd,pc,NULL)); 8530b0564aSStefano Zampini } else { 86*9566063dSJacob Faibussowitsch PetscCall(KSPSolve(mglevels[i]->smoothd,mglevels[i]->b,mglevels[i]->x)); 87*9566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[i]->smoothd,pc,mglevels[i]->x)); 8830b0564aSStefano Zampini } 89*9566063dSJacob Faibussowitsch if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventEnd(mglevels[i]->eventsmoothsolve,0,0,0,0)); 90*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 91*9566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i+1]->interpolate,mglevels[i]->X,&mglevels[i+1]->X)); 92*9566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i+1]->interpolate,mglevels[i]->x,mglevels[i+1]->x)); 93*9566063dSJacob Faibussowitsch if (mglevels[i+1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i+1]->eventinterprestrict,0,0,0,0)); 944b9ad928SBarry Smith } 95*9566063dSJacob Faibussowitsch if (mglevels[l-1]->eventsmoothsolve) PetscCall(PetscLogEventBegin(mglevels[l-1]->eventsmoothsolve,0,0,0,0)); 9630b0564aSStefano Zampini if (matapp) { 97*9566063dSJacob Faibussowitsch PetscCall(KSPMatSolve(mglevels[l-1]->smoothd,mglevels[l-1]->B,mglevels[l-1]->X)); 98*9566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[l-1]->smoothd,pc,NULL)); 9930b0564aSStefano Zampini } else { 100*9566063dSJacob Faibussowitsch PetscCall(KSPSolve(mglevels[l-1]->smoothd,mglevels[l-1]->b,mglevels[l-1]->x)); 101*9566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[l-1]->smoothd,pc,mglevels[l-1]->x)); 10230b0564aSStefano Zampini } 103*9566063dSJacob Faibussowitsch if (mglevels[l-1]->eventsmoothsolve) PetscCall(PetscLogEventEnd(mglevels[l-1]->eventsmoothsolve,0,0,0,0)); 1044b9ad928SBarry Smith PetscFunctionReturn(0); 1054b9ad928SBarry Smith } 106