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 6d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGFCycle_Private(PC pc, PC_MG_Levels **mglevels, PetscBool transpose, PetscBool matapp) 7d71ae5a4SJacob Faibussowitsch { 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--) { 149566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict, 0, 0, 0, 0)); 159566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i]->restrct, mglevels[i]->B, &mglevels[i - 1]->B)); 169566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i]->restrct, mglevels[i]->b, mglevels[i - 1]->b)); 179566063dSJacob 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) { 239566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mglevels[0]->B, MAT_DO_NOT_COPY_VALUES, &mglevels[0]->X)); 2430b0564aSStefano Zampini } else { 259566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(mglevels[0]->X)); 2630b0564aSStefano Zampini } 2730b0564aSStefano Zampini } else { 289566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(mglevels[0]->x)); 2930b0564aSStefano Zampini } 304b9ad928SBarry Smith for (i = 0; i < l - 1; i++) { 319566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc, &mglevels[i], transpose, matapp, NULL)); 329566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 339566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i + 1]->interpolate, mglevels[i]->X, &mglevels[i + 1]->X)); 349566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i + 1]->interpolate, mglevels[i]->x, mglevels[i + 1]->x)); 359566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 364b9ad928SBarry Smith } 379566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc, &mglevels[l - 1], transpose, matapp, NULL)); 38fcb023d4SJed Brown } else { 399566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc, &mglevels[l - 1], transpose, matapp, NULL)); 40fcb023d4SJed Brown for (i = l - 2; i >= 0; i--) { 419566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 429566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i + 1]->interpolate, mglevels[i + 1]->X, &mglevels[i]->X)); 439566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i + 1]->interpolate, mglevels[i + 1]->x, mglevels[i]->x)); 449566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 459566063dSJacob Faibussowitsch PetscCall(PCMGMCycle_Private(pc, &mglevels[i], transpose, matapp, NULL)); 46fcb023d4SJed Brown } 47fcb023d4SJed Brown for (i = 1; i < l; i++) { 489566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict, 0, 0, 0, 0)); 499566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i]->restrct, mglevels[i - 1]->B, &mglevels[i]->B)); 509566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i]->restrct, mglevels[i - 1]->b, mglevels[i]->b)); 519566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict, 0, 0, 0, 0)); 52fcb023d4SJed Brown } 53fcb023d4SJed Brown } 54*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 554b9ad928SBarry Smith } 564b9ad928SBarry Smith 57d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGKCycle_Private(PC pc, PC_MG_Levels **mglevels, PetscBool transpose, PetscBool matapp) 58d71ae5a4SJacob Faibussowitsch { 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--) { 649566063dSJacob Faibussowitsch if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict, 0, 0, 0, 0)); 659566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatRestrict(mglevels[i]->restrct, mglevels[i]->B, &mglevels[i - 1]->B)); 669566063dSJacob Faibussowitsch else PetscCall(MatRestrict(mglevels[i]->restrct, mglevels[i]->b, mglevels[i - 1]->b)); 679566063dSJacob 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) { 739566063dSJacob Faibussowitsch PetscCall(MatDuplicate(mglevels[0]->B, MAT_DO_NOT_COPY_VALUES, &mglevels[0]->X)); 7430b0564aSStefano Zampini } else { 759566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(mglevels[0]->X)); 7630b0564aSStefano Zampini } 7730b0564aSStefano Zampini } else { 789566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(mglevels[0]->x)); 7930b0564aSStefano Zampini } 804b9ad928SBarry Smith for (i = 0; i < l - 1; i++) { 819566063dSJacob Faibussowitsch if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventBegin(mglevels[i]->eventsmoothsolve, 0, 0, 0, 0)); 8230b0564aSStefano Zampini if (matapp) { 839566063dSJacob Faibussowitsch PetscCall(KSPMatSolve(mglevels[i]->smoothd, mglevels[i]->B, mglevels[i]->X)); 849566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[i]->smoothd, pc, NULL)); 8530b0564aSStefano Zampini } else { 869566063dSJacob Faibussowitsch PetscCall(KSPSolve(mglevels[i]->smoothd, mglevels[i]->b, mglevels[i]->x)); 879566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[i]->smoothd, pc, mglevels[i]->x)); 8830b0564aSStefano Zampini } 899566063dSJacob Faibussowitsch if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventEnd(mglevels[i]->eventsmoothsolve, 0, 0, 0, 0)); 909566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 919566063dSJacob Faibussowitsch if (matapp) PetscCall(MatMatInterpolate(mglevels[i + 1]->interpolate, mglevels[i]->X, &mglevels[i + 1]->X)); 929566063dSJacob Faibussowitsch else PetscCall(MatInterpolate(mglevels[i + 1]->interpolate, mglevels[i]->x, mglevels[i + 1]->x)); 939566063dSJacob Faibussowitsch if (mglevels[i + 1]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i + 1]->eventinterprestrict, 0, 0, 0, 0)); 944b9ad928SBarry Smith } 959566063dSJacob Faibussowitsch if (mglevels[l - 1]->eventsmoothsolve) PetscCall(PetscLogEventBegin(mglevels[l - 1]->eventsmoothsolve, 0, 0, 0, 0)); 9630b0564aSStefano Zampini if (matapp) { 979566063dSJacob Faibussowitsch PetscCall(KSPMatSolve(mglevels[l - 1]->smoothd, mglevels[l - 1]->B, mglevels[l - 1]->X)); 989566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[l - 1]->smoothd, pc, NULL)); 9930b0564aSStefano Zampini } else { 1009566063dSJacob Faibussowitsch PetscCall(KSPSolve(mglevels[l - 1]->smoothd, mglevels[l - 1]->b, mglevels[l - 1]->x)); 1019566063dSJacob Faibussowitsch PetscCall(KSPCheckSolve(mglevels[l - 1]->smoothd, pc, mglevels[l - 1]->x)); 10230b0564aSStefano Zampini } 1039566063dSJacob Faibussowitsch if (mglevels[l - 1]->eventsmoothsolve) PetscCall(PetscLogEventEnd(mglevels[l - 1]->eventsmoothsolve, 0, 0, 0, 0)); 104*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1054b9ad928SBarry Smith } 106