xref: /petsc/src/ksp/pc/impls/mg/fmg.c (revision 31d78bcd2b98084dc1368b20eb1129c8b9fb39fe)
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 
PCMGFCycle_Private(PC pc,PC_MG_Levels ** mglevels,PetscBool transpose,PetscBool matapp)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 
PCMGKCycle_Private(PC pc,PC_MG_Levels ** mglevels,PetscBool transpose,PetscBool matapp)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