xref: /petsc/src/ksp/pc/impls/mg/smg.c (revision e8e8640d1cb9a3a2f50c0c0d7b26e5c4d521e2e4)
14b9ad928SBarry Smith /*
24b9ad928SBarry Smith      Additive Multigrid V Cycle routine
34b9ad928SBarry Smith */
4af0996ceSBarry Smith #include <petsc/private/pcmgimpl.h>
54b9ad928SBarry Smith 
PCMGACycle_Private(PC pc,PC_MG_Levels ** mglevels,PetscBool transpose,PetscBool matapp)6d71ae5a4SJacob Faibussowitsch PetscErrorCode PCMGACycle_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;
114b9ad928SBarry Smith   /* compute RHS on each level */
124b9ad928SBarry Smith   for (i = l - 1; i > 0; i--) {
139566063dSJacob Faibussowitsch     if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict, 0, 0, 0, 0));
14fcb023d4SJed Brown     if (!transpose) {
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));
17fcb023d4SJed Brown     } else {
189566063dSJacob Faibussowitsch       if (matapp) PetscCall(MatMatRestrict(mglevels[i]->interpolate, mglevels[i]->B, &mglevels[i - 1]->B));
199566063dSJacob Faibussowitsch       else PetscCall(MatRestrict(mglevels[i]->interpolate, mglevels[i]->b, mglevels[i - 1]->b));
20fcb023d4SJed Brown     }
219566063dSJacob Faibussowitsch     if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict, 0, 0, 0, 0));
224b9ad928SBarry Smith   }
23a8c7a070SBarry Smith   /* solve separately on each level */
244b9ad928SBarry Smith   for (i = 0; i < l; i++) {
2530b0564aSStefano Zampini     if (matapp) {
2630b0564aSStefano Zampini       if (!mglevels[i]->X) {
279566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(mglevels[i]->B, MAT_DO_NOT_COPY_VALUES, &mglevels[i]->X));
2830b0564aSStefano Zampini       } else {
299566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(mglevels[i]->X));
3030b0564aSStefano Zampini       }
3130b0564aSStefano Zampini     } else {
329566063dSJacob Faibussowitsch       PetscCall(VecZeroEntries(mglevels[i]->x));
3330b0564aSStefano Zampini     }
349566063dSJacob Faibussowitsch     if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventBegin(mglevels[i]->eventsmoothsolve, 0, 0, 0, 0));
35fcb023d4SJed Brown     if (!transpose) {
3630b0564aSStefano Zampini       if (matapp) {
379566063dSJacob Faibussowitsch         PetscCall(KSPMatSolve(mglevels[i]->smoothd, mglevels[i]->B, mglevels[i]->X));
389566063dSJacob Faibussowitsch         PetscCall(KSPCheckSolve(mglevels[i]->smoothd, pc, NULL));
3930b0564aSStefano Zampini       } else {
409566063dSJacob Faibussowitsch         PetscCall(KSPSolve(mglevels[i]->smoothd, mglevels[i]->b, mglevels[i]->x));
419566063dSJacob Faibussowitsch         PetscCall(KSPCheckSolve(mglevels[i]->smoothd, pc, mglevels[i]->x));
4230b0564aSStefano Zampini       }
43fcb023d4SJed Brown     } else {
4428b400f6SJacob Faibussowitsch       PetscCheck(!matapp, PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Not supported");
459566063dSJacob Faibussowitsch       PetscCall(KSPSolveTranspose(mglevels[i]->smoothu, mglevels[i]->b, mglevels[i]->x));
469566063dSJacob Faibussowitsch       PetscCall(KSPCheckSolve(mglevels[i]->smoothu, pc, mglevels[i]->x));
47fcb023d4SJed Brown     }
489566063dSJacob Faibussowitsch     if (mglevels[i]->eventsmoothsolve) PetscCall(PetscLogEventEnd(mglevels[i]->eventsmoothsolve, 0, 0, 0, 0));
494b9ad928SBarry Smith   }
504b9ad928SBarry Smith   for (i = 1; i < l; i++) {
519566063dSJacob Faibussowitsch     if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventBegin(mglevels[i]->eventinterprestrict, 0, 0, 0, 0));
52fcb023d4SJed Brown     if (!transpose) {
539566063dSJacob Faibussowitsch       if (matapp) PetscCall(MatMatInterpolateAdd(mglevels[i]->interpolate, mglevels[i - 1]->X, mglevels[i]->X, &mglevels[i]->X));
549566063dSJacob Faibussowitsch       else PetscCall(MatInterpolateAdd(mglevels[i]->interpolate, mglevels[i - 1]->x, mglevels[i]->x, mglevels[i]->x));
55fcb023d4SJed Brown     } else {
569566063dSJacob Faibussowitsch       if (matapp) PetscCall(MatMatInterpolateAdd(mglevels[i]->restrct, mglevels[i - 1]->X, mglevels[i]->X, &mglevels[i]->X));
579566063dSJacob Faibussowitsch       else PetscCall(MatInterpolateAdd(mglevels[i]->restrct, mglevels[i - 1]->x, mglevels[i]->x, mglevels[i]->x));
58fcb023d4SJed Brown     }
599566063dSJacob Faibussowitsch     if (mglevels[i]->eventinterprestrict) PetscCall(PetscLogEventEnd(mglevels[i]->eventinterprestrict, 0, 0, 0, 0));
604b9ad928SBarry Smith   }
61*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
624b9ad928SBarry Smith }
63