xref: /petsc/src/mat/tests/ex139.c (revision e8e8640d1cb9a3a2f50c0c0d7b26e5c4d521e2e4)
1c4762a1bSJed Brown const char help[] = "Test MatCreateLocalRef()\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscmat.h>
4c4762a1bSJed Brown 
GetLocalRef(Mat A,IS isrow,IS iscol,Mat * B)5d71ae5a4SJacob Faibussowitsch static PetscErrorCode GetLocalRef(Mat A, IS isrow, IS iscol, Mat *B)
6d71ae5a4SJacob Faibussowitsch {
7c4762a1bSJed Brown   IS istmp;
8c4762a1bSJed Brown 
9c4762a1bSJed Brown   PetscFunctionBegin;
109566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Extracting LocalRef with isrow:\n"));
119566063dSJacob Faibussowitsch   PetscCall(ISOnComm(isrow, PETSC_COMM_WORLD, PETSC_COPY_VALUES, &istmp));
129566063dSJacob Faibussowitsch   PetscCall(ISView(istmp, PETSC_VIEWER_STDOUT_WORLD));
139566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&istmp));
149566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Extracting LocalRef with iscol (only rank=0 shown):\n"));
159566063dSJacob Faibussowitsch   PetscCall(ISOnComm(iscol, PETSC_COMM_WORLD, PETSC_COPY_VALUES, &istmp));
169566063dSJacob Faibussowitsch   PetscCall(ISView(istmp, PETSC_VIEWER_STDOUT_WORLD));
179566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&istmp));
18c4762a1bSJed Brown 
199566063dSJacob Faibussowitsch   PetscCall(MatCreateLocalRef(A, isrow, iscol, B));
20*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21c4762a1bSJed Brown }
22c4762a1bSJed Brown 
main(int argc,char * argv[])23d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
24d71ae5a4SJacob Faibussowitsch {
25c4762a1bSJed Brown   MPI_Comm               comm;
26c4762a1bSJed Brown   Mat                    J, B;
27c4762a1bSJed Brown   PetscInt               i, j, k, l, rstart, rend, m, n, top_bs, row_bs, col_bs, nlocblocks, *idx, nrowblocks, ncolblocks, *ridx, *cidx, *icol, *irow;
28c4762a1bSJed Brown   PetscScalar           *vals;
29c4762a1bSJed Brown   ISLocalToGlobalMapping brmap;
30c4762a1bSJed Brown   IS                     is0, is1;
31c4762a1bSJed Brown   PetscBool              diag, blocked;
32c4762a1bSJed Brown 
33327415f7SBarry Smith   PetscFunctionBeginUser;
349566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, 0, help));
35c4762a1bSJed Brown   comm = PETSC_COMM_WORLD;
36c4762a1bSJed Brown 
37d0609cedSBarry Smith   PetscOptionsBegin(comm, NULL, "LocalRef Test Options", NULL);
38c4762a1bSJed Brown   {
399371c9d4SSatish Balay     top_bs  = 2;
409371c9d4SSatish Balay     row_bs  = 2;
419371c9d4SSatish Balay     col_bs  = 2;
429371c9d4SSatish Balay     diag    = PETSC_FALSE;
439371c9d4SSatish Balay     blocked = PETSC_FALSE;
449566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-top_bs", "Block size of top-level matrix", 0, top_bs, &top_bs, NULL));
459566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-row_bs", "Block size of row map", 0, row_bs, &row_bs, NULL));
469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-col_bs", "Block size of col map", 0, col_bs, &col_bs, NULL));
479566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-diag", "Extract a diagonal black", 0, diag, &diag, NULL));
489566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-blocked", "Use block insertion", 0, blocked, &blocked, NULL));
49c4762a1bSJed Brown   }
50d0609cedSBarry Smith   PetscOptionsEnd();
51c4762a1bSJed Brown 
529566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, &J));
539566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(J, 6, 6, PETSC_DETERMINE, PETSC_DETERMINE));
549566063dSJacob Faibussowitsch   PetscCall(MatSetBlockSize(J, top_bs));
559566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(J));
569566063dSJacob Faibussowitsch   PetscCall(MatSeqBAIJSetPreallocation(J, top_bs, PETSC_DECIDE, 0));
579566063dSJacob Faibussowitsch   PetscCall(MatMPIBAIJSetPreallocation(J, top_bs, PETSC_DECIDE, 0, PETSC_DECIDE, 0));
589566063dSJacob Faibussowitsch   PetscCall(MatSetUp(J));
599566063dSJacob Faibussowitsch   PetscCall(MatGetSize(J, &m, &n));
609566063dSJacob Faibussowitsch   PetscCall(MatGetOwnershipRange(J, &rstart, &rend));
61c4762a1bSJed Brown 
62c4762a1bSJed Brown   nlocblocks = (rend - rstart) / top_bs + 2;
639566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nlocblocks, &idx));
64ad540459SPierre Jolivet   for (i = 0; i < nlocblocks; i++) idx[i] = (rstart / top_bs + i - 1 + m / top_bs) % (m / top_bs);
659566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(comm, top_bs, nlocblocks, idx, PETSC_OWN_POINTER, &brmap));
669566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "Block ISLocalToGlobalMapping:\n"));
679566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingView(brmap, PETSC_VIEWER_STDOUT_WORLD));
68c4762a1bSJed Brown 
699566063dSJacob Faibussowitsch   PetscCall(MatSetLocalToGlobalMapping(J, brmap, brmap));
709566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&brmap));
71c4762a1bSJed Brown 
72c4762a1bSJed Brown   /* Create index sets for local submatrix */
73c4762a1bSJed Brown   nrowblocks = (rend - rstart) / row_bs;
74c4762a1bSJed Brown   ncolblocks = (rend - rstart) / col_bs;
759566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(nrowblocks, &ridx, ncolblocks, &cidx));
76c4762a1bSJed Brown   for (i = 0; i < nrowblocks; i++) ridx[i] = i + ((i > nrowblocks / 2) ^ !rstart);
77c4762a1bSJed Brown   for (i = 0; i < ncolblocks; i++) cidx[i] = i + ((i < ncolblocks / 2) ^ !!rstart);
789566063dSJacob Faibussowitsch   PetscCall(ISCreateBlock(PETSC_COMM_SELF, row_bs, nrowblocks, ridx, PETSC_COPY_VALUES, &is0));
799566063dSJacob Faibussowitsch   PetscCall(ISCreateBlock(PETSC_COMM_SELF, col_bs, ncolblocks, cidx, PETSC_COPY_VALUES, &is1));
809566063dSJacob Faibussowitsch   PetscCall(PetscFree2(ridx, cidx));
81c4762a1bSJed Brown 
82c4762a1bSJed Brown   if (diag) {
839566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&is1));
849566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)is0));
85c4762a1bSJed Brown     is1        = is0;
86c4762a1bSJed Brown     ncolblocks = nrowblocks;
87c4762a1bSJed Brown   }
88c4762a1bSJed Brown 
899566063dSJacob Faibussowitsch   PetscCall(GetLocalRef(J, is0, is1, &B));
90c4762a1bSJed Brown 
919566063dSJacob Faibussowitsch   PetscCall(MatZeroEntries(J));
92c4762a1bSJed Brown 
939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(row_bs, &irow, col_bs, &icol, row_bs * col_bs, &vals));
94c4762a1bSJed Brown   for (i = 0; i < nrowblocks; i++) {
95c4762a1bSJed Brown     for (j = 0; j < ncolblocks; j++) {
96c4762a1bSJed Brown       for (k = 0; k < row_bs; k++) {
97ad540459SPierre Jolivet         for (l = 0; l < col_bs; l++) vals[k * col_bs + l] = i * 100000 + j * 1000 + k * 10 + l;
98c4762a1bSJed Brown         irow[k] = i * row_bs + k;
99c4762a1bSJed Brown       }
100c4762a1bSJed Brown       for (l = 0; l < col_bs; l++) icol[l] = j * col_bs + l;
101c4762a1bSJed Brown       if (blocked) {
1029566063dSJacob Faibussowitsch         PetscCall(MatSetValuesBlockedLocal(B, 1, &i, 1, &j, vals, ADD_VALUES));
103c4762a1bSJed Brown       } else {
1049566063dSJacob Faibussowitsch         PetscCall(MatSetValuesLocal(B, row_bs, irow, col_bs, icol, vals, ADD_VALUES));
105c4762a1bSJed Brown       }
106c4762a1bSJed Brown     }
107c4762a1bSJed Brown   }
1089566063dSJacob Faibussowitsch   PetscCall(PetscFree3(irow, icol, vals));
109c4762a1bSJed Brown 
1109566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
1119566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
112c4762a1bSJed Brown 
1139566063dSJacob Faibussowitsch   PetscCall(MatView(J, PETSC_VIEWER_STDOUT_WORLD));
114c4762a1bSJed Brown 
1159566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is0));
1169566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is1));
1179566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
1189566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&J));
1199566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
120b122ec5aSJacob Faibussowitsch   return 0;
121c4762a1bSJed Brown }
122c4762a1bSJed Brown 
123c4762a1bSJed Brown /*TEST
124c4762a1bSJed Brown 
125c4762a1bSJed Brown    test:
126c4762a1bSJed Brown       nsize: 2
127c4762a1bSJed Brown       filter: grep -v "type: mpi"
128c4762a1bSJed Brown       args: -blocked {{0 1}} -mat_type {{aij baij}}
129c4762a1bSJed Brown 
130c4762a1bSJed Brown TEST*/
131