1c4762a1bSJed Brown 2c4762a1bSJed Brown static char help[] = "Shows how to add a new MatOperation to AIJ MatType\n\n"; 3c4762a1bSJed Brown 4c4762a1bSJed Brown #include <petscmat.h> 5c4762a1bSJed Brown #include <petscblaslapack.h> 6c4762a1bSJed Brown 7d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatScaleUserImpl_SeqAIJ(Mat inA, PetscScalar alpha) 8d71ae5a4SJacob Faibussowitsch { 9c4762a1bSJed Brown PetscFunctionBegin; 109566063dSJacob Faibussowitsch PetscCall(MatScale(inA, alpha)); 11*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12c4762a1bSJed Brown } 13c4762a1bSJed Brown 14c4762a1bSJed Brown extern PetscErrorCode MatScaleUserImpl(Mat, PetscScalar); 15c4762a1bSJed Brown 16d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatScaleUserImpl_MPIAIJ(Mat A, PetscScalar aa) 17d71ae5a4SJacob Faibussowitsch { 18c4762a1bSJed Brown Mat AA, AB; 19c4762a1bSJed Brown 20c4762a1bSJed Brown PetscFunctionBegin; 219566063dSJacob Faibussowitsch PetscCall(MatMPIAIJGetSeqAIJ(A, &AA, &AB, NULL)); 229566063dSJacob Faibussowitsch PetscCall(MatScaleUserImpl(AA, aa)); 239566063dSJacob Faibussowitsch PetscCall(MatScaleUserImpl(AB, aa)); 24*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25c4762a1bSJed Brown } 26c4762a1bSJed Brown 27c4762a1bSJed Brown /* This routine registers MatScaleUserImpl_SeqAIJ() and 28c4762a1bSJed Brown MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl() 29c4762a1bSJed Brown functionality for SeqAIJ and MPIAIJ matrix-types */ 30d71ae5a4SJacob Faibussowitsch PetscErrorCode RegisterMatScaleUserImpl(Mat mat) 31d71ae5a4SJacob Faibussowitsch { 32c4762a1bSJed Brown PetscMPIInt size; 33c4762a1bSJed Brown 34362febeeSStefano Zampini PetscFunctionBegin; 359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 36c4762a1bSJed Brown if (size == 1) { /* SeqAIJ Matrix */ 379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ)); 38c4762a1bSJed Brown } else { /* MPIAIJ Matrix */ 39c4762a1bSJed Brown Mat AA, AB; 409566063dSJacob Faibussowitsch PetscCall(MatMPIAIJGetSeqAIJ(mat, &AA, &AB, NULL)); 419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", MatScaleUserImpl_MPIAIJ)); 429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)AA, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ)); 439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)AB, "MatScaleUserImpl_C", MatScaleUserImpl_SeqAIJ)); 44c4762a1bSJed Brown } 45*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 46c4762a1bSJed Brown } 47c4762a1bSJed Brown 482e956fe4SStefano Zampini /* This routine deregisters MatScaleUserImpl_SeqAIJ() and 492e956fe4SStefano Zampini MatScaleUserImpl_MPIAIJ() as methods providing MatScaleUserImpl() 502e956fe4SStefano Zampini functionality for SeqAIJ and MPIAIJ matrix-types */ 51d71ae5a4SJacob Faibussowitsch PetscErrorCode DeRegisterMatScaleUserImpl(Mat mat) 52d71ae5a4SJacob Faibussowitsch { 532e956fe4SStefano Zampini PetscMPIInt size; 542e956fe4SStefano Zampini 552e956fe4SStefano Zampini PetscFunctionBegin; 562e956fe4SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size)); 572e956fe4SStefano Zampini if (size == 1) { /* SeqAIJ Matrix */ 582e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", NULL)); 592e956fe4SStefano Zampini } else { /* MPIAIJ Matrix */ 602e956fe4SStefano Zampini Mat AA, AB; 612e956fe4SStefano Zampini PetscCall(MatMPIAIJGetSeqAIJ(mat, &AA, &AB, NULL)); 622e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatScaleUserImpl_C", NULL)); 632e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)AA, "MatScaleUserImpl_C", NULL)); 642e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)AB, "MatScaleUserImpl_C", NULL)); 652e956fe4SStefano Zampini } 66*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 672e956fe4SStefano Zampini } 682e956fe4SStefano Zampini 69c4762a1bSJed Brown /* this routines queries the already registered MatScaleUserImp_XXX 70c4762a1bSJed Brown implementations for the given matrix, and calls the correct 71c4762a1bSJed Brown routine. i.e if MatType is SeqAIJ, MatScaleUserImpl_SeqAIJ() gets 72c4762a1bSJed Brown called, and if MatType is MPIAIJ, MatScaleUserImpl_MPIAIJ() gets 73c4762a1bSJed Brown called */ 74d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScaleUserImpl(Mat mat, PetscScalar a) 75d71ae5a4SJacob Faibussowitsch { 765f80ce2aSJacob Faibussowitsch PetscErrorCode (*f)(Mat, PetscScalar); 77c4762a1bSJed Brown 78c4762a1bSJed Brown PetscFunctionBegin; 799566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)mat, "MatScaleUserImpl_C", &f)); 809566063dSJacob Faibussowitsch if (f) PetscCall((*f)(mat, a)); 81*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82c4762a1bSJed Brown } 83c4762a1bSJed Brown 84c4762a1bSJed Brown /* Main user code that uses MatScaleUserImpl() */ 85c4762a1bSJed Brown 86d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 87d71ae5a4SJacob Faibussowitsch { 88c4762a1bSJed Brown Mat mat; 89c4762a1bSJed Brown PetscInt i, j, m = 2, n, Ii, J; 90c4762a1bSJed Brown PetscScalar v, none = -1.0; 91c4762a1bSJed Brown PetscMPIInt rank, size; 92c4762a1bSJed Brown 93327415f7SBarry Smith PetscFunctionBeginUser; 949566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 969566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 97c4762a1bSJed Brown n = 2 * size; 98c4762a1bSJed Brown 99c4762a1bSJed Brown /* create the matrix */ 1009566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &mat)); 1019566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat, PETSC_DECIDE, PETSC_DECIDE, m * n, m * n)); 1029566063dSJacob Faibussowitsch PetscCall(MatSetType(mat, MATAIJ)); 1039566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 104c4762a1bSJed Brown 105c4762a1bSJed Brown /* register user defined MatScaleUser() operation for both SeqAIJ 106c4762a1bSJed Brown and MPIAIJ types */ 1079566063dSJacob Faibussowitsch PetscCall(RegisterMatScaleUserImpl(mat)); 108c4762a1bSJed Brown 109c4762a1bSJed Brown /* assemble the matrix */ 110c4762a1bSJed Brown for (i = 0; i < m; i++) { 111c4762a1bSJed Brown for (j = 2 * rank; j < 2 * rank + 2; j++) { 1129371c9d4SSatish Balay v = -1.0; 1139371c9d4SSatish Balay Ii = j + n * i; 1149371c9d4SSatish Balay if (i > 0) { 1159371c9d4SSatish Balay J = Ii - n; 1169371c9d4SSatish Balay PetscCall(MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 1179371c9d4SSatish Balay } 1189371c9d4SSatish Balay if (i < m - 1) { 1199371c9d4SSatish Balay J = Ii + n; 1209371c9d4SSatish Balay PetscCall(MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 1219371c9d4SSatish Balay } 1229371c9d4SSatish Balay if (j > 0) { 1239371c9d4SSatish Balay J = Ii - 1; 1249371c9d4SSatish Balay PetscCall(MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 1259371c9d4SSatish Balay } 1269371c9d4SSatish Balay if (j < n - 1) { 1279371c9d4SSatish Balay J = Ii + 1; 1289371c9d4SSatish Balay PetscCall(MatSetValues(mat, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 1299371c9d4SSatish Balay } 1309371c9d4SSatish Balay v = 4.0; 1319371c9d4SSatish Balay PetscCall(MatSetValues(mat, 1, &Ii, 1, &Ii, &v, INSERT_VALUES)); 132c4762a1bSJed Brown } 133c4762a1bSJed Brown } 1349566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 1359566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 136c4762a1bSJed Brown 137c4762a1bSJed Brown /* check the matrix before and after scaling by -1.0 */ 1389566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Matrix _before_ MatScaleUserImpl() operation\n")); 1399566063dSJacob Faibussowitsch PetscCall(MatView(mat, PETSC_VIEWER_STDOUT_WORLD)); 1409566063dSJacob Faibussowitsch PetscCall(MatScaleUserImpl(mat, none)); 1419566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Matrix _after_ MatScaleUserImpl() operation\n")); 1429566063dSJacob Faibussowitsch PetscCall(MatView(mat, PETSC_VIEWER_STDOUT_WORLD)); 143c4762a1bSJed Brown 1442e956fe4SStefano Zampini /* deregister user defined MatScaleUser() operation for both SeqAIJ 1452e956fe4SStefano Zampini and MPIAIJ types */ 1462e956fe4SStefano Zampini PetscCall(DeRegisterMatScaleUserImpl(mat)); 1479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat)); 1489566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 149b122ec5aSJacob Faibussowitsch return 0; 150c4762a1bSJed Brown } 151c4762a1bSJed Brown 152c4762a1bSJed Brown /*TEST 153c4762a1bSJed Brown 154c4762a1bSJed Brown test: 155c4762a1bSJed Brown 156c4762a1bSJed Brown test: 157c4762a1bSJed Brown suffix: 2 158c4762a1bSJed Brown nsize: 2 159c4762a1bSJed Brown 160c4762a1bSJed Brown TEST*/ 161