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 5366976f2fSJacob Faibussowitsch static 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 /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an 594dfdc2d9SRichard Tran Mills * spptr pointer. */ 604dfdc2d9SRichard Tran Mills if (aijsell) { 614dfdc2d9SRichard Tran Mills /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */ 629566063dSJacob Faibussowitsch PetscCall(MatDestroy(&aijsell->S)); 639566063dSJacob Faibussowitsch PetscCall(PetscFree(A->spptr)); 644dfdc2d9SRichard Tran Mills } 654dfdc2d9SRichard Tran Mills 664dfdc2d9SRichard Tran Mills /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ() 674dfdc2d9SRichard Tran Mills * to destroy everything that remains. */ 689566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ)); 694dfdc2d9SRichard Tran Mills /* Note that I don't call MatSetType(). I believe this is because that 704dfdc2d9SRichard Tran Mills * is only to be called when *building* a matrix. I could be wrong, but 714dfdc2d9SRichard Tran Mills * that is how things work for the SuperLU matrix class. */ 722e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_seqaijsell_seqaij_C", NULL)); 739566063dSJacob Faibussowitsch PetscCall(MatDestroy_SeqAIJ(A)); 743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 754dfdc2d9SRichard Tran Mills } 764dfdc2d9SRichard Tran Mills 77a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed. 78a2a1850bSRichard Tran Mills * We track the ObjectState to determine when this needs to be done. */ 79d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A) 80d71ae5a4SJacob Faibussowitsch { 81b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 82a2a1850bSRichard Tran Mills PetscObjectState state; 83b0e5de86SRichard Tran Mills 84b0e5de86SRichard Tran Mills PetscFunctionBegin; 859566063dSJacob Faibussowitsch PetscCall(PetscObjectStateGet((PetscObject)A, &state)); 86a2a1850bSRichard Tran Mills if (aijsell->S && aijsell->state == state) { 87a2a1850bSRichard Tran Mills /* The existing shadow matrix is up-to-date, so simply exit. */ 883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89a2a1850bSRichard Tran Mills } 90a2a1850bSRichard Tran Mills 919566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_Convert, A, 0, 0, 0)); 92b0e5de86SRichard Tran Mills if (aijsell->S) { 939566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_REUSE_MATRIX, &aijsell->S)); 94b0e5de86SRichard Tran Mills } else { 959566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_INITIAL_MATRIX, &aijsell->S)); 96b0e5de86SRichard Tran Mills } 979566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_Convert, A, 0, 0, 0)); 98b0e5de86SRichard Tran Mills 99b0e5de86SRichard Tran Mills /* Record the ObjectState so that we can tell when the shadow matrix needs updating */ 1009566063dSJacob Faibussowitsch PetscCall(PetscObjectStateGet((PetscObject)A, &aijsell->state)); 1013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 102b0e5de86SRichard Tran Mills } 103b0e5de86SRichard Tran Mills 10466976f2fSJacob Faibussowitsch static PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M) 105d71ae5a4SJacob Faibussowitsch { 1064dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell; 1074dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell_dest; 1084dfdc2d9SRichard Tran Mills 1094dfdc2d9SRichard Tran Mills PetscFunctionBegin; 1109566063dSJacob Faibussowitsch PetscCall(MatDuplicate_SeqAIJ(A, op, M)); 1114dfdc2d9SRichard Tran Mills aijsell = (Mat_SeqAIJSELL *)A->spptr; 1124dfdc2d9SRichard Tran Mills aijsell_dest = (Mat_SeqAIJSELL *)(*M)->spptr; 1139566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(aijsell_dest, aijsell, 1)); 1144dfdc2d9SRichard Tran Mills /* We don't duplicate the shadow matrix -- that will be constructed as needed. */ 1154dfdc2d9SRichard Tran Mills aijsell_dest->S = NULL; 1161baa6e33SBarry Smith if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 1173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1184dfdc2d9SRichard Tran Mills } 1194dfdc2d9SRichard Tran Mills 12066976f2fSJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode) 121d71ae5a4SJacob Faibussowitsch { 1224dfdc2d9SRichard Tran Mills Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 1238cde19baSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1244dfdc2d9SRichard Tran Mills 1254dfdc2d9SRichard Tran Mills PetscFunctionBegin; 1263ba16761SJacob Faibussowitsch if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(PETSC_SUCCESS); 1274dfdc2d9SRichard Tran Mills 1284dfdc2d9SRichard Tran Mills /* I disable the use of the inode routines so that the AIJSELL ones will be 1294dfdc2d9SRichard Tran Mills * used instead, but I wonder if it might make sense (and is feasible) to 1304dfdc2d9SRichard Tran Mills * use some of them. */ 1314dfdc2d9SRichard Tran Mills a->inode.use = PETSC_FALSE; 1324dfdc2d9SRichard Tran Mills 1334dfdc2d9SRichard Tran Mills /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some 1344dfdc2d9SRichard Tran Mills * extra information and some different methods, call the AssemblyEnd 1354dfdc2d9SRichard Tran Mills * routine for a MATSEQAIJ. 1364dfdc2d9SRichard Tran Mills * I'm not sure if this is the best way to do this, but it avoids 1374dfdc2d9SRichard Tran Mills * a lot of code duplication. */ 1384dfdc2d9SRichard Tran Mills 1399566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd_SeqAIJ(A, mode)); 1404dfdc2d9SRichard Tran Mills 1414dfdc2d9SRichard Tran Mills /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks). 1424dfdc2d9SRichard Tran Mills * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */ 1431baa6e33SBarry Smith if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1454dfdc2d9SRichard Tran Mills } 1464dfdc2d9SRichard Tran Mills 14766976f2fSJacob Faibussowitsch static PetscErrorCode MatMult_SeqAIJSELL(Mat A, Vec xx, Vec yy) 148d71ae5a4SJacob Faibussowitsch { 149b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 150b0e5de86SRichard Tran Mills 151b0e5de86SRichard Tran Mills PetscFunctionBegin; 1529566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1539566063dSJacob Faibussowitsch PetscCall(MatMult_SeqSELL(aijsell->S, xx, yy)); 1543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 155b0e5de86SRichard Tran Mills } 156b0e5de86SRichard Tran Mills 15766976f2fSJacob Faibussowitsch static PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A, Vec xx, Vec yy) 158d71ae5a4SJacob Faibussowitsch { 1594da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1604da9d7bdSRichard Tran Mills 1614da9d7bdSRichard Tran Mills PetscFunctionBegin; 1629566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1639566063dSJacob Faibussowitsch PetscCall(MatMultTranspose_SeqSELL(aijsell->S, xx, yy)); 1643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1654da9d7bdSRichard Tran Mills } 1664da9d7bdSRichard Tran Mills 16766976f2fSJacob Faibussowitsch static PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) 168d71ae5a4SJacob Faibussowitsch { 1694da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1704da9d7bdSRichard Tran Mills 1714da9d7bdSRichard Tran Mills PetscFunctionBegin; 1729566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1739566063dSJacob Faibussowitsch PetscCall(MatMultAdd_SeqSELL(aijsell->S, xx, yy, zz)); 1743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1754da9d7bdSRichard Tran Mills } 1764da9d7bdSRichard Tran Mills 17766976f2fSJacob Faibussowitsch static PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) 178d71ae5a4SJacob Faibussowitsch { 1794da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 1804da9d7bdSRichard Tran Mills 1814da9d7bdSRichard Tran Mills PetscFunctionBegin; 1829566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1839566063dSJacob Faibussowitsch PetscCall(MatMultTransposeAdd_SeqSELL(aijsell->S, xx, yy, zz)); 1843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1854da9d7bdSRichard Tran Mills } 1864da9d7bdSRichard Tran Mills 18766976f2fSJacob Faibussowitsch static PetscErrorCode MatSOR_SeqAIJSELL(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal fshift, PetscInt its, PetscInt lits, Vec xx) 188d71ae5a4SJacob Faibussowitsch { 189af22a668SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr; 190af22a668SRichard Tran Mills 191af22a668SRichard Tran Mills PetscFunctionBegin; 1929566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSELL_build_shadow(A)); 1939566063dSJacob Faibussowitsch PetscCall(MatSOR_SeqSELL(aijsell->S, bb, omega, flag, fshift, its, lits, xx)); 1943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 195af22a668SRichard Tran Mills } 196af22a668SRichard Tran Mills 1974dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a 1984dfdc2d9SRichard Tran Mills * SeqAIJSELL matrix. This routine is called by the MatCreate_SeqAIJSELL() 1994dfdc2d9SRichard Tran Mills * routine, but can also be used to convert an assembled SeqAIJ matrix 2004dfdc2d9SRichard Tran Mills * into a SeqAIJSELL one. */ 201d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A, MatType type, MatReuse reuse, Mat *newmat) 202d71ae5a4SJacob Faibussowitsch { 2034dfdc2d9SRichard Tran Mills Mat B = *newmat; 2044dfdc2d9SRichard Tran Mills Mat_SeqAIJ *b; 2054dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell; 2064dfdc2d9SRichard Tran Mills PetscBool set; 2074dfdc2d9SRichard Tran Mills PetscBool sametype; 2084dfdc2d9SRichard Tran Mills 2094dfdc2d9SRichard Tran Mills PetscFunctionBegin; 21048a46eb9SPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B)); 2114dfdc2d9SRichard Tran Mills 2129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, type, &sametype)); 2133ba16761SJacob Faibussowitsch if (sametype) PetscFunctionReturn(PETSC_SUCCESS); 2144dfdc2d9SRichard Tran Mills 2154dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&aijsell)); 2164dfdc2d9SRichard Tran Mills b = (Mat_SeqAIJ *)B->data; 2174dfdc2d9SRichard Tran Mills B->spptr = (void *)aijsell; 2184dfdc2d9SRichard Tran Mills 2194dfdc2d9SRichard Tran Mills /* Disable use of the inode routines so that the AIJSELL ones will be used instead. 2204dfdc2d9SRichard Tran Mills * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too. 2214dfdc2d9SRichard Tran Mills * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */ 2224dfdc2d9SRichard Tran Mills b->inode.use = PETSC_FALSE; 2234dfdc2d9SRichard Tran Mills 2244dfdc2d9SRichard Tran Mills /* Set function pointers for methods that we inherit from AIJ but override. 2254dfdc2d9SRichard Tran Mills * We also parse some command line options below, since those determine some of the methods we point to. */ 2264dfdc2d9SRichard Tran Mills B->ops->duplicate = MatDuplicate_SeqAIJSELL; 2274dfdc2d9SRichard Tran Mills B->ops->assemblyend = MatAssemblyEnd_SeqAIJSELL; 2284dfdc2d9SRichard Tran Mills B->ops->destroy = MatDestroy_SeqAIJSELL; 2294dfdc2d9SRichard Tran Mills 2304dfdc2d9SRichard Tran Mills aijsell->S = NULL; 2314dfdc2d9SRichard Tran Mills aijsell->eager_shadow = PETSC_FALSE; 2324dfdc2d9SRichard Tran Mills 2334dfdc2d9SRichard Tran Mills /* Parse command line options. */ 234d0609cedSBarry Smith PetscOptionsBegin(PetscObjectComm((PetscObject)A), ((PetscObject)A)->prefix, "AIJSELL Options", "Mat"); 235*835f2295SStefano Zampini PetscCall(PetscOptionsBool("-mat_aijsell_eager_shadow", "Eager Shadowing", "None", aijsell->eager_shadow, &aijsell->eager_shadow, &set)); 236d0609cedSBarry Smith PetscOptionsEnd(); 2374dfdc2d9SRichard Tran Mills 2384dfdc2d9SRichard Tran Mills /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */ 23948a46eb9SPierre Jolivet if (A->assembled && aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A)); 2404dfdc2d9SRichard Tran Mills 241b0e5de86SRichard Tran Mills B->ops->mult = MatMult_SeqAIJSELL; 242b0e5de86SRichard Tran Mills B->ops->multtranspose = MatMultTranspose_SeqAIJSELL; 243b0e5de86SRichard Tran Mills B->ops->multadd = MatMultAdd_SeqAIJSELL; 244b0e5de86SRichard Tran Mills B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL; 245af22a668SRichard Tran Mills B->ops->sor = MatSOR_SeqAIJSELL; 2464dfdc2d9SRichard Tran Mills 2479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqaijsell_seqaij_C", MatConvert_SeqAIJSELL_SeqAIJ)); 2484dfdc2d9SRichard Tran Mills 2499566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJSELL)); 2504dfdc2d9SRichard Tran Mills *newmat = B; 2513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2524dfdc2d9SRichard Tran Mills } 2534dfdc2d9SRichard Tran Mills 2544dfdc2d9SRichard Tran Mills /*@C 25511a5261eSBarry Smith MatCreateSeqAIJSELL - Creates a sparse matrix of type `MATSEQAIJSELL`. 2564dfdc2d9SRichard Tran Mills 257d083f849SBarry Smith Collective 2584dfdc2d9SRichard Tran Mills 2594dfdc2d9SRichard Tran Mills Input Parameters: 26011a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 2614dfdc2d9SRichard Tran Mills . m - number of rows 2624dfdc2d9SRichard Tran Mills . n - number of columns 2634dfdc2d9SRichard Tran Mills . nz - number of nonzeros per row (same for all rows) 2644dfdc2d9SRichard Tran Mills - nnz - array containing the number of nonzeros in the various rows 2652ef1f0ffSBarry Smith (possibly different for each row) or `NULL` 2664dfdc2d9SRichard Tran Mills 2674dfdc2d9SRichard Tran Mills Output Parameter: 2684dfdc2d9SRichard Tran Mills . A - the matrix 2694dfdc2d9SRichard Tran Mills 2704dfdc2d9SRichard Tran Mills Options Database Keys: 2712ef1f0ffSBarry Smith . -mat_aijsell_eager_shadow - Construct shadow matrix upon matrix assembly; default is to take a "lazy" approach, 2722ef1f0ffSBarry Smith performing this step the first time the matrix is applied 2732ef1f0ffSBarry Smith 2742ef1f0ffSBarry Smith Level: intermediate 2754dfdc2d9SRichard Tran Mills 2764dfdc2d9SRichard Tran Mills Notes: 2772920cce0SJacob Faibussowitsch This type inherits from AIJ and is largely identical, but keeps a "shadow" copy of the matrix 2782920cce0SJacob Faibussowitsch in `MATSEQSELL` format, which is used when this format may be more suitable for a requested 2792920cce0SJacob Faibussowitsch operation. Currently, `MATSEQSELL` format is used for `MatMult()`, `MatMultTranspose()`, 2802920cce0SJacob Faibussowitsch `MatMultAdd()`, `MatMultTransposeAdd()`, and `MatSOR()` operations. 2812920cce0SJacob Faibussowitsch 2822ef1f0ffSBarry Smith If `nnz` is given then `nz` is ignored 2834dfdc2d9SRichard Tran Mills 284aa624791SPierre Jolivet Because `MATSEQAIJSELL` is a subtype of `MATSEQAIJ`, the option `-mat_seqaij_type seqaijsell` can be used to make 285aa624791SPierre Jolivet sequential `MATSEQAIJ` matrices default to being instances of `MATSEQAIJSELL`. 28611a5261eSBarry Smith 2871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreate()`, `MatCreateMPIAIJSELL()`, `MatSetValues()` 2884dfdc2d9SRichard Tran Mills @*/ 289d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqAIJSELL(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt nz, const PetscInt nnz[], Mat *A) 290d71ae5a4SJacob Faibussowitsch { 2914dfdc2d9SRichard Tran Mills PetscFunctionBegin; 2929566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 2939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 2949566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQAIJSELL)); 2959566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation_SeqAIJ(*A, nz, nnz)); 2963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2974dfdc2d9SRichard Tran Mills } 2984dfdc2d9SRichard Tran Mills 299d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A) 300d71ae5a4SJacob Faibussowitsch { 3014dfdc2d9SRichard Tran Mills PetscFunctionBegin; 3029566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATSEQAIJ)); 3039566063dSJacob Faibussowitsch PetscCall(MatConvert_SeqAIJ_SeqAIJSELL(A, MATSEQAIJSELL, MAT_INPLACE_MATRIX, &A)); 3043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3054dfdc2d9SRichard Tran Mills } 306