xref: /petsc/src/mat/impls/aij/seq/aijsell/aijsell.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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 
179371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJSELL_SeqAIJ(Mat A, MatType type, MatReuse reuse, Mat *newmat) {
184dfdc2d9SRichard Tran Mills   /* This routine is only called to convert a MATAIJSELL to its base PETSc type, */
194dfdc2d9SRichard Tran Mills   /* so we will ignore 'MatType type'. */
204dfdc2d9SRichard Tran Mills   Mat             B       = *newmat;
214dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
224dfdc2d9SRichard Tran Mills 
234dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
24*48a46eb9SPierre Jolivet   if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B));
254dfdc2d9SRichard Tran Mills 
264dfdc2d9SRichard Tran Mills   /* Reset the original function pointers. */
274dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJ;
284dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJ;
294dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJ;
304dfdc2d9SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJ;
314dfdc2d9SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJ;
324dfdc2d9SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJ;
334dfdc2d9SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJ;
34af22a668SRichard Tran Mills   B->ops->sor              = MatSOR_SeqAIJ;
354dfdc2d9SRichard Tran Mills 
369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqaijsell_seqaij_C", NULL));
374dfdc2d9SRichard Tran Mills 
384dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL *)B->spptr;
394dfdc2d9SRichard Tran Mills 
408cde19baSRichard Tran Mills   /* Clean up the Mat_SeqAIJSELL data structure.
418cde19baSRichard 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. */
429566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&aijsell->S));
439566063dSJacob Faibussowitsch   PetscCall(PetscFree(B->spptr));
444dfdc2d9SRichard Tran Mills 
454dfdc2d9SRichard Tran Mills   /* Change the type of B to MATSEQAIJ. */
469566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ));
474dfdc2d9SRichard Tran Mills 
484dfdc2d9SRichard Tran Mills   *newmat = B;
494dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
504dfdc2d9SRichard Tran Mills }
514dfdc2d9SRichard Tran Mills 
529371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqAIJSELL(Mat A) {
534dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
544dfdc2d9SRichard Tran Mills 
554dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
564dfdc2d9SRichard Tran Mills 
574dfdc2d9SRichard Tran Mills   /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an
584dfdc2d9SRichard Tran Mills    * spptr pointer. */
594dfdc2d9SRichard Tran Mills   if (aijsell) {
604dfdc2d9SRichard Tran Mills     /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */
619566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&aijsell->S));
629566063dSJacob Faibussowitsch     PetscCall(PetscFree(A->spptr));
634dfdc2d9SRichard Tran Mills   }
644dfdc2d9SRichard Tran Mills 
654dfdc2d9SRichard Tran Mills   /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ()
664dfdc2d9SRichard Tran Mills    * to destroy everything that remains. */
679566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ));
684dfdc2d9SRichard Tran Mills   /* Note that I don't call MatSetType().  I believe this is because that
694dfdc2d9SRichard Tran Mills    * is only to be called when *building* a matrix.  I could be wrong, but
704dfdc2d9SRichard Tran Mills    * that is how things work for the SuperLU matrix class. */
712e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatConvert_seqaijsell_seqaij_C", NULL));
729566063dSJacob Faibussowitsch   PetscCall(MatDestroy_SeqAIJ(A));
734dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
744dfdc2d9SRichard Tran Mills }
754dfdc2d9SRichard Tran Mills 
76a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed.
77a2a1850bSRichard Tran Mills  * We track the ObjectState to determine when this needs to be done. */
789371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A) {
79b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell = (Mat_SeqAIJSELL *)A->spptr;
80a2a1850bSRichard Tran Mills   PetscObjectState state;
81b0e5de86SRichard Tran Mills 
82b0e5de86SRichard Tran Mills   PetscFunctionBegin;
839566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)A, &state));
84a2a1850bSRichard Tran Mills   if (aijsell->S && aijsell->state == state) {
85a2a1850bSRichard Tran Mills     /* The existing shadow matrix is up-to-date, so simply exit. */
86a2a1850bSRichard Tran Mills     PetscFunctionReturn(0);
87a2a1850bSRichard Tran Mills   }
88a2a1850bSRichard Tran Mills 
899566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(MAT_Convert, A, 0, 0, 0));
90b0e5de86SRichard Tran Mills   if (aijsell->S) {
919566063dSJacob Faibussowitsch     PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_REUSE_MATRIX, &aijsell->S));
92b0e5de86SRichard Tran Mills   } else {
939566063dSJacob Faibussowitsch     PetscCall(MatConvert_SeqAIJ_SeqSELL(A, MATSEQSELL, MAT_INITIAL_MATRIX, &aijsell->S));
94b0e5de86SRichard Tran Mills   }
959566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(MAT_Convert, A, 0, 0, 0));
96b0e5de86SRichard Tran Mills 
97b0e5de86SRichard Tran Mills   /* Record the ObjectState so that we can tell when the shadow matrix needs updating */
989566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)A, &aijsell->state));
99b0e5de86SRichard Tran Mills 
100b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
101b0e5de86SRichard Tran Mills }
102b0e5de86SRichard Tran Mills 
1039371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M) {
1044dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1054dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell_dest;
1064dfdc2d9SRichard Tran Mills 
1074dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1089566063dSJacob Faibussowitsch   PetscCall(MatDuplicate_SeqAIJ(A, op, M));
1094dfdc2d9SRichard Tran Mills   aijsell      = (Mat_SeqAIJSELL *)A->spptr;
1104dfdc2d9SRichard Tran Mills   aijsell_dest = (Mat_SeqAIJSELL *)(*M)->spptr;
1119566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(aijsell_dest, aijsell, 1));
1124dfdc2d9SRichard Tran Mills   /* We don't duplicate the shadow matrix -- that will be constructed as needed. */
1134dfdc2d9SRichard Tran Mills   aijsell_dest->S = NULL;
1141baa6e33SBarry Smith   if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A));
1154dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1164dfdc2d9SRichard Tran Mills }
1174dfdc2d9SRichard Tran Mills 
1189371c9d4SSatish Balay PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode) {
1194dfdc2d9SRichard Tran Mills   Mat_SeqAIJ     *a       = (Mat_SeqAIJ *)A->data;
1208cde19baSRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
1214dfdc2d9SRichard Tran Mills 
1224dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1234dfdc2d9SRichard Tran Mills   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
1244dfdc2d9SRichard Tran Mills 
1254dfdc2d9SRichard Tran Mills   /* I disable the use of the inode routines so that the AIJSELL ones will be
1264dfdc2d9SRichard Tran Mills    * used instead, but I wonder if it might make sense (and is feasible) to
1274dfdc2d9SRichard Tran Mills    * use some of them. */
1284dfdc2d9SRichard Tran Mills   a->inode.use = PETSC_FALSE;
1294dfdc2d9SRichard Tran Mills 
1304dfdc2d9SRichard Tran Mills   /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some
1314dfdc2d9SRichard Tran Mills    * extra information and some different methods, call the AssemblyEnd
1324dfdc2d9SRichard Tran Mills    * routine for a MATSEQAIJ.
1334dfdc2d9SRichard Tran Mills    * I'm not sure if this is the best way to do this, but it avoids
1344dfdc2d9SRichard Tran Mills    * a lot of code duplication. */
1354dfdc2d9SRichard Tran Mills 
1369566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd_SeqAIJ(A, mode));
1374dfdc2d9SRichard Tran Mills 
1384dfdc2d9SRichard Tran Mills   /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks).
1394dfdc2d9SRichard Tran Mills    * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */
1401baa6e33SBarry Smith   if (aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A));
1414dfdc2d9SRichard Tran Mills 
1424dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1434dfdc2d9SRichard Tran Mills }
1444dfdc2d9SRichard Tran Mills 
1459371c9d4SSatish Balay PetscErrorCode MatMult_SeqAIJSELL(Mat A, Vec xx, Vec yy) {
146b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
147b0e5de86SRichard Tran Mills 
148b0e5de86SRichard Tran Mills   PetscFunctionBegin;
1499566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSELL_build_shadow(A));
1509566063dSJacob Faibussowitsch   PetscCall(MatMult_SeqSELL(aijsell->S, xx, yy));
151b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
152b0e5de86SRichard Tran Mills }
153b0e5de86SRichard Tran Mills 
1549371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A, Vec xx, Vec yy) {
1554da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
1564da9d7bdSRichard Tran Mills 
1574da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1589566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSELL_build_shadow(A));
1599566063dSJacob Faibussowitsch   PetscCall(MatMultTranspose_SeqSELL(aijsell->S, xx, yy));
1604da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
1614da9d7bdSRichard Tran Mills }
1624da9d7bdSRichard Tran Mills 
1639371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) {
1644da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
1654da9d7bdSRichard Tran Mills 
1664da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1679566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSELL_build_shadow(A));
1689566063dSJacob Faibussowitsch   PetscCall(MatMultAdd_SeqSELL(aijsell->S, xx, yy, zz));
1694da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
1704da9d7bdSRichard Tran Mills }
1714da9d7bdSRichard Tran Mills 
1729371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A, Vec xx, Vec yy, Vec zz) {
1734da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
1744da9d7bdSRichard Tran Mills 
1754da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1769566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSELL_build_shadow(A));
1779566063dSJacob Faibussowitsch   PetscCall(MatMultTransposeAdd_SeqSELL(aijsell->S, xx, yy, zz));
1784da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
1794da9d7bdSRichard Tran Mills }
1804da9d7bdSRichard Tran Mills 
1819371c9d4SSatish Balay PetscErrorCode MatSOR_SeqAIJSELL(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal fshift, PetscInt its, PetscInt lits, Vec xx) {
182af22a668SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL *)A->spptr;
183af22a668SRichard Tran Mills 
184af22a668SRichard Tran Mills   PetscFunctionBegin;
1859566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSELL_build_shadow(A));
1869566063dSJacob Faibussowitsch   PetscCall(MatSOR_SeqSELL(aijsell->S, bb, omega, flag, fshift, its, lits, xx));
187af22a668SRichard Tran Mills   PetscFunctionReturn(0);
188af22a668SRichard Tran Mills }
189af22a668SRichard Tran Mills 
1904dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a
1914dfdc2d9SRichard Tran Mills  * SeqAIJSELL matrix.  This routine is called by the MatCreate_SeqAIJSELL()
1924dfdc2d9SRichard Tran Mills  * routine, but can also be used to convert an assembled SeqAIJ matrix
1934dfdc2d9SRichard Tran Mills  * into a SeqAIJSELL one. */
1949371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A, MatType type, MatReuse reuse, Mat *newmat) {
1954dfdc2d9SRichard Tran Mills   Mat             B = *newmat;
1964dfdc2d9SRichard Tran Mills   Mat_SeqAIJ     *b;
1974dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1984dfdc2d9SRichard Tran Mills   PetscBool       set;
1994dfdc2d9SRichard Tran Mills   PetscBool       sametype;
2004dfdc2d9SRichard Tran Mills 
2014dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
202*48a46eb9SPierre Jolivet   if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B));
2034dfdc2d9SRichard Tran Mills 
2049566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)A, type, &sametype));
2054dfdc2d9SRichard Tran Mills   if (sametype) PetscFunctionReturn(0);
2064dfdc2d9SRichard Tran Mills 
2079566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B, &aijsell));
2084dfdc2d9SRichard Tran Mills   b        = (Mat_SeqAIJ *)B->data;
2094dfdc2d9SRichard Tran Mills   B->spptr = (void *)aijsell;
2104dfdc2d9SRichard Tran Mills 
2114dfdc2d9SRichard Tran Mills   /* Disable use of the inode routines so that the AIJSELL ones will be used instead.
2124dfdc2d9SRichard Tran Mills    * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too.
2134dfdc2d9SRichard Tran Mills    * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */
2144dfdc2d9SRichard Tran Mills   b->inode.use = PETSC_FALSE;
2154dfdc2d9SRichard Tran Mills 
2164dfdc2d9SRichard Tran Mills   /* Set function pointers for methods that we inherit from AIJ but override.
2174dfdc2d9SRichard Tran Mills    * We also parse some command line options below, since those determine some of the methods we point to. */
2184dfdc2d9SRichard Tran Mills   B->ops->duplicate   = MatDuplicate_SeqAIJSELL;
2194dfdc2d9SRichard Tran Mills   B->ops->assemblyend = MatAssemblyEnd_SeqAIJSELL;
2204dfdc2d9SRichard Tran Mills   B->ops->destroy     = MatDestroy_SeqAIJSELL;
2214dfdc2d9SRichard Tran Mills 
2224dfdc2d9SRichard Tran Mills   aijsell->S            = NULL;
2234dfdc2d9SRichard Tran Mills   aijsell->eager_shadow = PETSC_FALSE;
2244dfdc2d9SRichard Tran Mills 
2254dfdc2d9SRichard Tran Mills   /* Parse command line options. */
226d0609cedSBarry Smith   PetscOptionsBegin(PetscObjectComm((PetscObject)A), ((PetscObject)A)->prefix, "AIJSELL Options", "Mat");
2279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-mat_aijsell_eager_shadow", "Eager Shadowing", "None", (PetscBool)aijsell->eager_shadow, (PetscBool *)&aijsell->eager_shadow, &set));
228d0609cedSBarry Smith   PetscOptionsEnd();
2294dfdc2d9SRichard Tran Mills 
2304dfdc2d9SRichard Tran Mills   /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */
231*48a46eb9SPierre Jolivet   if (A->assembled && aijsell->eager_shadow) PetscCall(MatSeqAIJSELL_build_shadow(A));
2324dfdc2d9SRichard Tran Mills 
233b0e5de86SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJSELL;
234b0e5de86SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJSELL;
235b0e5de86SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJSELL;
236b0e5de86SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL;
237af22a668SRichard Tran Mills   B->ops->sor              = MatSOR_SeqAIJSELL;
2384dfdc2d9SRichard Tran Mills 
2399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqaijsell_seqaij_C", MatConvert_SeqAIJSELL_SeqAIJ));
2404dfdc2d9SRichard Tran Mills 
2419566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJSELL));
2424dfdc2d9SRichard Tran Mills   *newmat = B;
2434dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2444dfdc2d9SRichard Tran Mills }
2454dfdc2d9SRichard Tran Mills 
2464dfdc2d9SRichard Tran Mills /*@C
2474dfdc2d9SRichard Tran Mills    MatCreateSeqAIJSELL - Creates a sparse matrix of type SEQAIJSELL.
2484dfdc2d9SRichard Tran Mills    This type inherits from AIJ and is largely identical, but keeps a "shadow"
2498197ac24SRichard Tran Mills    copy of the matrix in SEQSELL format, which is used when this format
2508197ac24SRichard Tran Mills    may be more suitable for a requested operation. Currently, SEQSELL format
2518197ac24SRichard Tran Mills    is used for MatMult, MatMultTranspose, MatMultAdd, MatMultTransposeAdd,
2528197ac24SRichard Tran Mills    and MatSOR operations.
253ca9cdca7SRichard Tran Mills    Because SEQAIJSELL is a subtype of SEQAIJ, the option "-mat_seqaij_type seqaijsell" can be used to make
254ca9cdca7SRichard Tran Mills    sequential AIJ matrices default to being instances of MATSEQAIJSELL.
2554dfdc2d9SRichard Tran Mills 
256d083f849SBarry Smith    Collective
2574dfdc2d9SRichard Tran Mills 
2584dfdc2d9SRichard Tran Mills    Input Parameters:
2594dfdc2d9SRichard Tran Mills +  comm - MPI communicator, set to PETSC_COMM_SELF
2604dfdc2d9SRichard Tran Mills .  m - number of rows
2614dfdc2d9SRichard Tran Mills .  n - number of columns
2624dfdc2d9SRichard Tran Mills .  nz - number of nonzeros per row (same for all rows)
2634dfdc2d9SRichard Tran Mills -  nnz - array containing the number of nonzeros in the various rows
2644dfdc2d9SRichard Tran Mills          (possibly different for each row) or NULL
2654dfdc2d9SRichard Tran Mills 
2664dfdc2d9SRichard Tran Mills    Output Parameter:
2674dfdc2d9SRichard Tran Mills .  A - the matrix
2684dfdc2d9SRichard Tran Mills 
2694dfdc2d9SRichard Tran Mills    Options Database Keys:
2704dfdc2d9SRichard Tran Mills .  -mat_aijsell_eager_shadow - Construct shadow matrix upon matrix assembly; default is to take a "lazy" approach, performing this step the first time the matrix is applied
2714dfdc2d9SRichard Tran Mills 
2724dfdc2d9SRichard Tran Mills    Notes:
2734dfdc2d9SRichard Tran Mills    If nnz is given then nz is ignored
2744dfdc2d9SRichard Tran Mills 
2754dfdc2d9SRichard Tran Mills    Level: intermediate
2764dfdc2d9SRichard Tran Mills 
277db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateMPIAIJSELL()`, `MatSetValues()`
2784dfdc2d9SRichard Tran Mills @*/
2799371c9d4SSatish Balay PetscErrorCode MatCreateSeqAIJSELL(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt nz, const PetscInt nnz[], Mat *A) {
2804dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2819566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
2829566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
2839566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQAIJSELL));
2849566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSetPreallocation_SeqAIJ(*A, nz, nnz));
2854dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2864dfdc2d9SRichard Tran Mills }
2874dfdc2d9SRichard Tran Mills 
2889371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A) {
2894dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2909566063dSJacob Faibussowitsch   PetscCall(MatSetType(A, MATSEQAIJ));
2919566063dSJacob Faibussowitsch   PetscCall(MatConvert_SeqAIJ_SeqAIJSELL(A, MATSEQAIJSELL, MAT_INPLACE_MATRIX, &A));
2924dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2934dfdc2d9SRichard Tran Mills }
294