14dfdc2d9SRichard Tran Mills /* 24dfdc2d9SRichard Tran Mills Defines basic operations for the MATSEQAIJSELL matrix class. 34dfdc2d9SRichard Tran Mills This class is derived from the MATAIJCLASS, but maintains a "shadow" copy 44dfdc2d9SRichard Tran Mills of the matrix stored in MATSEQSELL format, which is used as appropriate for 54dfdc2d9SRichard Tran Mills performing operations for which this format is more suitable. 64dfdc2d9SRichard Tran Mills */ 74dfdc2d9SRichard Tran Mills 84dfdc2d9SRichard Tran Mills #include <../src/mat/impls/aij/seq/aij.h> 9b0e5de86SRichard Tran Mills #include <../src/mat/impls/sell/seq/sell.h> 104dfdc2d9SRichard Tran Mills 114dfdc2d9SRichard Tran Mills typedef struct { 124dfdc2d9SRichard Tran Mills Mat S; /* The SELL formatted "shadow" matrix. */ 134dfdc2d9SRichard Tran Mills PetscBool eager_shadow; 144dfdc2d9SRichard Tran Mills PetscObjectState state; /* State of the matrix when shadow matrix was last constructed. */ 154dfdc2d9SRichard Tran Mills } Mat_SeqAIJSELL; 164dfdc2d9SRichard Tran Mills 17d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJSELL_SeqAIJ(Mat A, MatType type, MatReuse reuse, Mat *newmat) 18d71ae5a4SJacob Faibussowitsch { 194dfdc2d9SRichard Tran Mills /* This routine is only called to convert a MATAIJSELL to its base PETSc type, */ 204dfdc2d9SRichard Tran Mills /* so we will ignore 'MatType type'. */ 214dfdc2d9SRichard Tran Mills Mat B = *newmat; 224dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 234dfdc2d9SRichard Tran Mills 244dfdc2d9SRichard Tran Mills PetscFunctionBegin; 2548a46eb9SPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B)); 264dfdc2d9SRichard Tran Mills 274dfdc2d9SRichard Tran Mills /* Reset the original function pointers. */ 284dfdc2d9SRichard Tran Mills B->ops->duplicate = MatDuplicate_SeqAIJ; 294dfdc2d9SRichard Tran Mills B->ops->assemblyend = MatAssemblyEnd_SeqAIJ; 304dfdc2d9SRichard Tran Mills B->ops->destroy = MatDestroy_SeqAIJ; 314dfdc2d9SRichard Tran Mills B->ops->mult = MatMult_SeqAIJ; 324dfdc2d9SRichard Tran Mills B->ops->multtranspose = MatMultTranspose_SeqAIJ; 334dfdc2d9SRichard Tran Mills B->ops->multadd = MatMultAdd_SeqAIJ; 344dfdc2d9SRichard Tran Mills B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJ; 35af22a668SRichard Tran Mills B->ops->sor = MatSOR_SeqAIJ; 364dfdc2d9SRichard Tran Mills 379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqaijsell_seqaij_C", NULL)); 384dfdc2d9SRichard Tran Mills 394dfdc2d9SRichard Tran Mills if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL *)B->spptr; 404dfdc2d9SRichard Tran Mills 418cde19baSRichard Tran Mills /* Clean up the Mat_SeqAIJSELL data structure. 428cde19baSRichard Tran Mills * Note that MatDestroy() simply returns if passed a NULL value, so it's OK to call even if the shadow matrix was never constructed. */ 439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&aijsell->S)); 449566063dSJacob Faibussowitsch PetscCall(PetscFree(B->spptr)); 454dfdc2d9SRichard Tran Mills 464dfdc2d9SRichard Tran Mills /* Change the type of B to MATSEQAIJ. */ 479566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ)); 484dfdc2d9SRichard Tran Mills 494dfdc2d9SRichard Tran Mills *newmat = B; 503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 514dfdc2d9SRichard Tran Mills } 524dfdc2d9SRichard Tran Mills 53d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqAIJSELL(Mat A) 54d71ae5a4SJacob Faibussowitsch { 554dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 564dfdc2d9SRichard Tran Mills 574dfdc2d9SRichard Tran Mills PetscFunctionBegin; 584dfdc2d9SRichard Tran Mills 594dfdc2d9SRichard Tran Mills /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an 604dfdc2d9SRichard Tran Mills * spptr pointer. */ 614dfdc2d9SRichard Tran Mills if (aijsell) { 624dfdc2d9SRichard Tran Mills /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */ 639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&aijsell->S)); 649566063dSJacob Faibussowitsch PetscCall(PetscFree(A->spptr)); 654dfdc2d9SRichard Tran Mills } 664dfdc2d9SRichard Tran Mills 674dfdc2d9SRichard Tran Mills /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ() 684dfdc2d9SRichard Tran Mills * to destroy everything that remains. */ 699566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ)); 704dfdc2d9SRichard Tran Mills /* Note that I don't call MatSetType(). I believe this is because that 714dfdc2d9SRichard Tran Mills * is only to be called when *building* a matrix. I could be wrong, but 724dfdc2d9SRichard Tran Mills * that is how things work for the SuperLU matrix class. */ 732e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_seqaijsell_seqaij_C", NULL)); 749566063dSJacob Faibussowitsch PetscCall(MatDestroy_SeqAIJ(A)); 753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 764dfdc2d9SRichard Tran Mills } 774dfdc2d9SRichard Tran Mills 78a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed. 79a2a1850bSRichard Tran Mills * We track the ObjectState to determine when this needs to be done. */ 80d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A) 81d71ae5a4SJacob Faibussowitsch { 82b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 83a2a1850bSRichard Tran Mills PetscObjectState state; 84b0e5de86SRichard Tran Mills 85b0e5de86SRichard Tran Mills PetscFunctionBegin; 869566063dSJacob Faibussowitsch PetscCall(PetscObjectStateGet((PetscObject)A, &state)); 87a2a1850bSRichard Tran Mills if (aijsell->S && aijsell->state == state) { 88a2a1850bSRichard Tran Mills /* The existing shadow matrix is up-to-date, so simply exit. */ 893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 90a2a1850bSRichard Tran Mills } 91a2a1850bSRichard Tran Mills 929566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_Convert, A, 0, 0, 0)); 93b0e5de86SRichard Tran Mills if (aijsell->S) { 949566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_REUSE_MATRIX, &aijsell->S)); 95b0e5de86SRichard Tran Mills } else { 969566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_INITIAL_MATRIX, &aijsell->S)); 97b0e5de86SRichard Tran Mills } 989566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_Convert, A, 0, 0, 0)); 99b0e5de86SRichard Tran Mills 100b0e5de86SRichard Tran Mills /* Record the ObjectState so that we can tell when the shadow matrix needs updating */ 1019566063dSJacob Faibussowitsch PetscCall(PetscObjectStateGet((PetscObject)A, &aijsell->state)); 102b0e5de86SRichard Tran Mills 1033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104b0e5de86SRichard Tran Mills } 105b0e5de86SRichard Tran Mills 106d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M) 107d71ae5a4SJacob Faibussowitsch { 1084dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell; 1094dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell_dest; 1104dfdc2d9SRichard Tran Mills 1114dfdc2d9SRichard Tran Mills PetscFunctionBegin; 1129566063dSJacob Faibussowitsch PetscCall(MatDuplicate_SeqAIJ(A, op, M)); 1134dfdc2d9SRichard Tran Mills aijsell = (Mat_SeqAIJSELL *)A->spptr; 1144dfdc2d9SRichard Tran Mills aijsell_dest = (Mat_SeqAIJSELL *)(*M)->spptr; 1159566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(aijsell_dest, aijsell, 1)); 1164dfdc2d9SRichard Tran Mills /* We don't duplicate the shadow matrix -- that will be constructed as needed. */ 1174dfdc2d9SRichard Tran Mills aijsell_dest->S = NULL; 1181baa6e33SBarry Smith if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1204dfdc2d9SRichard Tran Mills } 1214dfdc2d9SRichard Tran Mills 122d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode) 123d71ae5a4SJacob Faibussowitsch { 1244dfdc2d9SRichard Tran Mills Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 1258cde19baSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1264dfdc2d9SRichard Tran Mills 1274dfdc2d9SRichard Tran Mills PetscFunctionBegin; 1283ba16761SJacob Faibussowitsch if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(PETSC_SUCCESS); 1294dfdc2d9SRichard Tran Mills 1304dfdc2d9SRichard Tran Mills /* I disable the use of the inode routines so that the AIJSELL ones will be 1314dfdc2d9SRichard Tran Mills * used instead, but I wonder if it might make sense (and is feasible) to 1324dfdc2d9SRichard Tran Mills * use some of them. */ 1334dfdc2d9SRichard Tran Mills a->inode.use = PETSC_FALSE; 1344dfdc2d9SRichard Tran Mills 1354dfdc2d9SRichard Tran Mills /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some 1364dfdc2d9SRichard Tran Mills * extra information and some different methods, call the AssemblyEnd 1374dfdc2d9SRichard Tran Mills * routine for a MATSEQAIJ. 1384dfdc2d9SRichard Tran Mills * I'm not sure if this is the best way to do this, but it avoids 1394dfdc2d9SRichard Tran Mills * a lot of code duplication. */ 1404dfdc2d9SRichard Tran Mills 1419566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd_SeqAIJ(A, mode)); 1424dfdc2d9SRichard Tran Mills 1434dfdc2d9SRichard Tran Mills /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks). 1444dfdc2d9SRichard Tran Mills * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */ 1451baa6e33SBarry Smith if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 1464dfdc2d9SRichard Tran Mills 1473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1484dfdc2d9SRichard Tran Mills } 1494dfdc2d9SRichard Tran Mills 150d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqAIJSELL(Mat A, Vec xx, Vec yy) 151d71ae5a4SJacob Faibussowitsch { 152b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 153b0e5de86SRichard Tran Mills 154b0e5de86SRichard Tran Mills PetscFunctionBegin; 1559566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1569566063dSJacob Faibussowitsch PetscCall(MatMult_SeqSELL(aijsell->S, xx, yy)); 1573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 158b0e5de86SRichard Tran Mills } 159b0e5de86SRichard Tran Mills 160d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A, Vec xx, Vec yy) 161d71ae5a4SJacob Faibussowitsch { 1624da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1634da9d7bdSRichard Tran Mills 1644da9d7bdSRichard Tran Mills PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1669566063dSJacob Faibussowitsch PetscCall(MatMultTranspose_SeqSELL(aijsell->S, xx, yy)); 1673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1684da9d7bdSRichard Tran Mills } 1694da9d7bdSRichard Tran Mills 170d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) 171d71ae5a4SJacob Faibussowitsch { 1724da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1734da9d7bdSRichard Tran Mills 1744da9d7bdSRichard Tran Mills PetscFunctionBegin; 1759566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1769566063dSJacob Faibussowitsch PetscCall(MatMultAdd_SeqSELL(aijsell->S, xx, yy, zz)); 1773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1784da9d7bdSRichard Tran Mills } 1794da9d7bdSRichard Tran Mills 180d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) 181d71ae5a4SJacob Faibussowitsch { 1824da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1834da9d7bdSRichard Tran Mills 1844da9d7bdSRichard Tran Mills PetscFunctionBegin; 1859566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1869566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd_SeqSELL(aijsell->S, xx, yy, zz)); 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1884da9d7bdSRichard Tran Mills } 1894da9d7bdSRichard Tran Mills 190d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSOR_SeqAIJSELL(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal fshift, PetscInt its, PetscInt lits, Vec xx) 191d71ae5a4SJacob Faibussowitsch { 192af22a668SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 193af22a668SRichard Tran Mills 194af22a668SRichard Tran Mills PetscFunctionBegin; 1959566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1969566063dSJacob Faibussowitsch PetscCall(MatSOR_SeqSELL(aijsell->S, bb, omega, flag, fshift, its, lits, xx)); 1973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 198af22a668SRichard Tran Mills } 199af22a668SRichard Tran Mills 2004dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a 2014dfdc2d9SRichard Tran Mills * SeqAIJSELL matrix. This routine is called by the MatCreate_SeqAIJSELL() 2024dfdc2d9SRichard Tran Mills * routine, but can also be used to convert an assembled SeqAIJ matrix 2034dfdc2d9SRichard Tran Mills * into a SeqAIJSELL one. */ 204d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A, MatType type, MatReuse reuse, Mat *newmat) 205d71ae5a4SJacob Faibussowitsch { 2064dfdc2d9SRichard Tran Mills Mat B = *newmat; 2074dfdc2d9SRichard Tran Mills Mat_SeqAIJ *b; 2084dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell; 2094dfdc2d9SRichard Tran Mills PetscBool set; 2104dfdc2d9SRichard Tran Mills PetscBool sametype; 2114dfdc2d9SRichard Tran Mills 2124dfdc2d9SRichard Tran Mills PetscFunctionBegin; 21348a46eb9SPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B)); 2144dfdc2d9SRichard Tran Mills 2159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, type, &sametype)); 2163ba16761SJacob Faibussowitsch if (sametype) PetscFunctionReturn(PETSC_SUCCESS); 2174dfdc2d9SRichard Tran Mills 2184dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&aijsell)); 2194dfdc2d9SRichard Tran Mills b = (Mat_SeqAIJ *)B->data; 2204dfdc2d9SRichard Tran Mills B->spptr = (void *)aijsell; 2214dfdc2d9SRichard Tran Mills 2224dfdc2d9SRichard Tran Mills /* Disable use of the inode routines so that the AIJSELL ones will be used instead. 2234dfdc2d9SRichard Tran Mills * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too. 2244dfdc2d9SRichard Tran Mills * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */ 2254dfdc2d9SRichard Tran Mills b->inode.use = PETSC_FALSE; 2264dfdc2d9SRichard Tran Mills 2274dfdc2d9SRichard Tran Mills /* Set function pointers for methods that we inherit from AIJ but override. 2284dfdc2d9SRichard Tran Mills * We also parse some command line options below, since those determine some of the methods we point to. */ 2294dfdc2d9SRichard Tran Mills B->ops->duplicate = MatDuplicate_SeqAIJSELL; 2304dfdc2d9SRichard Tran Mills B->ops->assemblyend = MatAssemblyEnd_SeqAIJSELL; 2314dfdc2d9SRichard Tran Mills B->ops->destroy = MatDestroy_SeqAIJSELL; 2324dfdc2d9SRichard Tran Mills 2334dfdc2d9SRichard Tran Mills aijsell->S = NULL; 2344dfdc2d9SRichard Tran Mills aijsell->eager_shadow = PETSC_FALSE; 2354dfdc2d9SRichard Tran Mills 2364dfdc2d9SRichard Tran Mills /* Parse command line options. */ 237d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)A), ((PetscObject)A)->prefix, "AIJSELL Options", "Mat"); 2389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_aijsell_eager_shadow", "Eager Shadowing", "None", (PetscBool)aijsell->eager_shadow, (PetscBool *)&aijsell->eager_shadow, &set)); 239d0609cedSBarry Smith PetscOptionsEnd(); 2404dfdc2d9SRichard Tran Mills 2414dfdc2d9SRichard Tran Mills /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */ 24248a46eb9SPierre Jolivet if (A->assembled && aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 2434dfdc2d9SRichard Tran Mills 244b0e5de86SRichard Tran Mills B->ops->mult = MatMult_SeqAIJSELL; 245b0e5de86SRichard Tran Mills B->ops->multtranspose = MatMultTranspose_SeqAIJSELL; 246b0e5de86SRichard Tran Mills B->ops->multadd = MatMultAdd_SeqAIJSELL; 247b0e5de86SRichard Tran Mills B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL; 248af22a668SRichard Tran Mills B->ops->sor = MatSOR_SeqAIJSELL; 2494dfdc2d9SRichard Tran Mills 2509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqaijsell_seqaij_C", MatConvert_SeqAIJSELL_SeqAIJ)); 2514dfdc2d9SRichard Tran Mills 2529566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJSELL)); 2534dfdc2d9SRichard Tran Mills *newmat = B; 2543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2554dfdc2d9SRichard Tran Mills } 2564dfdc2d9SRichard Tran Mills 2574dfdc2d9SRichard Tran Mills /*@C 25811a5261eSBarry Smith MatCreateSeqAIJSELL - Creates a sparse matrix of type `MATSEQAIJSELL`. 2594dfdc2d9SRichard Tran Mills This type inherits from AIJ and is largely identical, but keeps a "shadow" 26011a5261eSBarry Smith copy of the matrix in `MATSEQSELL` format, which is used when this format 26111a5261eSBarry Smith may be more suitable for a requested operation. Currently, `MATSEQSELL` format 26211a5261eSBarry Smith is used for `MatMult()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()`, 26311a5261eSBarry Smith and `MatSOR()` operations. 2644dfdc2d9SRichard Tran Mills 265d083f849SBarry Smith Collective 2664dfdc2d9SRichard Tran Mills 2674dfdc2d9SRichard Tran Mills Input Parameters: 26811a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 2694dfdc2d9SRichard Tran Mills . m - number of rows 2704dfdc2d9SRichard Tran Mills . n - number of columns 2714dfdc2d9SRichard Tran Mills . nz - number of nonzeros per row (same for all rows) 2724dfdc2d9SRichard Tran Mills - nnz - array containing the number of nonzeros in the various rows 2732ef1f0ffSBarry Smith (possibly different for each row) or `NULL` 2744dfdc2d9SRichard Tran Mills 2754dfdc2d9SRichard Tran Mills Output Parameter: 2764dfdc2d9SRichard Tran Mills . A - the matrix 2774dfdc2d9SRichard Tran Mills 2784dfdc2d9SRichard Tran Mills Options Database Keys: 2792ef1f0ffSBarry Smith . -mat_aijsell_eager_shadow - Construct shadow matrix upon matrix assembly; default is to take a "lazy" approach, 2802ef1f0ffSBarry Smith performing this step the first time the matrix is applied 2812ef1f0ffSBarry Smith 2822ef1f0ffSBarry Smith Level: intermediate 2834dfdc2d9SRichard Tran Mills 2844dfdc2d9SRichard Tran Mills Notes: 2852ef1f0ffSBarry Smith If `nnz` is given then `nz` is ignored 2864dfdc2d9SRichard Tran Mills 287aa624791SPierre Jolivet Because `MATSEQAIJSELL` is a subtype of `MATSEQAIJ`, the option `-mat_seqaij_type seqaijsell` can be used to make 288aa624791SPierre Jolivet sequential `MATSEQAIJ` matrices default to being instances of `MATSEQAIJSELL`. 28911a5261eSBarry Smith 290*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatCreateMPIAIJSELL()`, `MatSetValues()` 2914dfdc2d9SRichard Tran Mills @*/ 292d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqAIJSELL(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt nz, const PetscInt nnz[], Mat *A) 293d71ae5a4SJacob Faibussowitsch { 2944dfdc2d9SRichard Tran Mills PetscFunctionBegin; 2959566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 2969566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 2979566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQAIJSELL)); 2989566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation_SeqAIJ(*A, nz, nnz)); 2993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3004dfdc2d9SRichard Tran Mills } 3014dfdc2d9SRichard Tran Mills 302d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A) 303d71ae5a4SJacob Faibussowitsch { 3044dfdc2d9SRichard Tran Mills PetscFunctionBegin; 3059566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATSEQAIJ)); 3069566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqAIJSELL(A, MATSEQAIJSELL, MAT_INPLACE_MATRIX, &A)); 3073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3084dfdc2d9SRichard Tran Mills } 309