149bd79ccSDebojyoti Ghosh 249bd79ccSDebojyoti Ghosh /* 349bd79ccSDebojyoti Ghosh Defines the basic matrix operations for the KAIJ matrix storage format. 449bd79ccSDebojyoti Ghosh This format is used to evaluate matrices of the form: 549bd79ccSDebojyoti Ghosh 649bd79ccSDebojyoti Ghosh [I \otimes S + A \otimes T] 749bd79ccSDebojyoti Ghosh 849bd79ccSDebojyoti Ghosh where 949bd79ccSDebojyoti Ghosh S is a dense (p \times q) matrix 1049bd79ccSDebojyoti Ghosh T is a dense (p \times q) matrix 1149bd79ccSDebojyoti Ghosh A is an AIJ (n \times n) matrix 1249bd79ccSDebojyoti Ghosh I is the identity matrix 1349bd79ccSDebojyoti Ghosh 1449bd79ccSDebojyoti Ghosh The resulting matrix is (np \times nq) 1549bd79ccSDebojyoti Ghosh 1649bd79ccSDebojyoti Ghosh We provide: 1749bd79ccSDebojyoti Ghosh MatMult() 1849bd79ccSDebojyoti Ghosh MatMultAdd() 1949bd79ccSDebojyoti Ghosh MatInvertBlockDiagonal() 2049bd79ccSDebojyoti Ghosh and 2149bd79ccSDebojyoti Ghosh MatCreateKAIJ(Mat,PetscInt,PetscInt,const PetscScalar[],const PetscScalar[],Mat*) 2249bd79ccSDebojyoti Ghosh 2349bd79ccSDebojyoti Ghosh This single directory handles both the sequential and parallel codes 2449bd79ccSDebojyoti Ghosh */ 2549bd79ccSDebojyoti Ghosh 2649bd79ccSDebojyoti Ghosh #include <../src/mat/impls/kaij/kaij.h> /*I "petscmat.h" I*/ 2749bd79ccSDebojyoti Ghosh #include <../src/mat/utils/freespace.h> 2849bd79ccSDebojyoti Ghosh #include <petsc/private/vecimpl.h> 2949bd79ccSDebojyoti Ghosh 3049bd79ccSDebojyoti Ghosh /*@C 3149bd79ccSDebojyoti Ghosh MatKAIJGetAIJ - Get the AIJ matrix describing the blockwise action of the KAIJ matrix 3249bd79ccSDebojyoti Ghosh 3349bd79ccSDebojyoti Ghosh Not Collective, but if the KAIJ matrix is parallel, the AIJ matrix is also parallel 3449bd79ccSDebojyoti Ghosh 3549bd79ccSDebojyoti Ghosh Input Parameter: 3649bd79ccSDebojyoti Ghosh . A - the KAIJ matrix 3749bd79ccSDebojyoti Ghosh 3849bd79ccSDebojyoti Ghosh Output Parameter: 3949bd79ccSDebojyoti Ghosh . B - the AIJ matrix 4049bd79ccSDebojyoti Ghosh 4149bd79ccSDebojyoti Ghosh Level: advanced 4249bd79ccSDebojyoti Ghosh 4349bd79ccSDebojyoti Ghosh Notes: The reference count on the AIJ matrix is not increased so you should not destroy it. 4449bd79ccSDebojyoti Ghosh 45db781477SPatrick Sanan .seealso: `MatCreateKAIJ()` 4649bd79ccSDebojyoti Ghosh @*/ 4749bd79ccSDebojyoti Ghosh PetscErrorCode MatKAIJGetAIJ(Mat A,Mat *B) 4849bd79ccSDebojyoti Ghosh { 4949bd79ccSDebojyoti Ghosh PetscBool ismpikaij,isseqkaij; 5049bd79ccSDebojyoti Ghosh 5149bd79ccSDebojyoti Ghosh PetscFunctionBegin; 529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMPIKAIJ,&ismpikaij)); 539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATSEQKAIJ,&isseqkaij)); 5449bd79ccSDebojyoti Ghosh if (ismpikaij) { 5549bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 5649bd79ccSDebojyoti Ghosh 5749bd79ccSDebojyoti Ghosh *B = b->A; 5849bd79ccSDebojyoti Ghosh } else if (isseqkaij) { 5949bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 6049bd79ccSDebojyoti Ghosh 6149bd79ccSDebojyoti Ghosh *B = b->AIJ; 62b04351cbSRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix passed in is not of type KAIJ"); 6349bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 6449bd79ccSDebojyoti Ghosh } 6549bd79ccSDebojyoti Ghosh 6649bd79ccSDebojyoti Ghosh /*@C 6749bd79ccSDebojyoti Ghosh MatKAIJGetS - Get the S matrix describing the shift action of the KAIJ matrix 6849bd79ccSDebojyoti Ghosh 690567c835SRichard Tran Mills Not Collective; the entire S is stored and returned independently on all processes. 7049bd79ccSDebojyoti Ghosh 7149bd79ccSDebojyoti Ghosh Input Parameter: 7249bd79ccSDebojyoti Ghosh . A - the KAIJ matrix 7349bd79ccSDebojyoti Ghosh 74a5b5c723SRichard Tran Mills Output Parameters: 75a5b5c723SRichard Tran Mills + m - the number of rows in S 76a5b5c723SRichard Tran Mills . n - the number of columns in S 77a5b5c723SRichard Tran Mills - S - the S matrix, in form of a scalar array in column-major format 7849bd79ccSDebojyoti Ghosh 79a5b5c723SRichard Tran Mills Note: All output parameters are optional (pass NULL or PETSC_IGNORE if not desired) 8031a97b9aSRichard Tran Mills 8149bd79ccSDebojyoti Ghosh Level: advanced 8249bd79ccSDebojyoti Ghosh 83db781477SPatrick Sanan .seealso: `MatCreateKAIJ()`, `MatGetBlockSizes()` 8449bd79ccSDebojyoti Ghosh @*/ 85a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJGetS(Mat A,PetscInt *m,PetscInt *n,PetscScalar **S) 8649bd79ccSDebojyoti Ghosh { 8749bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 8849bd79ccSDebojyoti Ghosh PetscFunctionBegin; 89a5b5c723SRichard Tran Mills if (m) *m = b->p; 90a5b5c723SRichard Tran Mills if (n) *n = b->q; 91a5b5c723SRichard Tran Mills if (S) *S = b->S; 92a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 93a5b5c723SRichard Tran Mills } 94a5b5c723SRichard Tran Mills 95a5b5c723SRichard Tran Mills /*@C 96a5b5c723SRichard Tran Mills MatKAIJGetSRead - Get a read-only pointer to the S matrix describing the shift action of the KAIJ matrix 97a5b5c723SRichard Tran Mills 98a5b5c723SRichard Tran Mills Not Collective; the entire S is stored and returned independently on all processes. 99a5b5c723SRichard Tran Mills 100a5b5c723SRichard Tran Mills Input Parameter: 101a5b5c723SRichard Tran Mills . A - the KAIJ matrix 102a5b5c723SRichard Tran Mills 103a5b5c723SRichard Tran Mills Output Parameters: 104a5b5c723SRichard Tran Mills + m - the number of rows in S 105a5b5c723SRichard Tran Mills . n - the number of columns in S 106a5b5c723SRichard Tran Mills - S - the S matrix, in form of a scalar array in column-major format 107a5b5c723SRichard Tran Mills 108a5b5c723SRichard Tran Mills Note: All output parameters are optional (pass NULL or PETSC_IGNORE if not desired) 109a5b5c723SRichard Tran Mills 110a5b5c723SRichard Tran Mills Level: advanced 111a5b5c723SRichard Tran Mills 112db781477SPatrick Sanan .seealso: `MatCreateKAIJ()`, `MatGetBlockSizes()` 113a5b5c723SRichard Tran Mills @*/ 114a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJGetSRead(Mat A,PetscInt *m,PetscInt *n,const PetscScalar **S) 115a5b5c723SRichard Tran Mills { 116a5b5c723SRichard Tran Mills Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 117a5b5c723SRichard Tran Mills PetscFunctionBegin; 118a5b5c723SRichard Tran Mills if (m) *m = b->p; 119a5b5c723SRichard Tran Mills if (n) *n = b->q; 120a5b5c723SRichard Tran Mills if (S) *S = b->S; 121a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 122a5b5c723SRichard Tran Mills } 123a5b5c723SRichard Tran Mills 124a5b5c723SRichard Tran Mills /*@C 125a5b5c723SRichard Tran Mills MatKAIJRestoreS - Restore array obtained with MatKAIJGetS() 126a5b5c723SRichard Tran Mills 127a5b5c723SRichard Tran Mills Not collective 128a5b5c723SRichard Tran Mills 129a5b5c723SRichard Tran Mills Input Parameter: 130a5b5c723SRichard Tran Mills . A - the KAIJ matrix 131a5b5c723SRichard Tran Mills 132a5b5c723SRichard Tran Mills Output Parameter: 133a5b5c723SRichard Tran Mills . S - location of pointer to array obtained with MatKAIJGetS() 134a5b5c723SRichard Tran Mills 135a5b5c723SRichard Tran Mills Note: This routine zeros the array pointer to prevent accidental reuse after it has been restored. 136a5b5c723SRichard Tran Mills If NULL is passed, it will not attempt to zero the array pointer. 137a5b5c723SRichard Tran Mills 138a5b5c723SRichard Tran Mills Level: advanced 139db781477SPatrick Sanan .seealso: `MatKAIJGetS()`, `MatKAIJGetSRead()`, `MatKAIJRestoreSRead()` 140a5b5c723SRichard Tran Mills @*/ 141a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJRestoreS(Mat A,PetscScalar **S) 142a5b5c723SRichard Tran Mills { 143a5b5c723SRichard Tran Mills PetscFunctionBegin; 144a5b5c723SRichard Tran Mills if (S) *S = NULL; 1459566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 146a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 147a5b5c723SRichard Tran Mills } 148a5b5c723SRichard Tran Mills 149a5b5c723SRichard Tran Mills /*@C 150a5b5c723SRichard Tran Mills MatKAIJRestoreSRead - Restore array obtained with MatKAIJGetSRead() 151a5b5c723SRichard Tran Mills 152a5b5c723SRichard Tran Mills Not collective 153a5b5c723SRichard Tran Mills 154a5b5c723SRichard Tran Mills Input Parameter: 155a5b5c723SRichard Tran Mills . A - the KAIJ matrix 156a5b5c723SRichard Tran Mills 157a5b5c723SRichard Tran Mills Output Parameter: 158a5b5c723SRichard Tran Mills . S - location of pointer to array obtained with MatKAIJGetS() 159a5b5c723SRichard Tran Mills 160a5b5c723SRichard Tran Mills Note: This routine zeros the array pointer to prevent accidental reuse after it has been restored. 161a5b5c723SRichard Tran Mills If NULL is passed, it will not attempt to zero the array pointer. 162a5b5c723SRichard Tran Mills 163a5b5c723SRichard Tran Mills Level: advanced 164db781477SPatrick Sanan .seealso: `MatKAIJGetS()`, `MatKAIJGetSRead()`, `MatKAIJRestoreSRead()` 165a5b5c723SRichard Tran Mills @*/ 166a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJRestoreSRead(Mat A,const PetscScalar **S) 167a5b5c723SRichard Tran Mills { 168a5b5c723SRichard Tran Mills PetscFunctionBegin; 169a5b5c723SRichard Tran Mills if (S) *S = NULL; 17049bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 17149bd79ccSDebojyoti Ghosh } 17249bd79ccSDebojyoti Ghosh 17349bd79ccSDebojyoti Ghosh /*@C 17431a97b9aSRichard Tran Mills MatKAIJGetT - Get the transformation matrix T associated with the KAIJ matrix 17549bd79ccSDebojyoti Ghosh 1760567c835SRichard Tran Mills Not Collective; the entire T is stored and returned independently on all processes 17749bd79ccSDebojyoti Ghosh 17849bd79ccSDebojyoti Ghosh Input Parameter: 17949bd79ccSDebojyoti Ghosh . A - the KAIJ matrix 18049bd79ccSDebojyoti Ghosh 181d8d19677SJose E. Roman Output Parameters: 182a5b5c723SRichard Tran Mills + m - the number of rows in T 183a5b5c723SRichard Tran Mills . n - the number of columns in T 184a5b5c723SRichard Tran Mills - T - the T matrix, in form of a scalar array in column-major format 18549bd79ccSDebojyoti Ghosh 186a5b5c723SRichard Tran Mills Note: All output parameters are optional (pass NULL or PETSC_IGNORE if not desired) 18731a97b9aSRichard Tran Mills 18849bd79ccSDebojyoti Ghosh Level: advanced 18949bd79ccSDebojyoti Ghosh 190db781477SPatrick Sanan .seealso: `MatCreateKAIJ()`, `MatGetBlockSizes()` 19149bd79ccSDebojyoti Ghosh @*/ 192a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJGetT(Mat A,PetscInt *m,PetscInt *n,PetscScalar **T) 19349bd79ccSDebojyoti Ghosh { 19449bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 19549bd79ccSDebojyoti Ghosh PetscFunctionBegin; 196a5b5c723SRichard Tran Mills if (m) *m = b->p; 197a5b5c723SRichard Tran Mills if (n) *n = b->q; 198a5b5c723SRichard Tran Mills if (T) *T = b->T; 199a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 200a5b5c723SRichard Tran Mills } 201a5b5c723SRichard Tran Mills 202a5b5c723SRichard Tran Mills /*@C 203a5b5c723SRichard Tran Mills MatKAIJGetTRead - Get a read-only pointer to the transformation matrix T associated with the KAIJ matrix 204a5b5c723SRichard Tran Mills 205a5b5c723SRichard Tran Mills Not Collective; the entire T is stored and returned independently on all processes 206a5b5c723SRichard Tran Mills 207a5b5c723SRichard Tran Mills Input Parameter: 208a5b5c723SRichard Tran Mills . A - the KAIJ matrix 209a5b5c723SRichard Tran Mills 210d8d19677SJose E. Roman Output Parameters: 211a5b5c723SRichard Tran Mills + m - the number of rows in T 212a5b5c723SRichard Tran Mills . n - the number of columns in T 213a5b5c723SRichard Tran Mills - T - the T matrix, in form of a scalar array in column-major format 214a5b5c723SRichard Tran Mills 215a5b5c723SRichard Tran Mills Note: All output parameters are optional (pass NULL or PETSC_IGNORE if not desired) 216a5b5c723SRichard Tran Mills 217a5b5c723SRichard Tran Mills Level: advanced 218a5b5c723SRichard Tran Mills 219db781477SPatrick Sanan .seealso: `MatCreateKAIJ()`, `MatGetBlockSizes()` 220a5b5c723SRichard Tran Mills @*/ 221a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJGetTRead(Mat A,PetscInt *m,PetscInt *n,const PetscScalar **T) 222a5b5c723SRichard Tran Mills { 223a5b5c723SRichard Tran Mills Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 224a5b5c723SRichard Tran Mills PetscFunctionBegin; 225a5b5c723SRichard Tran Mills if (m) *m = b->p; 226a5b5c723SRichard Tran Mills if (n) *n = b->q; 227a5b5c723SRichard Tran Mills if (T) *T = b->T; 228a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 229a5b5c723SRichard Tran Mills } 230a5b5c723SRichard Tran Mills 231a5b5c723SRichard Tran Mills /*@C 232a5b5c723SRichard Tran Mills MatKAIJRestoreT - Restore array obtained with MatKAIJGetT() 233a5b5c723SRichard Tran Mills 234a5b5c723SRichard Tran Mills Not collective 235a5b5c723SRichard Tran Mills 236a5b5c723SRichard Tran Mills Input Parameter: 237a5b5c723SRichard Tran Mills . A - the KAIJ matrix 238a5b5c723SRichard Tran Mills 239a5b5c723SRichard Tran Mills Output Parameter: 240a5b5c723SRichard Tran Mills . T - location of pointer to array obtained with MatKAIJGetS() 241a5b5c723SRichard Tran Mills 242a5b5c723SRichard Tran Mills Note: This routine zeros the array pointer to prevent accidental reuse after it has been restored. 243a5b5c723SRichard Tran Mills If NULL is passed, it will not attempt to zero the array pointer. 244a5b5c723SRichard Tran Mills 245a5b5c723SRichard Tran Mills Level: advanced 246db781477SPatrick Sanan .seealso: `MatKAIJGetT()`, `MatKAIJGetTRead()`, `MatKAIJRestoreTRead()` 247a5b5c723SRichard Tran Mills @*/ 248a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJRestoreT(Mat A,PetscScalar **T) 249a5b5c723SRichard Tran Mills { 250a5b5c723SRichard Tran Mills PetscFunctionBegin; 251a5b5c723SRichard Tran Mills if (T) *T = NULL; 2529566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 253a5b5c723SRichard Tran Mills PetscFunctionReturn(0); 254a5b5c723SRichard Tran Mills } 255a5b5c723SRichard Tran Mills 256a5b5c723SRichard Tran Mills /*@C 257a5b5c723SRichard Tran Mills MatKAIJRestoreTRead - Restore array obtained with MatKAIJGetTRead() 258a5b5c723SRichard Tran Mills 259a5b5c723SRichard Tran Mills Not collective 260a5b5c723SRichard Tran Mills 261a5b5c723SRichard Tran Mills Input Parameter: 262a5b5c723SRichard Tran Mills . A - the KAIJ matrix 263a5b5c723SRichard Tran Mills 264a5b5c723SRichard Tran Mills Output Parameter: 265a5b5c723SRichard Tran Mills . T - location of pointer to array obtained with MatKAIJGetS() 266a5b5c723SRichard Tran Mills 267a5b5c723SRichard Tran Mills Note: This routine zeros the array pointer to prevent accidental reuse after it has been restored. 268a5b5c723SRichard Tran Mills If NULL is passed, it will not attempt to zero the array pointer. 269a5b5c723SRichard Tran Mills 270a5b5c723SRichard Tran Mills Level: advanced 271db781477SPatrick Sanan .seealso: `MatKAIJGetT()`, `MatKAIJGetTRead()`, `MatKAIJRestoreTRead()` 272a5b5c723SRichard Tran Mills @*/ 273a5b5c723SRichard Tran Mills PetscErrorCode MatKAIJRestoreTRead(Mat A,const PetscScalar **T) 274a5b5c723SRichard Tran Mills { 275a5b5c723SRichard Tran Mills PetscFunctionBegin; 276a5b5c723SRichard Tran Mills if (T) *T = NULL; 27749bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 27849bd79ccSDebojyoti Ghosh } 27949bd79ccSDebojyoti Ghosh 2800567c835SRichard Tran Mills /*@ 2810567c835SRichard Tran Mills MatKAIJSetAIJ - Set the AIJ matrix describing the blockwise action of the KAIJ matrix 2820567c835SRichard Tran Mills 2830567c835SRichard Tran Mills Logically Collective; if the AIJ matrix is parallel, the KAIJ matrix is also parallel 2840567c835SRichard Tran Mills 2850567c835SRichard Tran Mills Input Parameters: 2860567c835SRichard Tran Mills + A - the KAIJ matrix 2870567c835SRichard Tran Mills - B - the AIJ matrix 2880567c835SRichard Tran Mills 28915b9d025SRichard Tran Mills Notes: 29015b9d025SRichard Tran Mills This function increases the reference count on the AIJ matrix, so the user is free to destroy the matrix if it is not needed. 29115b9d025SRichard Tran Mills Changes to the entries of the AIJ matrix will immediately affect the KAIJ matrix. 29215b9d025SRichard Tran Mills 2930567c835SRichard Tran Mills Level: advanced 2940567c835SRichard Tran Mills 295db781477SPatrick Sanan .seealso: `MatKAIJGetAIJ()`, `MatKAIJSetS()`, `MatKAIJSetT()` 2960567c835SRichard Tran Mills @*/ 2970567c835SRichard Tran Mills PetscErrorCode MatKAIJSetAIJ(Mat A,Mat B) 2980567c835SRichard Tran Mills { 2990567c835SRichard Tran Mills PetscMPIInt size; 30006d61a37SPierre Jolivet PetscBool flg; 3010567c835SRichard Tran Mills 3020567c835SRichard Tran Mills PetscFunctionBegin; 3039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 3040567c835SRichard Tran Mills if (size == 1) { 3059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&flg)); 30628b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"MatKAIJSetAIJ() with MATSEQKAIJ does not support %s as the AIJ mat",((PetscObject)B)->type_name); 3070567c835SRichard Tran Mills Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 3080567c835SRichard Tran Mills a->AIJ = B; 3090567c835SRichard Tran Mills } else { 3100567c835SRichard Tran Mills Mat_MPIKAIJ *a = (Mat_MPIKAIJ*)A->data; 3110567c835SRichard Tran Mills a->A = B; 3120567c835SRichard Tran Mills } 3139566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)B)); 3140567c835SRichard Tran Mills PetscFunctionReturn(0); 3150567c835SRichard Tran Mills } 3160567c835SRichard Tran Mills 3170567c835SRichard Tran Mills /*@C 3180567c835SRichard Tran Mills MatKAIJSetS - Set the S matrix describing the shift action of the KAIJ matrix 3190567c835SRichard Tran Mills 3200567c835SRichard Tran Mills Logically Collective; the entire S is stored independently on all processes. 3210567c835SRichard Tran Mills 3220567c835SRichard Tran Mills Input Parameters: 3230567c835SRichard Tran Mills + A - the KAIJ matrix 3240567c835SRichard Tran Mills . p - the number of rows in S 3250567c835SRichard Tran Mills . q - the number of columns in S 3260567c835SRichard Tran Mills - S - the S matrix, in form of a scalar array in column-major format 3270567c835SRichard Tran Mills 3280567c835SRichard Tran Mills Notes: The dimensions p and q must match those of the transformation matrix T associated with the KAIJ matrix. 32988f48298SRichard Tran Mills The S matrix is copied, so the user can destroy this array. 3300567c835SRichard Tran Mills 3310567c835SRichard Tran Mills Level: Advanced 3320567c835SRichard Tran Mills 333db781477SPatrick Sanan .seealso: `MatKAIJGetS()`, `MatKAIJSetT()`, `MatKAIJSetAIJ()` 3340567c835SRichard Tran Mills @*/ 3350567c835SRichard Tran Mills PetscErrorCode MatKAIJSetS(Mat A,PetscInt p,PetscInt q,const PetscScalar S[]) 3360567c835SRichard Tran Mills { 3370567c835SRichard Tran Mills Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 3380567c835SRichard Tran Mills 3390567c835SRichard Tran Mills PetscFunctionBegin; 3409566063dSJacob Faibussowitsch PetscCall(PetscFree(a->S)); 3410567c835SRichard Tran Mills if (S) { 3429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(p*q,&a->S)); 3439566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(a->S,S,p*q*sizeof(PetscScalar))); 3440567c835SRichard Tran Mills } else a->S = NULL; 3450567c835SRichard Tran Mills 3460567c835SRichard Tran Mills a->p = p; 3470567c835SRichard Tran Mills a->q = q; 3480567c835SRichard Tran Mills PetscFunctionReturn(0); 3490567c835SRichard Tran Mills } 3500567c835SRichard Tran Mills 3510567c835SRichard Tran Mills /*@C 352910cf402Sprj- MatKAIJGetScaledIdentity - Check if both S and T are scaled identities. 353910cf402Sprj- 354910cf402Sprj- Logically Collective. 355910cf402Sprj- 356910cf402Sprj- Input Parameter: 357910cf402Sprj- . A - the KAIJ matrix 358910cf402Sprj- 359910cf402Sprj- Output Parameter: 360910cf402Sprj- . identity - the Boolean value 361910cf402Sprj- 362910cf402Sprj- Level: Advanced 363910cf402Sprj- 364db781477SPatrick Sanan .seealso: `MatKAIJGetS()`, `MatKAIJGetT()` 365910cf402Sprj- @*/ 366910cf402Sprj- PetscErrorCode MatKAIJGetScaledIdentity(Mat A,PetscBool* identity) 367910cf402Sprj- { 368910cf402Sprj- Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 369910cf402Sprj- PetscInt i,j; 370910cf402Sprj- 371910cf402Sprj- PetscFunctionBegin; 372910cf402Sprj- if (a->p != a->q) { 373910cf402Sprj- *identity = PETSC_FALSE; 374910cf402Sprj- PetscFunctionReturn(0); 375910cf402Sprj- } else *identity = PETSC_TRUE; 376910cf402Sprj- if (!a->isTI || a->S) { 377910cf402Sprj- for (i=0; i<a->p && *identity; i++) { 378910cf402Sprj- for (j=0; j<a->p && *identity; j++) { 379910cf402Sprj- if (i != j) { 380910cf402Sprj- if (a->S && PetscAbsScalar(a->S[i+j*a->p]) > PETSC_SMALL) *identity = PETSC_FALSE; 381910cf402Sprj- if (a->T && PetscAbsScalar(a->T[i+j*a->p]) > PETSC_SMALL) *identity = PETSC_FALSE; 382910cf402Sprj- } else { 383910cf402Sprj- if (a->S && PetscAbsScalar(a->S[i*(a->p+1)]-a->S[0]) > PETSC_SMALL) *identity = PETSC_FALSE; 384910cf402Sprj- if (a->T && PetscAbsScalar(a->T[i*(a->p+1)]-a->T[0]) > PETSC_SMALL) *identity = PETSC_FALSE; 385910cf402Sprj- } 386910cf402Sprj- } 387910cf402Sprj- } 388910cf402Sprj- } 389910cf402Sprj- PetscFunctionReturn(0); 390910cf402Sprj- } 391910cf402Sprj- 392910cf402Sprj- /*@C 3930567c835SRichard Tran Mills MatKAIJSetT - Set the transformation matrix T associated with the KAIJ matrix 3940567c835SRichard Tran Mills 3950567c835SRichard Tran Mills Logically Collective; the entire T is stored independently on all processes. 3960567c835SRichard Tran Mills 3970567c835SRichard Tran Mills Input Parameters: 3980567c835SRichard Tran Mills + A - the KAIJ matrix 3990567c835SRichard Tran Mills . p - the number of rows in S 4000567c835SRichard Tran Mills . q - the number of columns in S 4010567c835SRichard Tran Mills - T - the T matrix, in form of a scalar array in column-major format 4020567c835SRichard Tran Mills 4030567c835SRichard Tran Mills Notes: The dimensions p and q must match those of the shift matrix S associated with the KAIJ matrix. 40488f48298SRichard Tran Mills The T matrix is copied, so the user can destroy this array. 4050567c835SRichard Tran Mills 4060567c835SRichard Tran Mills Level: Advanced 4070567c835SRichard Tran Mills 408db781477SPatrick Sanan .seealso: `MatKAIJGetT()`, `MatKAIJSetS()`, `MatKAIJSetAIJ()` 4090567c835SRichard Tran Mills @*/ 4100567c835SRichard Tran Mills PetscErrorCode MatKAIJSetT(Mat A,PetscInt p,PetscInt q,const PetscScalar T[]) 4110567c835SRichard Tran Mills { 4120567c835SRichard Tran Mills PetscInt i,j; 4130567c835SRichard Tran Mills Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 4140567c835SRichard Tran Mills PetscBool isTI = PETSC_FALSE; 4150567c835SRichard Tran Mills 4160567c835SRichard Tran Mills PetscFunctionBegin; 4170567c835SRichard Tran Mills /* check if T is an identity matrix */ 4180567c835SRichard Tran Mills if (T && (p == q)) { 4190567c835SRichard Tran Mills isTI = PETSC_TRUE; 4200567c835SRichard Tran Mills for (i=0; i<p; i++) { 4210567c835SRichard Tran Mills for (j=0; j<q; j++) { 4220567c835SRichard Tran Mills if (i == j) { 4230567c835SRichard Tran Mills /* diagonal term must be 1 */ 4240567c835SRichard Tran Mills if (T[i+j*p] != 1.0) isTI = PETSC_FALSE; 4250567c835SRichard Tran Mills } else { 4260567c835SRichard Tran Mills /* off-diagonal term must be 0 */ 4270567c835SRichard Tran Mills if (T[i+j*p] != 0.0) isTI = PETSC_FALSE; 4280567c835SRichard Tran Mills } 4290567c835SRichard Tran Mills } 4300567c835SRichard Tran Mills } 4310567c835SRichard Tran Mills } 4320567c835SRichard Tran Mills a->isTI = isTI; 4330567c835SRichard Tran Mills 4349566063dSJacob Faibussowitsch PetscCall(PetscFree(a->T)); 4350567c835SRichard Tran Mills if (T && (!isTI)) { 4369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(p*q,&a->T)); 4379566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(a->T,T,p*q*sizeof(PetscScalar))); 43850d19d74SRichard Tran Mills } else a->T = NULL; 4390567c835SRichard Tran Mills 4400567c835SRichard Tran Mills a->p = p; 4410567c835SRichard Tran Mills a->q = q; 4420567c835SRichard Tran Mills PetscFunctionReturn(0); 4430567c835SRichard Tran Mills } 4440567c835SRichard Tran Mills 44549bd79ccSDebojyoti Ghosh PetscErrorCode MatDestroy_SeqKAIJ(Mat A) 44649bd79ccSDebojyoti Ghosh { 44749bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 44849bd79ccSDebojyoti Ghosh 44949bd79ccSDebojyoti Ghosh PetscFunctionBegin; 4509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&b->AIJ)); 4519566063dSJacob Faibussowitsch PetscCall(PetscFree(b->S)); 4529566063dSJacob Faibussowitsch PetscCall(PetscFree(b->T)); 4539566063dSJacob Faibussowitsch PetscCall(PetscFree(b->ibdiag)); 4549566063dSJacob Faibussowitsch PetscCall(PetscFree5(b->sor.w,b->sor.y,b->sor.work,b->sor.t,b->sor.arr)); 4559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqkaij_seqaij_C",NULL)); 4569566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 45749bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 45849bd79ccSDebojyoti Ghosh } 45949bd79ccSDebojyoti Ghosh 460e0e5a793SRichard Tran Mills PETSC_INTERN PetscErrorCode MatKAIJ_build_AIJ_OAIJ(Mat A) 461e0e5a793SRichard Tran Mills { 462e0e5a793SRichard Tran Mills Mat_MPIKAIJ *a; 463e0e5a793SRichard Tran Mills Mat_MPIAIJ *mpiaij; 464e0e5a793SRichard Tran Mills PetscScalar *T; 465e0e5a793SRichard Tran Mills PetscInt i,j; 466e0e5a793SRichard Tran Mills PetscObjectState state; 467e0e5a793SRichard Tran Mills 468e0e5a793SRichard Tran Mills PetscFunctionBegin; 469e0e5a793SRichard Tran Mills a = (Mat_MPIKAIJ*)A->data; 470e0e5a793SRichard Tran Mills mpiaij = (Mat_MPIAIJ*)a->A->data; 471e0e5a793SRichard Tran Mills 4729566063dSJacob Faibussowitsch PetscCall(PetscObjectStateGet((PetscObject)a->A,&state)); 473e0e5a793SRichard Tran Mills if (state == a->state) { 474e0e5a793SRichard Tran Mills /* The existing AIJ and KAIJ members are up-to-date, so simply exit. */ 475e0e5a793SRichard Tran Mills PetscFunctionReturn(0); 476e0e5a793SRichard Tran Mills } else { 4779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&a->AIJ)); 4789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&a->OAIJ)); 479e0e5a793SRichard Tran Mills if (a->isTI) { 480e0e5a793SRichard Tran Mills /* If the transformation matrix associated with the parallel matrix A is the identity matrix, then a->T will be NULL. 481e0e5a793SRichard Tran Mills * In this case, if we pass a->T directly to the MatCreateKAIJ() calls to create the sequential submatrices, the routine will 482e0e5a793SRichard Tran Mills * not be able to tell that transformation matrix should be set to the identity; thus we create a temporary identity matrix 483e0e5a793SRichard Tran Mills * to pass in. */ 4849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(a->p*a->q,&T)); 485e0e5a793SRichard Tran Mills for (i=0; i<a->p; i++) { 486e0e5a793SRichard Tran Mills for (j=0; j<a->q; j++) { 487e0e5a793SRichard Tran Mills if (i==j) T[i+j*a->p] = 1.0; 488e0e5a793SRichard Tran Mills else T[i+j*a->p] = 0.0; 489e0e5a793SRichard Tran Mills } 490e0e5a793SRichard Tran Mills } 491e0e5a793SRichard Tran Mills } else T = a->T; 4929566063dSJacob Faibussowitsch PetscCall(MatCreateKAIJ(mpiaij->A,a->p,a->q,a->S,T,&a->AIJ)); 4939566063dSJacob Faibussowitsch PetscCall(MatCreateKAIJ(mpiaij->B,a->p,a->q,NULL,T,&a->OAIJ)); 4941baa6e33SBarry Smith if (a->isTI) PetscCall(PetscFree(T)); 495e0e5a793SRichard Tran Mills a->state = state; 496e0e5a793SRichard Tran Mills } 497e0e5a793SRichard Tran Mills 498e0e5a793SRichard Tran Mills PetscFunctionReturn(0); 499e0e5a793SRichard Tran Mills } 500e0e5a793SRichard Tran Mills 50149bd79ccSDebojyoti Ghosh PetscErrorCode MatSetUp_KAIJ(Mat A) 50249bd79ccSDebojyoti Ghosh { 5030567c835SRichard Tran Mills PetscInt n; 5040567c835SRichard Tran Mills PetscMPIInt size; 5050567c835SRichard Tran Mills Mat_SeqKAIJ *seqkaij = (Mat_SeqKAIJ*)A->data; 5060567c835SRichard Tran Mills 50749bd79ccSDebojyoti Ghosh PetscFunctionBegin; 5089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 5090567c835SRichard Tran Mills if (size == 1) { 5109566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A,seqkaij->p*seqkaij->AIJ->rmap->n,seqkaij->q*seqkaij->AIJ->cmap->n,seqkaij->p*seqkaij->AIJ->rmap->N,seqkaij->q*seqkaij->AIJ->cmap->N)); 5119566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(A->rmap,seqkaij->p)); 5129566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(A->cmap,seqkaij->q)); 5139566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 5149566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 5150567c835SRichard Tran Mills } else { 5160567c835SRichard Tran Mills Mat_MPIKAIJ *a; 5170567c835SRichard Tran Mills Mat_MPIAIJ *mpiaij; 5180567c835SRichard Tran Mills IS from,to; 5190567c835SRichard Tran Mills Vec gvec; 5200567c835SRichard Tran Mills 5210567c835SRichard Tran Mills a = (Mat_MPIKAIJ*)A->data; 522d3f912faSRichard Tran Mills mpiaij = (Mat_MPIAIJ*)a->A->data; 5239566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A,a->p*a->A->rmap->n,a->q*a->A->cmap->n,a->p*a->A->rmap->N,a->q*a->A->cmap->N)); 5249566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(A->rmap,seqkaij->p)); 5259566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(A->cmap,seqkaij->q)); 5269566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 5279566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 5280567c835SRichard Tran Mills 5299566063dSJacob Faibussowitsch PetscCall(MatKAIJ_build_AIJ_OAIJ(A)); 5300567c835SRichard Tran Mills 5319566063dSJacob Faibussowitsch PetscCall(VecGetSize(mpiaij->lvec,&n)); 5329566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF,&a->w)); 5339566063dSJacob Faibussowitsch PetscCall(VecSetSizes(a->w,n*a->q,n*a->q)); 5349566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(a->w,a->q)); 5359566063dSJacob Faibussowitsch PetscCall(VecSetType(a->w,VECSEQ)); 5360567c835SRichard Tran Mills 5370567c835SRichard Tran Mills /* create two temporary Index sets for build scatter gather */ 5389566063dSJacob Faibussowitsch PetscCall(ISCreateBlock(PetscObjectComm((PetscObject)a->A),a->q,n,mpiaij->garray,PETSC_COPY_VALUES,&from)); 5399566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF,n*a->q,0,1,&to)); 5400567c835SRichard Tran Mills 5410567c835SRichard Tran Mills /* create temporary global vector to generate scatter context */ 5429566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)a->A),a->q,a->q*a->A->cmap->n,a->q*a->A->cmap->N,NULL,&gvec)); 5430567c835SRichard Tran Mills 5440567c835SRichard Tran Mills /* generate the scatter context */ 5459566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(gvec,from,a->w,to,&a->ctx)); 5460567c835SRichard Tran Mills 5479566063dSJacob Faibussowitsch PetscCall(ISDestroy(&from)); 5489566063dSJacob Faibussowitsch PetscCall(ISDestroy(&to)); 5499566063dSJacob Faibussowitsch PetscCall(VecDestroy(&gvec)); 5500567c835SRichard Tran Mills } 5510567c835SRichard Tran Mills 5520567c835SRichard Tran Mills A->assembled = PETSC_TRUE; 55349bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 55449bd79ccSDebojyoti Ghosh } 55549bd79ccSDebojyoti Ghosh 556e6985dafSRichard Tran Mills PetscErrorCode MatView_KAIJ(Mat A,PetscViewer viewer) 55749bd79ccSDebojyoti Ghosh { 558e6985dafSRichard Tran Mills PetscViewerFormat format; 559e6985dafSRichard Tran Mills Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 56049bd79ccSDebojyoti Ghosh Mat B; 561e6985dafSRichard Tran Mills PetscInt i; 562e6985dafSRichard Tran Mills PetscBool ismpikaij; 56349bd79ccSDebojyoti Ghosh 56449bd79ccSDebojyoti Ghosh PetscFunctionBegin; 5659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMPIKAIJ,&ismpikaij)); 5669566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 567e6985dafSRichard Tran Mills if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_IMPL) { 5689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"S and T have %" PetscInt_FMT " rows and %" PetscInt_FMT " columns\n",a->p,a->q)); 569e6985dafSRichard Tran Mills 570e6985dafSRichard Tran Mills /* Print appropriate details for S. */ 571e6985dafSRichard Tran Mills if (!a->S) { 5729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"S is NULL\n")); 573e6985dafSRichard Tran Mills } else if (format == PETSC_VIEWER_ASCII_IMPL) { 5749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Entries of S are ")); 575e6985dafSRichard Tran Mills for (i=0; i<(a->p * a->q); i++) { 576e6985dafSRichard Tran Mills #if defined(PETSC_USE_COMPLEX) 5779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e ",(double)PetscRealPart(a->S[i]),(double)PetscImaginaryPart(a->S[i]))); 578e6985dafSRichard Tran Mills #else 5799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(a->S[i]))); 580e6985dafSRichard Tran Mills #endif 581e6985dafSRichard Tran Mills } 5829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 58349bd79ccSDebojyoti Ghosh } 58449bd79ccSDebojyoti Ghosh 585e6985dafSRichard Tran Mills /* Print appropriate details for T. */ 586e6985dafSRichard Tran Mills if (a->isTI) { 5879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"T is the identity matrix\n")); 588e6985dafSRichard Tran Mills } else if (!a->T) { 5899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"T is NULL\n")); 590e6985dafSRichard Tran Mills } else if (format == PETSC_VIEWER_ASCII_IMPL) { 5919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Entries of T are ")); 592e6985dafSRichard Tran Mills for (i=0; i<(a->p * a->q); i++) { 593e6985dafSRichard Tran Mills #if defined(PETSC_USE_COMPLEX) 5949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e ",(double)PetscRealPart(a->T[i]),(double)PetscImaginaryPart(a->T[i]))); 595e6985dafSRichard Tran Mills #else 5969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(a->T[i]))); 597e6985dafSRichard Tran Mills #endif 598e6985dafSRichard Tran Mills } 5999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 600e6985dafSRichard Tran Mills } 60149bd79ccSDebojyoti Ghosh 602e6985dafSRichard Tran Mills /* Now print details for the AIJ matrix, using the AIJ viewer. */ 6039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Now viewing the associated AIJ matrix:\n")); 604e6985dafSRichard Tran Mills if (ismpikaij) { 605e6985dafSRichard Tran Mills Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 6069566063dSJacob Faibussowitsch PetscCall(MatView(b->A,viewer)); 607e6985dafSRichard Tran Mills } else { 6089566063dSJacob Faibussowitsch PetscCall(MatView(a->AIJ,viewer)); 609e6985dafSRichard Tran Mills } 610e6985dafSRichard Tran Mills 611e6985dafSRichard Tran Mills } else { 612e6985dafSRichard Tran Mills /* For all other matrix viewer output formats, simply convert to an AIJ matrix and call MatView() on that. */ 6139566063dSJacob Faibussowitsch PetscCall(MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&B)); 6149566063dSJacob Faibussowitsch PetscCall(MatView(B,viewer)); 6159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 616e6985dafSRichard Tran Mills } 61749bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 61849bd79ccSDebojyoti Ghosh } 61949bd79ccSDebojyoti Ghosh 62049bd79ccSDebojyoti Ghosh PetscErrorCode MatDestroy_MPIKAIJ(Mat A) 62149bd79ccSDebojyoti Ghosh { 62249bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 62349bd79ccSDebojyoti Ghosh 62449bd79ccSDebojyoti Ghosh PetscFunctionBegin; 6259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&b->AIJ)); 6269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&b->OAIJ)); 6279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&b->A)); 6289566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&b->ctx)); 6299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b->w)); 6309566063dSJacob Faibussowitsch PetscCall(PetscFree(b->S)); 6319566063dSJacob Faibussowitsch PetscCall(PetscFree(b->T)); 6329566063dSJacob Faibussowitsch PetscCall(PetscFree(b->ibdiag)); 6339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatGetDiagonalBlock_C",NULL)); 6349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatConvert_mpikaij_mpiaij_C",NULL)); 6359566063dSJacob Faibussowitsch PetscCall(PetscFree(A->data)); 63649bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 63749bd79ccSDebojyoti Ghosh } 63849bd79ccSDebojyoti Ghosh 63949bd79ccSDebojyoti Ghosh /* --------------------------------------------------------------------------------------*/ 64049bd79ccSDebojyoti Ghosh 64149bd79ccSDebojyoti Ghosh /* zz = yy + Axx */ 642836168d5SRichard Tran Mills PetscErrorCode MatMultAdd_SeqKAIJ(Mat A,Vec xx,Vec yy,Vec zz) 64349bd79ccSDebojyoti Ghosh { 64449bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 64549bd79ccSDebojyoti Ghosh Mat_SeqAIJ *a = (Mat_SeqAIJ*)b->AIJ->data; 64649bd79ccSDebojyoti Ghosh const PetscScalar *s = b->S, *t = b->T; 64749bd79ccSDebojyoti Ghosh const PetscScalar *x,*v,*bx; 64849bd79ccSDebojyoti Ghosh PetscScalar *y,*sums; 64949bd79ccSDebojyoti Ghosh const PetscInt m = b->AIJ->rmap->n,*idx,*ii; 65049bd79ccSDebojyoti Ghosh PetscInt n,i,jrow,j,l,p=b->p,q=b->q,k; 65149bd79ccSDebojyoti Ghosh 65249bd79ccSDebojyoti Ghosh PetscFunctionBegin; 65349bd79ccSDebojyoti Ghosh if (!yy) { 6549566063dSJacob Faibussowitsch PetscCall(VecSet(zz,0.0)); 65549bd79ccSDebojyoti Ghosh } else { 6569566063dSJacob Faibussowitsch PetscCall(VecCopy(yy,zz)); 65749bd79ccSDebojyoti Ghosh } 65849bd79ccSDebojyoti Ghosh if ((!s) && (!t) && (!b->isTI)) PetscFunctionReturn(0); 65949bd79ccSDebojyoti Ghosh 6609566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx,&x)); 6619566063dSJacob Faibussowitsch PetscCall(VecGetArray(zz,&y)); 66249bd79ccSDebojyoti Ghosh idx = a->j; 66349bd79ccSDebojyoti Ghosh v = a->a; 66449bd79ccSDebojyoti Ghosh ii = a->i; 66549bd79ccSDebojyoti Ghosh 66649bd79ccSDebojyoti Ghosh if (b->isTI) { 66749bd79ccSDebojyoti Ghosh for (i=0; i<m; i++) { 66849bd79ccSDebojyoti Ghosh jrow = ii[i]; 66949bd79ccSDebojyoti Ghosh n = ii[i+1] - jrow; 67049bd79ccSDebojyoti Ghosh sums = y + p*i; 67149bd79ccSDebojyoti Ghosh for (j=0; j<n; j++) { 67249bd79ccSDebojyoti Ghosh for (k=0; k<p; k++) { 67349bd79ccSDebojyoti Ghosh sums[k] += v[jrow+j]*x[q*idx[jrow+j]+k]; 67449bd79ccSDebojyoti Ghosh } 67549bd79ccSDebojyoti Ghosh } 67649bd79ccSDebojyoti Ghosh } 6779566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(3.0*(a->nz)*p)); 67849bd79ccSDebojyoti Ghosh } else if (t) { 67949bd79ccSDebojyoti Ghosh for (i=0; i<m; i++) { 68049bd79ccSDebojyoti Ghosh jrow = ii[i]; 68149bd79ccSDebojyoti Ghosh n = ii[i+1] - jrow; 68249bd79ccSDebojyoti Ghosh sums = y + p*i; 68349bd79ccSDebojyoti Ghosh for (j=0; j<n; j++) { 68449bd79ccSDebojyoti Ghosh for (k=0; k<p; k++) { 68549bd79ccSDebojyoti Ghosh for (l=0; l<q; l++) { 68649bd79ccSDebojyoti Ghosh sums[k] += v[jrow+j]*t[k+l*p]*x[q*idx[jrow+j]+l]; 68749bd79ccSDebojyoti Ghosh } 68849bd79ccSDebojyoti Ghosh } 68949bd79ccSDebojyoti Ghosh } 69049bd79ccSDebojyoti Ghosh } 691234d9204SRichard Tran Mills /* The flop count below assumes that v[jrow+j] is hoisted out (which an optimizing compiler is likely to do), 692234d9204SRichard Tran Mills * and also that T part is hoisted outside this loop (in exchange for temporary storage) as (A \otimes I) (I \otimes T), 693234d9204SRichard Tran Mills * so that this multiply doesn't have to be redone for each matrix entry, but just once per column. The latter 694234d9204SRichard Tran Mills * transformation is much less likely to be applied, but we nonetheless count the minimum flops required. */ 6959566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0*p*q-p)*m+2.0*p*a->nz)); 69649bd79ccSDebojyoti Ghosh } 69749bd79ccSDebojyoti Ghosh if (s) { 69849bd79ccSDebojyoti Ghosh for (i=0; i<m; i++) { 69949bd79ccSDebojyoti Ghosh sums = y + p*i; 70049bd79ccSDebojyoti Ghosh bx = x + q*i; 70149bd79ccSDebojyoti Ghosh if (i < b->AIJ->cmap->n) { 70249bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 70349bd79ccSDebojyoti Ghosh for (k=0; k<p; k++) { 70449bd79ccSDebojyoti Ghosh sums[k] += s[k+j*p]*bx[j]; 70549bd79ccSDebojyoti Ghosh } 70649bd79ccSDebojyoti Ghosh } 70749bd79ccSDebojyoti Ghosh } 70849bd79ccSDebojyoti Ghosh } 7099566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*m*p*q)); 71049bd79ccSDebojyoti Ghosh } 71149bd79ccSDebojyoti Ghosh 7129566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx,&x)); 7139566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(zz,&y)); 71449bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 71549bd79ccSDebojyoti Ghosh } 71649bd79ccSDebojyoti Ghosh 717bb6fb833SRichard Tran Mills PetscErrorCode MatMult_SeqKAIJ(Mat A,Vec xx,Vec yy) 71849bd79ccSDebojyoti Ghosh { 71949bd79ccSDebojyoti Ghosh PetscFunctionBegin; 7209566063dSJacob Faibussowitsch PetscCall(MatMultAdd_SeqKAIJ(A,xx,PETSC_NULL,yy)); 72149bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 72249bd79ccSDebojyoti Ghosh } 72349bd79ccSDebojyoti Ghosh 72449bd79ccSDebojyoti Ghosh #include <petsc/private/kernels/blockinvert.h> 72549bd79ccSDebojyoti Ghosh 726bb6fb833SRichard Tran Mills PetscErrorCode MatInvertBlockDiagonal_SeqKAIJ(Mat A,const PetscScalar **values) 72749bd79ccSDebojyoti Ghosh { 72849bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*)A->data; 72949bd79ccSDebojyoti Ghosh Mat_SeqAIJ *a = (Mat_SeqAIJ*)b->AIJ->data; 73049bd79ccSDebojyoti Ghosh const PetscScalar *S = b->S; 73149bd79ccSDebojyoti Ghosh const PetscScalar *T = b->T; 73249bd79ccSDebojyoti Ghosh const PetscScalar *v = a->a; 73349bd79ccSDebojyoti Ghosh const PetscInt p = b->p, q = b->q, m = b->AIJ->rmap->n, *idx = a->j, *ii = a->i; 73449bd79ccSDebojyoti Ghosh PetscInt i,j,*v_pivots,dof,dof2; 73549bd79ccSDebojyoti Ghosh PetscScalar *diag,aval,*v_work; 73649bd79ccSDebojyoti Ghosh 73749bd79ccSDebojyoti Ghosh PetscFunctionBegin; 73808401ef6SPierre Jolivet PetscCheck(p == q,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MATKAIJ: Block size must be square to calculate inverse."); 739aed4548fSBarry Smith PetscCheck(S || T || b->isTI,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MATKAIJ: Cannot invert a zero matrix."); 74049bd79ccSDebojyoti Ghosh 74149bd79ccSDebojyoti Ghosh dof = p; 74249bd79ccSDebojyoti Ghosh dof2 = dof*dof; 74349bd79ccSDebojyoti Ghosh 74449bd79ccSDebojyoti Ghosh if (b->ibdiagvalid) { 74549bd79ccSDebojyoti Ghosh if (values) *values = b->ibdiag; 74649bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 74749bd79ccSDebojyoti Ghosh } 74849bd79ccSDebojyoti Ghosh if (!b->ibdiag) { 7499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dof2*m,&b->ibdiag)); 7509566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,dof2*m*sizeof(PetscScalar))); 75149bd79ccSDebojyoti Ghosh } 75249bd79ccSDebojyoti Ghosh if (values) *values = b->ibdiag; 75349bd79ccSDebojyoti Ghosh diag = b->ibdiag; 75449bd79ccSDebojyoti Ghosh 7559566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(dof,&v_work,dof,&v_pivots)); 75649bd79ccSDebojyoti Ghosh for (i=0; i<m; i++) { 75749bd79ccSDebojyoti Ghosh if (S) { 7589566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(diag,S,dof2*sizeof(PetscScalar))); 75949bd79ccSDebojyoti Ghosh } else { 7609566063dSJacob Faibussowitsch PetscCall(PetscMemzero(diag,dof2*sizeof(PetscScalar))); 76149bd79ccSDebojyoti Ghosh } 76249bd79ccSDebojyoti Ghosh if (b->isTI) { 76349bd79ccSDebojyoti Ghosh aval = 0; 76449bd79ccSDebojyoti Ghosh for (j=ii[i]; j<ii[i+1]; j++) if (idx[j] == i) aval = v[j]; 76549bd79ccSDebojyoti Ghosh for (j=0; j<dof; j++) diag[j+dof*j] += aval; 76649bd79ccSDebojyoti Ghosh } else if (T) { 76749bd79ccSDebojyoti Ghosh aval = 0; 76849bd79ccSDebojyoti Ghosh for (j=ii[i]; j<ii[i+1]; j++) if (idx[j] == i) aval = v[j]; 76949bd79ccSDebojyoti Ghosh for (j=0; j<dof2; j++) diag[j] += aval*T[j]; 77049bd79ccSDebojyoti Ghosh } 7719566063dSJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(dof,diag,v_pivots,v_work,PETSC_FALSE,NULL)); 77249bd79ccSDebojyoti Ghosh diag += dof2; 77349bd79ccSDebojyoti Ghosh } 7749566063dSJacob Faibussowitsch PetscCall(PetscFree2(v_work,v_pivots)); 77549bd79ccSDebojyoti Ghosh 77649bd79ccSDebojyoti Ghosh b->ibdiagvalid = PETSC_TRUE; 77749bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 77849bd79ccSDebojyoti Ghosh } 77949bd79ccSDebojyoti Ghosh 78049bd79ccSDebojyoti Ghosh static PetscErrorCode MatGetDiagonalBlock_MPIKAIJ(Mat A,Mat *B) 78149bd79ccSDebojyoti Ghosh { 78249bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *kaij = (Mat_MPIKAIJ*) A->data; 78349bd79ccSDebojyoti Ghosh 78449bd79ccSDebojyoti Ghosh PetscFunctionBegin; 78549bd79ccSDebojyoti Ghosh *B = kaij->AIJ; 78649bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 78749bd79ccSDebojyoti Ghosh } 78849bd79ccSDebojyoti Ghosh 789fac53fa1SPierre Jolivet static PetscErrorCode MatConvert_KAIJ_AIJ(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 790fac53fa1SPierre Jolivet { 791fac53fa1SPierre Jolivet Mat_SeqKAIJ *a = (Mat_SeqKAIJ*)A->data; 792fac53fa1SPierre Jolivet Mat AIJ,OAIJ,B; 793fac53fa1SPierre Jolivet PetscInt *d_nnz,*o_nnz = NULL,nz,i,j,m,d; 794fac53fa1SPierre Jolivet const PetscInt p = a->p,q = a->q; 795fac53fa1SPierre Jolivet PetscBool ismpikaij,missing; 796fac53fa1SPierre Jolivet 797fac53fa1SPierre Jolivet PetscFunctionBegin; 798fac53fa1SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 7999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMPIKAIJ,&ismpikaij)); 800fac53fa1SPierre Jolivet if (ismpikaij) { 801fac53fa1SPierre Jolivet Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 802fac53fa1SPierre Jolivet AIJ = ((Mat_SeqKAIJ*)b->AIJ->data)->AIJ; 803fac53fa1SPierre Jolivet OAIJ = ((Mat_SeqKAIJ*)b->OAIJ->data)->AIJ; 804fac53fa1SPierre Jolivet } else { 805fac53fa1SPierre Jolivet AIJ = a->AIJ; 806fac53fa1SPierre Jolivet OAIJ = NULL; 807fac53fa1SPierre Jolivet } 8089566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 8099566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N)); 8109566063dSJacob Faibussowitsch PetscCall(MatSetType(B,MATAIJ)); 8119566063dSJacob Faibussowitsch PetscCall(MatGetSize(AIJ,&m,NULL)); 8129566063dSJacob Faibussowitsch PetscCall(MatMissingDiagonal(AIJ,&missing,&d)); /* assumption that all successive rows will have a missing diagonal */ 813fac53fa1SPierre Jolivet if (!missing || !a->S) d = m; 8149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m*p,&d_nnz)); 815fac53fa1SPierre Jolivet for (i = 0; i < m; ++i) { 8169566063dSJacob Faibussowitsch PetscCall(MatGetRow_SeqAIJ(AIJ,i,&nz,NULL,NULL)); 817fac53fa1SPierre Jolivet for (j = 0; j < p; ++j) d_nnz[i*p + j] = nz*q + (i >= d)*q; 8189566063dSJacob Faibussowitsch PetscCall(MatRestoreRow_SeqAIJ(AIJ,i,&nz,NULL,NULL)); 819fac53fa1SPierre Jolivet } 820fac53fa1SPierre Jolivet if (OAIJ) { 8219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m*p,&o_nnz)); 822fac53fa1SPierre Jolivet for (i = 0; i < m; ++i) { 8239566063dSJacob Faibussowitsch PetscCall(MatGetRow_SeqAIJ(OAIJ,i,&nz,NULL,NULL)); 824fac53fa1SPierre Jolivet for (j = 0; j < p; ++j) o_nnz[i*p + j] = nz*q; 8259566063dSJacob Faibussowitsch PetscCall(MatRestoreRow_SeqAIJ(OAIJ,i,&nz,NULL,NULL)); 826fac53fa1SPierre Jolivet } 8279566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(B,0,d_nnz,0,o_nnz)); 828fac53fa1SPierre Jolivet } else { 8299566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B,0,d_nnz)); 830fac53fa1SPierre Jolivet } 8319566063dSJacob Faibussowitsch PetscCall(PetscFree(d_nnz)); 8329566063dSJacob Faibussowitsch PetscCall(PetscFree(o_nnz)); 833fac53fa1SPierre Jolivet } else B = *newmat; 8349566063dSJacob Faibussowitsch PetscCall(MatConvert_Basic(A,newtype,MAT_REUSE_MATRIX,&B)); 835fac53fa1SPierre Jolivet if (reuse == MAT_INPLACE_MATRIX) { 8369566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A,&B)); 837fac53fa1SPierre Jolivet } else *newmat = B; 838fac53fa1SPierre Jolivet PetscFunctionReturn(0); 839fac53fa1SPierre Jolivet } 840fac53fa1SPierre Jolivet 84149bd79ccSDebojyoti Ghosh PetscErrorCode MatSOR_SeqKAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 84249bd79ccSDebojyoti Ghosh { 84349bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *kaij = (Mat_SeqKAIJ*) A->data; 84449bd79ccSDebojyoti Ghosh Mat_SeqAIJ *a = (Mat_SeqAIJ*)kaij->AIJ->data; 84549bd79ccSDebojyoti Ghosh const PetscScalar *aa = a->a, *T = kaij->T, *v; 84649bd79ccSDebojyoti Ghosh const PetscInt m = kaij->AIJ->rmap->n, *ai=a->i, *aj=a->j, p = kaij->p, q = kaij->q, *diag, *vi; 84749bd79ccSDebojyoti Ghosh const PetscScalar *b, *xb, *idiag; 84849bd79ccSDebojyoti Ghosh PetscScalar *x, *work, *workt, *w, *y, *arr, *t, *arrt; 84949bd79ccSDebojyoti Ghosh PetscInt i, j, k, i2, bs, bs2, nz; 85049bd79ccSDebojyoti Ghosh 85149bd79ccSDebojyoti Ghosh PetscFunctionBegin; 85249bd79ccSDebojyoti Ghosh its = its*lits; 853aed4548fSBarry Smith PetscCheck(!(flag & SOR_EISENSTAT),PETSC_COMM_SELF,PETSC_ERR_SUP,"No support yet for Eisenstat"); 85408401ef6SPierre Jolivet PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive",its,lits); 85528b400f6SJacob Faibussowitsch PetscCheck(!fshift,PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for diagonal shift"); 85608401ef6SPierre Jolivet PetscCheck(!(flag & SOR_APPLY_UPPER) && !(flag & SOR_APPLY_LOWER),PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for applying upper or lower triangular parts"); 85708401ef6SPierre Jolivet PetscCheck(p == q,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatSOR for KAIJ: No support for non-square dense blocks"); 858*f7d195e4SLawrence Mitchell bs = p; 859*f7d195e4SLawrence Mitchell bs2 = bs*bs; 86049bd79ccSDebojyoti Ghosh 86149bd79ccSDebojyoti Ghosh if (!m) PetscFunctionReturn(0); 86249bd79ccSDebojyoti Ghosh 8639566063dSJacob Faibussowitsch if (!kaij->ibdiagvalid) PetscCall(MatInvertBlockDiagonal_SeqKAIJ(A,NULL)); 86449bd79ccSDebojyoti Ghosh idiag = kaij->ibdiag; 86549bd79ccSDebojyoti Ghosh diag = a->diag; 86649bd79ccSDebojyoti Ghosh 86749bd79ccSDebojyoti Ghosh if (!kaij->sor.setup) { 8689566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(bs,&kaij->sor.w,bs,&kaij->sor.y,m*bs,&kaij->sor.work,m*bs,&kaij->sor.t,m*bs2,&kaij->sor.arr)); 86949bd79ccSDebojyoti Ghosh kaij->sor.setup = PETSC_TRUE; 87049bd79ccSDebojyoti Ghosh } 87149bd79ccSDebojyoti Ghosh y = kaij->sor.y; 87249bd79ccSDebojyoti Ghosh w = kaij->sor.w; 87349bd79ccSDebojyoti Ghosh work = kaij->sor.work; 87449bd79ccSDebojyoti Ghosh t = kaij->sor.t; 87549bd79ccSDebojyoti Ghosh arr = kaij->sor.arr; 87649bd79ccSDebojyoti Ghosh 877d0609cedSBarry Smith PetscCall( VecGetArray(xx,&x)); 8789566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb,&b)); 87949bd79ccSDebojyoti Ghosh 88049bd79ccSDebojyoti Ghosh if (flag & SOR_ZERO_INITIAL_GUESS) { 88149bd79ccSDebojyoti Ghosh if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 88249bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,b,idiag,x); /* x[0:bs] <- D^{-1} b[0:bs] */ 8839566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(t,b,bs*sizeof(PetscScalar))); 88449bd79ccSDebojyoti Ghosh i2 = bs; 88549bd79ccSDebojyoti Ghosh idiag += bs2; 88649bd79ccSDebojyoti Ghosh for (i=1; i<m; i++) { 88749bd79ccSDebojyoti Ghosh v = aa + ai[i]; 88849bd79ccSDebojyoti Ghosh vi = aj + ai[i]; 88949bd79ccSDebojyoti Ghosh nz = diag[i] - ai[i]; 89049bd79ccSDebojyoti Ghosh 89149bd79ccSDebojyoti Ghosh if (T) { /* b - T (Arow * x) */ 8929566063dSJacob Faibussowitsch PetscCall(PetscMemzero(w,bs*sizeof(PetscScalar))); 89349bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 89449bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) w[k] -= v[j] * x[vi[j]*bs+k]; 89549bd79ccSDebojyoti Ghosh } 89649bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs,w,T,&t[i2]); 89749bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) t[i2+k] += b[i2+k]; 89849bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 8999566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(t+i2,b+i2,bs*sizeof(PetscScalar))); 90049bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 90149bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) t[i2+k] -= v[j] * x[vi[j]*bs+k]; 90249bd79ccSDebojyoti Ghosh } 90349bd79ccSDebojyoti Ghosh } else { 9049566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(t+i2,b+i2,bs*sizeof(PetscScalar))); 90549bd79ccSDebojyoti Ghosh } 90649bd79ccSDebojyoti Ghosh 90749bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,t+i2,idiag,y); 90849bd79ccSDebojyoti Ghosh for (j=0; j<bs; j++) x[i2+j] = omega * y[j]; 90949bd79ccSDebojyoti Ghosh 91049bd79ccSDebojyoti Ghosh idiag += bs2; 91149bd79ccSDebojyoti Ghosh i2 += bs; 91249bd79ccSDebojyoti Ghosh } 91349bd79ccSDebojyoti Ghosh /* for logging purposes assume number of nonzero in lower half is 1/2 of total */ 9149566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*bs2*a->nz)); 91549bd79ccSDebojyoti Ghosh xb = t; 91649bd79ccSDebojyoti Ghosh } else xb = b; 91749bd79ccSDebojyoti Ghosh if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 91849bd79ccSDebojyoti Ghosh idiag = kaij->ibdiag+bs2*(m-1); 91949bd79ccSDebojyoti Ghosh i2 = bs * (m-1); 9209566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,xb+i2,bs*sizeof(PetscScalar))); 92149bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,w,idiag,x+i2); 92249bd79ccSDebojyoti Ghosh i2 -= bs; 92349bd79ccSDebojyoti Ghosh idiag -= bs2; 92449bd79ccSDebojyoti Ghosh for (i=m-2; i>=0; i--) { 92549bd79ccSDebojyoti Ghosh v = aa + diag[i] + 1 ; 92649bd79ccSDebojyoti Ghosh vi = aj + diag[i] + 1; 92749bd79ccSDebojyoti Ghosh nz = ai[i+1] - diag[i] - 1; 92849bd79ccSDebojyoti Ghosh 92949bd79ccSDebojyoti Ghosh if (T) { /* FIXME: This branch untested */ 9309566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,xb+i2,bs*sizeof(PetscScalar))); 93149bd79ccSDebojyoti Ghosh /* copy all rows of x that are needed into contiguous space */ 93249bd79ccSDebojyoti Ghosh workt = work; 93349bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9349566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 93549bd79ccSDebojyoti Ghosh workt += bs; 93649bd79ccSDebojyoti Ghosh } 93749bd79ccSDebojyoti Ghosh arrt = arr; 93849bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9399566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 94049bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 94149bd79ccSDebojyoti Ghosh arrt += bs2; 94249bd79ccSDebojyoti Ghosh } 94349bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 94449bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 9459566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,t+i2,bs*sizeof(PetscScalar))); 94649bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 94749bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) w[k] -= v[j] * x[vi[j]*bs+k]; 94849bd79ccSDebojyoti Ghosh } 94949bd79ccSDebojyoti Ghosh } 95049bd79ccSDebojyoti Ghosh 95149bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,w,idiag,y); /* RHS incorrect for omega != 1.0 */ 95249bd79ccSDebojyoti Ghosh for (j=0; j<bs; j++) x[i2+j] = (1.0-omega) * x[i2+j] + omega * y[j]; 95349bd79ccSDebojyoti Ghosh 95449bd79ccSDebojyoti Ghosh idiag -= bs2; 95549bd79ccSDebojyoti Ghosh i2 -= bs; 95649bd79ccSDebojyoti Ghosh } 9579566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*bs2*(a->nz))); 95849bd79ccSDebojyoti Ghosh } 95949bd79ccSDebojyoti Ghosh its--; 96049bd79ccSDebojyoti Ghosh } 96149bd79ccSDebojyoti Ghosh while (its--) { /* FIXME: This branch not updated */ 96249bd79ccSDebojyoti Ghosh if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 96349bd79ccSDebojyoti Ghosh i2 = 0; 96449bd79ccSDebojyoti Ghosh idiag = kaij->ibdiag; 96549bd79ccSDebojyoti Ghosh for (i=0; i<m; i++) { 9669566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,b+i2,bs*sizeof(PetscScalar))); 96749bd79ccSDebojyoti Ghosh 96849bd79ccSDebojyoti Ghosh v = aa + ai[i]; 96949bd79ccSDebojyoti Ghosh vi = aj + ai[i]; 97049bd79ccSDebojyoti Ghosh nz = diag[i] - ai[i]; 97149bd79ccSDebojyoti Ghosh workt = work; 97249bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9739566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 97449bd79ccSDebojyoti Ghosh workt += bs; 97549bd79ccSDebojyoti Ghosh } 97649bd79ccSDebojyoti Ghosh arrt = arr; 97749bd79ccSDebojyoti Ghosh if (T) { 97849bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9799566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 98049bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 98149bd79ccSDebojyoti Ghosh arrt += bs2; 98249bd79ccSDebojyoti Ghosh } 98349bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 98449bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 98549bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9869566063dSJacob Faibussowitsch PetscCall(PetscMemzero(arrt,bs2*sizeof(PetscScalar))); 98749bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) arrt[k+bs*k] = v[j]; 98849bd79ccSDebojyoti Ghosh arrt += bs2; 98949bd79ccSDebojyoti Ghosh } 99049bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 99149bd79ccSDebojyoti Ghosh } 9929566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(t+i2,w,bs*sizeof(PetscScalar))); 99349bd79ccSDebojyoti Ghosh 99449bd79ccSDebojyoti Ghosh v = aa + diag[i] + 1; 99549bd79ccSDebojyoti Ghosh vi = aj + diag[i] + 1; 99649bd79ccSDebojyoti Ghosh nz = ai[i+1] - diag[i] - 1; 99749bd79ccSDebojyoti Ghosh workt = work; 99849bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 9999566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 100049bd79ccSDebojyoti Ghosh workt += bs; 100149bd79ccSDebojyoti Ghosh } 100249bd79ccSDebojyoti Ghosh arrt = arr; 100349bd79ccSDebojyoti Ghosh if (T) { 100449bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10059566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 100649bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 100749bd79ccSDebojyoti Ghosh arrt += bs2; 100849bd79ccSDebojyoti Ghosh } 100949bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 101049bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 101149bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10129566063dSJacob Faibussowitsch PetscCall(PetscMemzero(arrt,bs2*sizeof(PetscScalar))); 101349bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) arrt[k+bs*k] = v[j]; 101449bd79ccSDebojyoti Ghosh arrt += bs2; 101549bd79ccSDebojyoti Ghosh } 101649bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 101749bd79ccSDebojyoti Ghosh } 101849bd79ccSDebojyoti Ghosh 101949bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,w,idiag,y); 102049bd79ccSDebojyoti Ghosh for (j=0; j<bs; j++) *(x+i2+j) = (1.0-omega) * *(x+i2+j) + omega * *(y+j); 102149bd79ccSDebojyoti Ghosh 102249bd79ccSDebojyoti Ghosh idiag += bs2; 102349bd79ccSDebojyoti Ghosh i2 += bs; 102449bd79ccSDebojyoti Ghosh } 102549bd79ccSDebojyoti Ghosh xb = t; 102649bd79ccSDebojyoti Ghosh } 102749bd79ccSDebojyoti Ghosh else xb = b; 102849bd79ccSDebojyoti Ghosh if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 102949bd79ccSDebojyoti Ghosh idiag = kaij->ibdiag+bs2*(m-1); 103049bd79ccSDebojyoti Ghosh i2 = bs * (m-1); 103149bd79ccSDebojyoti Ghosh if (xb == b) { 103249bd79ccSDebojyoti Ghosh for (i=m-1; i>=0; i--) { 10339566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,b+i2,bs*sizeof(PetscScalar))); 103449bd79ccSDebojyoti Ghosh 103549bd79ccSDebojyoti Ghosh v = aa + ai[i]; 103649bd79ccSDebojyoti Ghosh vi = aj + ai[i]; 103749bd79ccSDebojyoti Ghosh nz = diag[i] - ai[i]; 103849bd79ccSDebojyoti Ghosh workt = work; 103949bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10409566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 104149bd79ccSDebojyoti Ghosh workt += bs; 104249bd79ccSDebojyoti Ghosh } 104349bd79ccSDebojyoti Ghosh arrt = arr; 104449bd79ccSDebojyoti Ghosh if (T) { 104549bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10469566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 104749bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 104849bd79ccSDebojyoti Ghosh arrt += bs2; 104949bd79ccSDebojyoti Ghosh } 105049bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 105149bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 105249bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10539566063dSJacob Faibussowitsch PetscCall(PetscMemzero(arrt,bs2*sizeof(PetscScalar))); 105449bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) arrt[k+bs*k] = v[j]; 105549bd79ccSDebojyoti Ghosh arrt += bs2; 105649bd79ccSDebojyoti Ghosh } 105749bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 105849bd79ccSDebojyoti Ghosh } 105949bd79ccSDebojyoti Ghosh 106049bd79ccSDebojyoti Ghosh v = aa + diag[i] + 1; 106149bd79ccSDebojyoti Ghosh vi = aj + diag[i] + 1; 106249bd79ccSDebojyoti Ghosh nz = ai[i+1] - diag[i] - 1; 106349bd79ccSDebojyoti Ghosh workt = work; 106449bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10659566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 106649bd79ccSDebojyoti Ghosh workt += bs; 106749bd79ccSDebojyoti Ghosh } 106849bd79ccSDebojyoti Ghosh arrt = arr; 106949bd79ccSDebojyoti Ghosh if (T) { 107049bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10719566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 107249bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 107349bd79ccSDebojyoti Ghosh arrt += bs2; 107449bd79ccSDebojyoti Ghosh } 107549bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 107649bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 107749bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10789566063dSJacob Faibussowitsch PetscCall(PetscMemzero(arrt,bs2*sizeof(PetscScalar))); 107949bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) arrt[k+bs*k] = v[j]; 108049bd79ccSDebojyoti Ghosh arrt += bs2; 108149bd79ccSDebojyoti Ghosh } 108249bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 108349bd79ccSDebojyoti Ghosh } 108449bd79ccSDebojyoti Ghosh 108549bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,w,idiag,y); 108649bd79ccSDebojyoti Ghosh for (j=0; j<bs; j++) *(x+i2+j) = (1.0-omega) * *(x+i2+j) + omega * *(y+j); 108749bd79ccSDebojyoti Ghosh } 108849bd79ccSDebojyoti Ghosh } else { 108949bd79ccSDebojyoti Ghosh for (i=m-1; i>=0; i--) { 10909566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(w,xb+i2,bs*sizeof(PetscScalar))); 109149bd79ccSDebojyoti Ghosh v = aa + diag[i] + 1; 109249bd79ccSDebojyoti Ghosh vi = aj + diag[i] + 1; 109349bd79ccSDebojyoti Ghosh nz = ai[i+1] - diag[i] - 1; 109449bd79ccSDebojyoti Ghosh workt = work; 109549bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 10969566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(workt,x + bs*(*vi++),bs*sizeof(PetscScalar))); 109749bd79ccSDebojyoti Ghosh workt += bs; 109849bd79ccSDebojyoti Ghosh } 109949bd79ccSDebojyoti Ghosh arrt = arr; 110049bd79ccSDebojyoti Ghosh if (T) { 110149bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 11029566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(arrt,T,bs2*sizeof(PetscScalar))); 110349bd79ccSDebojyoti Ghosh for (k=0; k<bs2; k++) arrt[k] *= v[j]; 110449bd79ccSDebojyoti Ghosh arrt += bs2; 110549bd79ccSDebojyoti Ghosh } 110649bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 110749bd79ccSDebojyoti Ghosh } else if (kaij->isTI) { 110849bd79ccSDebojyoti Ghosh for (j=0; j<nz; j++) { 11099566063dSJacob Faibussowitsch PetscCall(PetscMemzero(arrt,bs2*sizeof(PetscScalar))); 111049bd79ccSDebojyoti Ghosh for (k=0; k<bs; k++) arrt[k+bs*k] = v[j]; 111149bd79ccSDebojyoti Ghosh arrt += bs2; 111249bd79ccSDebojyoti Ghosh } 111349bd79ccSDebojyoti Ghosh PetscKernel_w_gets_w_minus_Ar_times_v(bs,bs*nz,w,arr,work); 111449bd79ccSDebojyoti Ghosh } 111549bd79ccSDebojyoti Ghosh PetscKernel_w_gets_Ar_times_v(bs,bs,w,idiag,y); 111649bd79ccSDebojyoti Ghosh for (j=0; j<bs; j++) *(x+i2+j) = (1.0-omega) * *(x+i2+j) + omega * *(y+j); 111749bd79ccSDebojyoti Ghosh } 111849bd79ccSDebojyoti Ghosh } 11199566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*bs2*(a->nz))); 112049bd79ccSDebojyoti Ghosh } 112149bd79ccSDebojyoti Ghosh } 112249bd79ccSDebojyoti Ghosh 1123d0609cedSBarry Smith PetscCall(VecRestoreArray(xx,&x)); 11249566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb,&b)); 112549bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 112649bd79ccSDebojyoti Ghosh } 112749bd79ccSDebojyoti Ghosh 112849bd79ccSDebojyoti Ghosh /*===================================================================================*/ 112949bd79ccSDebojyoti Ghosh 1130836168d5SRichard Tran Mills PetscErrorCode MatMultAdd_MPIKAIJ(Mat A,Vec xx,Vec yy,Vec zz) 113149bd79ccSDebojyoti Ghosh { 113249bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 113349bd79ccSDebojyoti Ghosh 113449bd79ccSDebojyoti Ghosh PetscFunctionBegin; 113549bd79ccSDebojyoti Ghosh if (!yy) { 11369566063dSJacob Faibussowitsch PetscCall(VecSet(zz,0.0)); 113749bd79ccSDebojyoti Ghosh } else { 11389566063dSJacob Faibussowitsch PetscCall(VecCopy(yy,zz)); 113949bd79ccSDebojyoti Ghosh } 11409566063dSJacob Faibussowitsch PetscCall(MatKAIJ_build_AIJ_OAIJ(A)); /* Ensure b->AIJ and b->OAIJ are up to date. */ 114149bd79ccSDebojyoti Ghosh /* start the scatter */ 11429566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(b->ctx,xx,b->w,INSERT_VALUES,SCATTER_FORWARD)); 11439566063dSJacob Faibussowitsch PetscCall((*b->AIJ->ops->multadd)(b->AIJ,xx,zz,zz)); 11449566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(b->ctx,xx,b->w,INSERT_VALUES,SCATTER_FORWARD)); 11459566063dSJacob Faibussowitsch PetscCall((*b->OAIJ->ops->multadd)(b->OAIJ,b->w,zz,zz)); 114649bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 114749bd79ccSDebojyoti Ghosh } 114849bd79ccSDebojyoti Ghosh 1149bb6fb833SRichard Tran Mills PetscErrorCode MatMult_MPIKAIJ(Mat A,Vec xx,Vec yy) 115049bd79ccSDebojyoti Ghosh { 115149bd79ccSDebojyoti Ghosh PetscFunctionBegin; 11529566063dSJacob Faibussowitsch PetscCall(MatMultAdd_MPIKAIJ(A,xx,PETSC_NULL,yy)); 115349bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 115449bd79ccSDebojyoti Ghosh } 115549bd79ccSDebojyoti Ghosh 1156bb6fb833SRichard Tran Mills PetscErrorCode MatInvertBlockDiagonal_MPIKAIJ(Mat A,const PetscScalar **values) 115749bd79ccSDebojyoti Ghosh { 115849bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *b = (Mat_MPIKAIJ*)A->data; 115949bd79ccSDebojyoti Ghosh 116049bd79ccSDebojyoti Ghosh PetscFunctionBegin; 11619566063dSJacob Faibussowitsch PetscCall(MatKAIJ_build_AIJ_OAIJ(A)); /* Ensure b->AIJ is up to date. */ 11629566063dSJacob Faibussowitsch PetscCall((*b->AIJ->ops->invertblockdiagonal)(b->AIJ,values)); 116349bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 116449bd79ccSDebojyoti Ghosh } 116549bd79ccSDebojyoti Ghosh 116649bd79ccSDebojyoti Ghosh /* ----------------------------------------------------------------*/ 116749bd79ccSDebojyoti Ghosh 116849bd79ccSDebojyoti Ghosh PetscErrorCode MatGetRow_SeqKAIJ(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **values) 116949bd79ccSDebojyoti Ghosh { 117049bd79ccSDebojyoti Ghosh Mat_SeqKAIJ *b = (Mat_SeqKAIJ*) A->data; 11711ca5ffdbSRichard Tran Mills PetscErrorCode diag = PETSC_FALSE; 117249bd79ccSDebojyoti Ghosh PetscInt nzaij,nz,*colsaij,*idx,i,j,p=b->p,q=b->q,r=row/p,s=row%p,c; 117349bd79ccSDebojyoti Ghosh PetscScalar *vaij,*v,*S=b->S,*T=b->T; 117449bd79ccSDebojyoti Ghosh 117549bd79ccSDebojyoti Ghosh PetscFunctionBegin; 117628b400f6SJacob Faibussowitsch PetscCheck(!b->getrowactive,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Already active"); 117749bd79ccSDebojyoti Ghosh b->getrowactive = PETSC_TRUE; 1178aed4548fSBarry Smith PetscCheck(row >= 0 && row < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " out of range",row); 117949bd79ccSDebojyoti Ghosh 118049bd79ccSDebojyoti Ghosh if ((!S) && (!T) && (!b->isTI)) { 118149bd79ccSDebojyoti Ghosh if (ncols) *ncols = 0; 118249bd79ccSDebojyoti Ghosh if (cols) *cols = NULL; 118349bd79ccSDebojyoti Ghosh if (values) *values = NULL; 118449bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 118549bd79ccSDebojyoti Ghosh } 118649bd79ccSDebojyoti Ghosh 118749bd79ccSDebojyoti Ghosh if (T || b->isTI) { 11889566063dSJacob Faibussowitsch PetscCall(MatGetRow_SeqAIJ(b->AIJ,r,&nzaij,&colsaij,&vaij)); 118949bd79ccSDebojyoti Ghosh c = nzaij; 119049bd79ccSDebojyoti Ghosh for (i=0; i<nzaij; i++) { 119149bd79ccSDebojyoti Ghosh /* check if this row contains a diagonal entry */ 119249bd79ccSDebojyoti Ghosh if (colsaij[i] == r) { 119349bd79ccSDebojyoti Ghosh diag = PETSC_TRUE; 119449bd79ccSDebojyoti Ghosh c = i; 119549bd79ccSDebojyoti Ghosh } 119649bd79ccSDebojyoti Ghosh } 119749bd79ccSDebojyoti Ghosh } else nzaij = c = 0; 119849bd79ccSDebojyoti Ghosh 119949bd79ccSDebojyoti Ghosh /* calculate size of row */ 120049bd79ccSDebojyoti Ghosh nz = 0; 120149bd79ccSDebojyoti Ghosh if (S) nz += q; 120249bd79ccSDebojyoti Ghosh if (T || b->isTI) nz += (diag && S ? (nzaij-1)*q : nzaij*q); 120349bd79ccSDebojyoti Ghosh 120449bd79ccSDebojyoti Ghosh if (cols || values) { 12059566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nz,&idx,nz,&v)); 120638822f9dSRichard Tran Mills for (i=0; i<q; i++) { 120738822f9dSRichard Tran Mills /* We need to initialize the v[i] to zero to handle the case in which T is NULL (not the identity matrix). */ 120838822f9dSRichard Tran Mills v[i] = 0.0; 120938822f9dSRichard Tran Mills } 121049bd79ccSDebojyoti Ghosh if (b->isTI) { 121149bd79ccSDebojyoti Ghosh for (i=0; i<nzaij; i++) { 121249bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 121349bd79ccSDebojyoti Ghosh idx[i*q+j] = colsaij[i]*q+j; 121449bd79ccSDebojyoti Ghosh v[i*q+j] = (j==s ? vaij[i] : 0); 121549bd79ccSDebojyoti Ghosh } 121649bd79ccSDebojyoti Ghosh } 121749bd79ccSDebojyoti Ghosh } else if (T) { 121849bd79ccSDebojyoti Ghosh for (i=0; i<nzaij; i++) { 121949bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 122049bd79ccSDebojyoti Ghosh idx[i*q+j] = colsaij[i]*q+j; 122149bd79ccSDebojyoti Ghosh v[i*q+j] = vaij[i]*T[s+j*p]; 122249bd79ccSDebojyoti Ghosh } 122349bd79ccSDebojyoti Ghosh } 122449bd79ccSDebojyoti Ghosh } 122549bd79ccSDebojyoti Ghosh if (S) { 122649bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 122749bd79ccSDebojyoti Ghosh idx[c*q+j] = r*q+j; 122849bd79ccSDebojyoti Ghosh v[c*q+j] += S[s+j*p]; 122949bd79ccSDebojyoti Ghosh } 123049bd79ccSDebojyoti Ghosh } 123149bd79ccSDebojyoti Ghosh } 123249bd79ccSDebojyoti Ghosh 123349bd79ccSDebojyoti Ghosh if (ncols) *ncols = nz; 123449bd79ccSDebojyoti Ghosh if (cols) *cols = idx; 123549bd79ccSDebojyoti Ghosh if (values) *values = v; 123649bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 123749bd79ccSDebojyoti Ghosh } 123849bd79ccSDebojyoti Ghosh 123949bd79ccSDebojyoti Ghosh PetscErrorCode MatRestoreRow_SeqKAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 124049bd79ccSDebojyoti Ghosh { 124149bd79ccSDebojyoti Ghosh PetscFunctionBegin; 1242cb4a9cd9SHong Zhang if (nz) *nz = 0; 12439566063dSJacob Faibussowitsch PetscCall(PetscFree2(*idx,*v)); 124449bd79ccSDebojyoti Ghosh ((Mat_SeqKAIJ*)A->data)->getrowactive = PETSC_FALSE; 124549bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 124649bd79ccSDebojyoti Ghosh } 124749bd79ccSDebojyoti Ghosh 124849bd79ccSDebojyoti Ghosh PetscErrorCode MatGetRow_MPIKAIJ(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **values) 124949bd79ccSDebojyoti Ghosh { 125049bd79ccSDebojyoti Ghosh Mat_MPIKAIJ *b = (Mat_MPIKAIJ*) A->data; 125149bd79ccSDebojyoti Ghosh Mat AIJ = b->A; 1252fc64b2cfSRichard Tran Mills PetscBool diag = PETSC_FALSE; 1253761d359dSRichard Tran Mills Mat MatAIJ,MatOAIJ; 125449bd79ccSDebojyoti Ghosh const PetscInt rstart=A->rmap->rstart,rend=A->rmap->rend,p=b->p,q=b->q,*garray; 1255389eba51SJed Brown PetscInt nz,*idx,ncolsaij = 0,ncolsoaij = 0,*colsaij,*colsoaij,r,s,c,i,j,lrow; 125649bd79ccSDebojyoti Ghosh PetscScalar *v,*vals,*ovals,*S=b->S,*T=b->T; 125749bd79ccSDebojyoti Ghosh 125849bd79ccSDebojyoti Ghosh PetscFunctionBegin; 12599566063dSJacob Faibussowitsch PetscCall(MatKAIJ_build_AIJ_OAIJ(A)); /* Ensure b->AIJ and b->OAIJ are up to date. */ 1260761d359dSRichard Tran Mills MatAIJ = ((Mat_SeqKAIJ*)b->AIJ->data)->AIJ; 1261761d359dSRichard Tran Mills MatOAIJ = ((Mat_SeqKAIJ*)b->OAIJ->data)->AIJ; 126228b400f6SJacob Faibussowitsch PetscCheck(!b->getrowactive,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Already active"); 126349bd79ccSDebojyoti Ghosh b->getrowactive = PETSC_TRUE; 1264aed4548fSBarry Smith PetscCheck(row >= rstart && row < rend,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only local rows"); 126549bd79ccSDebojyoti Ghosh lrow = row - rstart; 126649bd79ccSDebojyoti Ghosh 126749bd79ccSDebojyoti Ghosh if ((!S) && (!T) && (!b->isTI)) { 126849bd79ccSDebojyoti Ghosh if (ncols) *ncols = 0; 126949bd79ccSDebojyoti Ghosh if (cols) *cols = NULL; 127049bd79ccSDebojyoti Ghosh if (values) *values = NULL; 127149bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 127249bd79ccSDebojyoti Ghosh } 127349bd79ccSDebojyoti Ghosh 127449bd79ccSDebojyoti Ghosh r = lrow/p; 127549bd79ccSDebojyoti Ghosh s = lrow%p; 127649bd79ccSDebojyoti Ghosh 127749bd79ccSDebojyoti Ghosh if (T || b->isTI) { 12789566063dSJacob Faibussowitsch PetscCall(MatMPIAIJGetSeqAIJ(AIJ,NULL,NULL,&garray)); 12799566063dSJacob Faibussowitsch PetscCall(MatGetRow_SeqAIJ(MatAIJ,lrow/p,&ncolsaij,&colsaij,&vals)); 12809566063dSJacob Faibussowitsch PetscCall(MatGetRow_SeqAIJ(MatOAIJ,lrow/p,&ncolsoaij,&colsoaij,&ovals)); 128149bd79ccSDebojyoti Ghosh 128249bd79ccSDebojyoti Ghosh c = ncolsaij + ncolsoaij; 128349bd79ccSDebojyoti Ghosh for (i=0; i<ncolsaij; i++) { 128449bd79ccSDebojyoti Ghosh /* check if this row contains a diagonal entry */ 128549bd79ccSDebojyoti Ghosh if (colsaij[i] == r) { 128649bd79ccSDebojyoti Ghosh diag = PETSC_TRUE; 128749bd79ccSDebojyoti Ghosh c = i; 128849bd79ccSDebojyoti Ghosh } 128949bd79ccSDebojyoti Ghosh } 129049bd79ccSDebojyoti Ghosh } else c = 0; 129149bd79ccSDebojyoti Ghosh 129249bd79ccSDebojyoti Ghosh /* calculate size of row */ 129349bd79ccSDebojyoti Ghosh nz = 0; 129449bd79ccSDebojyoti Ghosh if (S) nz += q; 129549bd79ccSDebojyoti Ghosh if (T || b->isTI) nz += (diag && S ? (ncolsaij+ncolsoaij-1)*q : (ncolsaij+ncolsoaij)*q); 129649bd79ccSDebojyoti Ghosh 129749bd79ccSDebojyoti Ghosh if (cols || values) { 12989566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nz,&idx,nz,&v)); 1299a437a796SRichard Tran Mills for (i=0; i<q; i++) { 1300a437a796SRichard Tran Mills /* We need to initialize the v[i] to zero to handle the case in which T is NULL (not the identity matrix). */ 1301a437a796SRichard Tran Mills v[i] = 0.0; 1302a437a796SRichard Tran Mills } 130349bd79ccSDebojyoti Ghosh if (b->isTI) { 130449bd79ccSDebojyoti Ghosh for (i=0; i<ncolsaij; i++) { 130549bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 130649bd79ccSDebojyoti Ghosh idx[i*q+j] = (colsaij[i]+rstart/p)*q+j; 130749bd79ccSDebojyoti Ghosh v[i*q+j] = (j==s ? vals[i] : 0.0); 130849bd79ccSDebojyoti Ghosh } 130949bd79ccSDebojyoti Ghosh } 131049bd79ccSDebojyoti Ghosh for (i=0; i<ncolsoaij; i++) { 131149bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 131249bd79ccSDebojyoti Ghosh idx[(i+ncolsaij)*q+j] = garray[colsoaij[i]]*q+j; 131349bd79ccSDebojyoti Ghosh v[(i+ncolsaij)*q+j] = (j==s ? ovals[i]: 0.0); 131449bd79ccSDebojyoti Ghosh } 131549bd79ccSDebojyoti Ghosh } 131649bd79ccSDebojyoti Ghosh } else if (T) { 131749bd79ccSDebojyoti Ghosh for (i=0; i<ncolsaij; i++) { 131849bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 131949bd79ccSDebojyoti Ghosh idx[i*q+j] = (colsaij[i]+rstart/p)*q+j; 132049bd79ccSDebojyoti Ghosh v[i*q+j] = vals[i]*T[s+j*p]; 132149bd79ccSDebojyoti Ghosh } 132249bd79ccSDebojyoti Ghosh } 132349bd79ccSDebojyoti Ghosh for (i=0; i<ncolsoaij; i++) { 132449bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 132549bd79ccSDebojyoti Ghosh idx[(i+ncolsaij)*q+j] = garray[colsoaij[i]]*q+j; 132649bd79ccSDebojyoti Ghosh v[(i+ncolsaij)*q+j] = ovals[i]*T[s+j*p]; 132749bd79ccSDebojyoti Ghosh } 132849bd79ccSDebojyoti Ghosh } 132949bd79ccSDebojyoti Ghosh } 133049bd79ccSDebojyoti Ghosh if (S) { 133149bd79ccSDebojyoti Ghosh for (j=0; j<q; j++) { 133249bd79ccSDebojyoti Ghosh idx[c*q+j] = (r+rstart/p)*q+j; 133349bd79ccSDebojyoti Ghosh v[c*q+j] += S[s+j*p]; 133449bd79ccSDebojyoti Ghosh } 133549bd79ccSDebojyoti Ghosh } 133649bd79ccSDebojyoti Ghosh } 133749bd79ccSDebojyoti Ghosh 133849bd79ccSDebojyoti Ghosh if (ncols) *ncols = nz; 133949bd79ccSDebojyoti Ghosh if (cols) *cols = idx; 134049bd79ccSDebojyoti Ghosh if (values) *values = v; 134149bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 134249bd79ccSDebojyoti Ghosh } 134349bd79ccSDebojyoti Ghosh 134449bd79ccSDebojyoti Ghosh PetscErrorCode MatRestoreRow_MPIKAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 134549bd79ccSDebojyoti Ghosh { 134649bd79ccSDebojyoti Ghosh PetscFunctionBegin; 13479566063dSJacob Faibussowitsch PetscCall(PetscFree2(*idx,*v)); 134849bd79ccSDebojyoti Ghosh ((Mat_SeqKAIJ*)A->data)->getrowactive = PETSC_FALSE; 134949bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 135049bd79ccSDebojyoti Ghosh } 135149bd79ccSDebojyoti Ghosh 135249bd79ccSDebojyoti Ghosh PetscErrorCode MatCreateSubMatrix_KAIJ(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 135349bd79ccSDebojyoti Ghosh { 135449bd79ccSDebojyoti Ghosh Mat A; 135549bd79ccSDebojyoti Ghosh 135649bd79ccSDebojyoti Ghosh PetscFunctionBegin; 13579566063dSJacob Faibussowitsch PetscCall(MatConvert(mat,MATAIJ,MAT_INITIAL_MATRIX,&A)); 13589566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(A,isrow,iscol,cll,newmat)); 13599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 136049bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 136149bd79ccSDebojyoti Ghosh } 136249bd79ccSDebojyoti Ghosh 136349bd79ccSDebojyoti Ghosh /* ---------------------------------------------------------------------------------- */ 136449bd79ccSDebojyoti Ghosh /*@C 136549bd79ccSDebojyoti Ghosh MatCreateKAIJ - Creates a matrix type to be used for matrices of the following form: 136649bd79ccSDebojyoti Ghosh 136749bd79ccSDebojyoti Ghosh [I \otimes S + A \otimes T] 136849bd79ccSDebojyoti Ghosh 136949bd79ccSDebojyoti Ghosh where 137049bd79ccSDebojyoti Ghosh S is a dense (p \times q) matrix 137149bd79ccSDebojyoti Ghosh T is a dense (p \times q) matrix 137249bd79ccSDebojyoti Ghosh A is an AIJ (n \times n) matrix 137349bd79ccSDebojyoti Ghosh I is the identity matrix 137449bd79ccSDebojyoti Ghosh The resulting matrix is (np \times nq) 137549bd79ccSDebojyoti Ghosh 1376d3b90ce1SRichard Tran Mills S and T are always stored independently on all processes as PetscScalar arrays in column-major format. 137749bd79ccSDebojyoti Ghosh 137849bd79ccSDebojyoti Ghosh Collective 137949bd79ccSDebojyoti Ghosh 138049bd79ccSDebojyoti Ghosh Input Parameters: 138149bd79ccSDebojyoti Ghosh + A - the AIJ matrix 138249bd79ccSDebojyoti Ghosh . p - number of rows in S and T 1383d3b90ce1SRichard Tran Mills . q - number of columns in S and T 1384d3b90ce1SRichard Tran Mills . S - the S matrix (can be PETSC_NULL), stored as a PetscScalar array (column-major) 1385d3b90ce1SRichard Tran Mills - T - the T matrix (can be PETSC_NULL), stored as a PetscScalar array (column-major) 138649bd79ccSDebojyoti Ghosh 138749bd79ccSDebojyoti Ghosh Output Parameter: 138849bd79ccSDebojyoti Ghosh . kaij - the new KAIJ matrix 138949bd79ccSDebojyoti Ghosh 1390d3b90ce1SRichard Tran Mills Notes: 1391d3b90ce1SRichard Tran Mills This function increases the reference count on the AIJ matrix, so the user is free to destroy the matrix if it is not needed. 1392d3b90ce1SRichard Tran Mills Changes to the entries of the AIJ matrix will immediately affect the KAIJ matrix. 139349bd79ccSDebojyoti Ghosh 1394761d359dSRichard Tran Mills Developer Notes: 1395761d359dSRichard Tran Mills In the MATMPIKAIJ case, the internal 'AIJ' and 'OAIJ' sequential KAIJ matrices are kept up to date by tracking the object state 1396761d359dSRichard Tran Mills of the AIJ matrix 'A' that describes the blockwise action of the MATMPIKAIJ matrix and, if the object state has changed, lazily 1397761d359dSRichard Tran Mills rebuilding 'AIJ' and 'OAIJ' just before executing operations with the MATMPIKAIJ matrix. If new types of operations are added, 1398761d359dSRichard Tran Mills routines implementing those must also ensure these are rebuilt when needed (by calling the internal MatKAIJ_build_AIJ_OAIJ() routine). 1399761d359dSRichard Tran Mills 140049bd79ccSDebojyoti Ghosh Level: advanced 140149bd79ccSDebojyoti Ghosh 1402db781477SPatrick Sanan .seealso: `MatKAIJSetAIJ()`, `MatKAIJSetS()`, `MatKAIJSetT()`, `MatKAIJGetAIJ()`, `MatKAIJGetS()`, `MatKAIJGetT()`, `MATKAIJ` 140349bd79ccSDebojyoti Ghosh @*/ 140449bd79ccSDebojyoti Ghosh PetscErrorCode MatCreateKAIJ(Mat A,PetscInt p,PetscInt q,const PetscScalar S[],const PetscScalar T[],Mat *kaij) 140549bd79ccSDebojyoti Ghosh { 140649bd79ccSDebojyoti Ghosh PetscFunctionBegin; 14079566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),kaij)); 14089566063dSJacob Faibussowitsch PetscCall(MatSetType(*kaij,MATKAIJ)); 14099566063dSJacob Faibussowitsch PetscCall(MatKAIJSetAIJ(*kaij,A)); 14109566063dSJacob Faibussowitsch PetscCall(MatKAIJSetS(*kaij,p,q,S)); 14119566063dSJacob Faibussowitsch PetscCall(MatKAIJSetT(*kaij,p,q,T)); 14129566063dSJacob Faibussowitsch PetscCall(MatSetUp(*kaij)); 14130567c835SRichard Tran Mills PetscFunctionReturn(0); 14140567c835SRichard Tran Mills } 141549bd79ccSDebojyoti Ghosh 14160567c835SRichard Tran Mills /*MC 14175881e567SRichard Tran Mills MATKAIJ - MATKAIJ = "kaij" - A matrix type to be used to evaluate matrices of form 14185881e567SRichard Tran Mills [I \otimes S + A \otimes T], 14190567c835SRichard Tran Mills where 14205881e567SRichard Tran Mills S is a dense (p \times q) matrix, 14215881e567SRichard Tran Mills T is a dense (p \times q) matrix, 14225881e567SRichard Tran Mills A is an AIJ (n \times n) matrix, 14235881e567SRichard Tran Mills and I is the identity matrix. 14245881e567SRichard Tran Mills The resulting matrix is (np \times nq). 14250567c835SRichard Tran Mills 1426d3b90ce1SRichard Tran Mills S and T are always stored independently on all processes as PetscScalar arrays in column-major format. 14270567c835SRichard Tran Mills 14285881e567SRichard Tran Mills Notes: 14295881e567SRichard Tran Mills A linear system with multiple right-hand sides, AX = B, can be expressed in the KAIJ-friendly form of (A \otimes I) x = b, 14305881e567SRichard Tran Mills where x and b are column vectors containing the row-major representations of X and B. 14315881e567SRichard Tran Mills 14320567c835SRichard Tran Mills Level: advanced 14330567c835SRichard Tran Mills 1434db781477SPatrick Sanan .seealso: `MatKAIJSetAIJ()`, `MatKAIJSetS()`, `MatKAIJSetT()`, `MatKAIJGetAIJ()`, `MatKAIJGetS()`, `MatKAIJGetT()`, `MatCreateKAIJ()` 14350567c835SRichard Tran Mills M*/ 14360567c835SRichard Tran Mills 14370567c835SRichard Tran Mills PETSC_EXTERN PetscErrorCode MatCreate_KAIJ(Mat A) 14380567c835SRichard Tran Mills { 14390567c835SRichard Tran Mills Mat_MPIKAIJ *b; 14400567c835SRichard Tran Mills PetscMPIInt size; 14410567c835SRichard Tran Mills 14420567c835SRichard Tran Mills PetscFunctionBegin; 14439566063dSJacob Faibussowitsch PetscCall(PetscNewLog(A,&b)); 14440567c835SRichard Tran Mills A->data = (void*)b; 14450567c835SRichard Tran Mills 14469566063dSJacob Faibussowitsch PetscCall(PetscMemzero(A->ops,sizeof(struct _MatOps))); 14470567c835SRichard Tran Mills 1448f4259b30SLisandro Dalcin b->w = NULL; 14499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 14500567c835SRichard Tran Mills if (size == 1) { 14519566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)A,MATSEQKAIJ)); 14520567c835SRichard Tran Mills A->ops->destroy = MatDestroy_SeqKAIJ; 1453bb6fb833SRichard Tran Mills A->ops->mult = MatMult_SeqKAIJ; 1454bb6fb833SRichard Tran Mills A->ops->multadd = MatMultAdd_SeqKAIJ; 1455bb6fb833SRichard Tran Mills A->ops->invertblockdiagonal = MatInvertBlockDiagonal_SeqKAIJ; 14560567c835SRichard Tran Mills A->ops->getrow = MatGetRow_SeqKAIJ; 14570567c835SRichard Tran Mills A->ops->restorerow = MatRestoreRow_SeqKAIJ; 14580567c835SRichard Tran Mills A->ops->sor = MatSOR_SeqKAIJ; 14599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqkaij_seqaij_C",MatConvert_KAIJ_AIJ)); 14600567c835SRichard Tran Mills } else { 14619566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)A,MATMPIKAIJ)); 14620567c835SRichard Tran Mills A->ops->destroy = MatDestroy_MPIKAIJ; 1463bb6fb833SRichard Tran Mills A->ops->mult = MatMult_MPIKAIJ; 1464bb6fb833SRichard Tran Mills A->ops->multadd = MatMultAdd_MPIKAIJ; 1465bb6fb833SRichard Tran Mills A->ops->invertblockdiagonal = MatInvertBlockDiagonal_MPIKAIJ; 14660567c835SRichard Tran Mills A->ops->getrow = MatGetRow_MPIKAIJ; 14670567c835SRichard Tran Mills A->ops->restorerow = MatRestoreRow_MPIKAIJ; 14689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatGetDiagonalBlock_C",MatGetDiagonalBlock_MPIKAIJ)); 14699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)A,"MatConvert_mpikaij_mpiaij_C",MatConvert_KAIJ_AIJ)); 14700567c835SRichard Tran Mills } 147106d61a37SPierre Jolivet A->ops->setup = MatSetUp_KAIJ; 147206d61a37SPierre Jolivet A->ops->view = MatView_KAIJ; 14730567c835SRichard Tran Mills A->ops->createsubmatrix = MatCreateSubMatrix_KAIJ; 147449bd79ccSDebojyoti Ghosh PetscFunctionReturn(0); 147549bd79ccSDebojyoti Ghosh } 1476