[petsc-users] KSPSolve with MPIAIJ with non-square 'diagonal parts'

Olivier Jamond olivier.jamond at cea.fr
Mon Aug 30 13:17:16 CDT 2021


Hello,

I am sorry because I surely miss something, but I cannot manage to solve 
a problem with a MPIAIJ matrix which has non-square 'diagonal parts'.

I copy/paste at the bottom of this message a very simple piece of code 
which causes me troubles. I this code I try to do 'x=KSP(A)*b' (with 
gmres/jacobi), but this fails whereas a matrix multiplication 'b=A*x' 
seems to work. Is ksp with such a matrix supposed to work (I can't find 
anything in the documentation about that, so I guess that it is...) ?

Many thanks,
Olivier

NB: this code should be launched with exactly 3 procs

#include "petscsys.h" /* framework routines */
#include "petscvec.h" /* vectors */
#include "petscmat.h" /* matrices */
#include "petscksp.h"

#include <vector>
#include <string>
#include <iostream>
#include <numeric>

static char help[] = "Trying to solve a linear system on a sub-block of 
a matrix\n\n";
int main(int argc, char **argv)
{
   MPI_Init(NULL, NULL);
   PetscErrorCode ierr;
   ierr = PetscInitialize(&argc, &argv, NULL, help);
   CHKERRQ(ierr);

   // clang-format off
   std::vector<std::vector<double>> AA = {
       { 1,  2,  0, /**/ 0,  3, /**/ 0,  0,  4},
       { 0,  5,  6, /**/ 7,  0, /**/ 0,  8,  0},
       { 9,  0, 10, /**/11,  0, /**/ 0, 12,  0},
       //---------------------------------------
       {13,  0, 14, /**/15, 16, /**/17,  0,  0},
       { 0, 18,  0, /**/19, 20, /**/21,  0,  0},
       { 0,  0,  0, /**/22, 23, /**/ 1, 24,  0},
       //--------------------------------------
       {25, 26, 27, /**/ 0,  0, /**/28, 29,  0},
       {30,  0,  0, /**/31, 32, /**/33,  0, 34},
   };


   std::vector<double> bb = {1.,
                             1.,
                             1.,
                             //
                             1.,
                             1.,
                             1.,
                             //
                             1.,
                             1.};


   std::vector<int> nDofsRow = {3, 3, 2};
   std::vector<int> nDofsCol = {3, 2, 3};
   // clang-format on

   int NDofs = std::accumulate(nDofsRow.begin(), nDofsRow.end(), 0);

   int pRank, nProc;
   MPI_Comm_rank(PETSC_COMM_WORLD, &pRank);
   MPI_Comm_size(PETSC_COMM_WORLD, &nProc);

   if (nProc != 3) {
     std::cerr << "THIS TEST MUST BE LAUNCHED WITH EXACTLY 3 PROCS\n";
     abort();
   }

   Mat A;
   MatCreate(PETSC_COMM_WORLD, &A);
   MatSetType(A, MATMPIAIJ);
   MatSetSizes(A, nDofsRow[pRank], nDofsCol[pRank], PETSC_DETERMINE, 
PETSC_DETERMINE);
   MatMPIAIJSetPreallocation(A, NDofs, NULL, NDofs, NULL);

   Vec b;
   VecCreate(PETSC_COMM_WORLD, &b);
   VecSetType(b, VECMPI);
   VecSetSizes(b, nDofsRow[pRank], PETSC_DECIDE);

   if (pRank == 0) {
     for (int i = 0; i < NDofs; ++i) {
       for (int j = 0; j < NDofs; ++j) {
         if (AA[i][j] != 0.) {
           MatSetValue(A, i, j, AA[i][j], ADD_VALUES);
         }
       }
       VecSetValue(b, i, bb[i], ADD_VALUES);
     }
   }

   MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
   MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
   VecAssemblyBegin(b);
   VecAssemblyEnd(b);

   PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, 
PETSC_VIEWER_ASCII_DENSE);
   MatView(A, PETSC_VIEWER_STDOUT_WORLD);
   VecView(b, PETSC_VIEWER_STDOUT_WORLD);

   KSP ksp;
   KSPCreate(PETSC_COMM_WORLD, &ksp);
   KSPSetOperators(ksp, A, A);
   KSPSetFromOptions(ksp);

   PC pc;
   KSPGetPC(ksp, &pc);
   PCSetFromOptions(pc);

   Vec x;
   MatCreateVecs(A, &x, NULL);
   ierr = KSPSolve(ksp, b, x);    // this fails
   MatMult(A, x, b);              // whereas the seems to be ok...

   VecView(x, PETSC_VIEWER_STDOUT_WORLD);

   MPI_Finalize();

   return 0;
}



More information about the petsc-users mailing list