xref: /petsc/src/mat/impls/aij/seq/aijsell/aijsell.c (revision a2a1850b0996193d10f1d358d457171e68eb9dd4)
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 
174dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJSELL_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat)
184dfdc2d9SRichard Tran Mills {
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   PetscErrorCode ierr;
224dfdc2d9SRichard Tran Mills   Mat            B        = *newmat;
234dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL*) A->spptr;
244dfdc2d9SRichard Tran Mills 
254dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
264dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) {
274dfdc2d9SRichard Tran Mills     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
284dfdc2d9SRichard Tran Mills   }
294dfdc2d9SRichard Tran Mills 
304dfdc2d9SRichard Tran Mills   /* Reset the original function pointers. */
314dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJ;
324dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJ;
334dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJ;
344dfdc2d9SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJ;
354dfdc2d9SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJ;
364dfdc2d9SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJ;
374dfdc2d9SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJ;
384dfdc2d9SRichard Tran Mills 
394dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",NULL);CHKERRQ(ierr);
404dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
414dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
424dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
434dfdc2d9SRichard Tran Mills 
444dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL*)B->spptr;
454dfdc2d9SRichard Tran Mills 
464dfdc2d9SRichard Tran Mills   /* Clean up the Mat_SeqAIJSELL data structure. */
474dfdc2d9SRichard Tran Mills   if(aijsell->S) {
484dfdc2d9SRichard Tran Mills     ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
494dfdc2d9SRichard Tran Mills   }
504dfdc2d9SRichard Tran Mills   ierr = PetscFree(B->spptr);CHKERRQ(ierr);
514dfdc2d9SRichard Tran Mills 
524dfdc2d9SRichard Tran Mills   /* Change the type of B to MATSEQAIJ. */
534dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ);CHKERRQ(ierr);
544dfdc2d9SRichard Tran Mills 
554dfdc2d9SRichard Tran Mills   *newmat = B;
564dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
574dfdc2d9SRichard Tran Mills }
584dfdc2d9SRichard Tran Mills 
594dfdc2d9SRichard Tran Mills PetscErrorCode MatDestroy_SeqAIJSELL(Mat A)
604dfdc2d9SRichard Tran Mills {
614dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
624dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell = (Mat_SeqAIJSELL*) A->spptr;
634dfdc2d9SRichard Tran Mills 
644dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
654dfdc2d9SRichard Tran Mills 
664dfdc2d9SRichard Tran Mills   /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an
674dfdc2d9SRichard Tran Mills    * spptr pointer. */
684dfdc2d9SRichard Tran Mills   if (aijsell) {
694dfdc2d9SRichard Tran Mills     /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */
704dfdc2d9SRichard Tran Mills     if (aijsell->S) {
714dfdc2d9SRichard Tran Mills       ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
724dfdc2d9SRichard Tran Mills     }
734dfdc2d9SRichard Tran Mills     ierr = PetscFree(A->spptr);CHKERRQ(ierr);
744dfdc2d9SRichard Tran Mills   }
754dfdc2d9SRichard Tran Mills 
764dfdc2d9SRichard Tran Mills   /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ()
774dfdc2d9SRichard Tran Mills    * to destroy everything that remains. */
784dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ);CHKERRQ(ierr);
794dfdc2d9SRichard Tran Mills   /* Note that I don't call MatSetType().  I believe this is because that
804dfdc2d9SRichard Tran Mills    * is only to be called when *building* a matrix.  I could be wrong, but
814dfdc2d9SRichard Tran Mills    * that is how things work for the SuperLU matrix class. */
824dfdc2d9SRichard Tran Mills   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
834dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
844dfdc2d9SRichard Tran Mills }
854dfdc2d9SRichard Tran Mills 
86*a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed.
87*a2a1850bSRichard Tran Mills  * We track the ObjectState to determine when this needs to be done. */
88b0e5de86SRichard Tran Mills PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A)
89b0e5de86SRichard Tran Mills {
90b0e5de86SRichard Tran Mills   PetscErrorCode   ierr;
91b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL   *aijsell = (Mat_SeqAIJSELL*) A->spptr;
92*a2a1850bSRichard Tran Mills   PetscObjectState state;
93b0e5de86SRichard Tran Mills 
94b0e5de86SRichard Tran Mills   PetscFunctionBegin;
95b0e5de86SRichard Tran Mills 
96*a2a1850bSRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&state);CHKERRQ(ierr);
97*a2a1850bSRichard Tran Mills   if (aijsell->S && aijsell->state == state) {
98*a2a1850bSRichard Tran Mills     /* The existing shadow matrix is up-to-date, so simply exit. */
99*a2a1850bSRichard Tran Mills     PetscFunctionReturn(0);
100*a2a1850bSRichard Tran Mills   }
101*a2a1850bSRichard Tran Mills 
102b0e5de86SRichard Tran Mills   if (aijsell->S) {
103b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_REUSE_MATRIX,&aijsell->S);CHKERRQ(ierr);
104b0e5de86SRichard Tran Mills   } else {
105b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_INITIAL_MATRIX,&aijsell->S);CHKERRQ(ierr);
106b0e5de86SRichard Tran Mills   }
107b0e5de86SRichard Tran Mills 
108b0e5de86SRichard Tran Mills   /* Record the ObjectState so that we can tell when the shadow matrix needs updating */
109b0e5de86SRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&aijsell->state);CHKERRQ(ierr);
110b0e5de86SRichard Tran Mills 
111b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
112b0e5de86SRichard Tran Mills }
113b0e5de86SRichard Tran Mills 
1144dfdc2d9SRichard Tran Mills PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M)
1154dfdc2d9SRichard Tran Mills {
1164dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
1174dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1184dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell_dest;
1194dfdc2d9SRichard Tran Mills 
1204dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1214dfdc2d9SRichard Tran Mills   ierr = MatDuplicate_SeqAIJ(A,op,M);CHKERRQ(ierr);
1224dfdc2d9SRichard Tran Mills   aijsell      = (Mat_SeqAIJSELL*) A->spptr;
1234dfdc2d9SRichard Tran Mills   aijsell_dest = (Mat_SeqAIJSELL*) (*M)->spptr;
1244dfdc2d9SRichard Tran Mills   ierr = PetscMemcpy(aijsell_dest,aijsell,sizeof(Mat_SeqAIJSELL));CHKERRQ(ierr);
1254dfdc2d9SRichard Tran Mills   /* We don't duplicate the shadow matrix -- that will be constructed as needed. */
1264dfdc2d9SRichard Tran Mills   aijsell_dest->S = NULL;
1274dfdc2d9SRichard Tran Mills   /* TODO: Have the shadow matrix be built now if eager_shadow is set to true. */
1284dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1294dfdc2d9SRichard Tran Mills }
1304dfdc2d9SRichard Tran Mills 
1314dfdc2d9SRichard Tran Mills PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode)
1324dfdc2d9SRichard Tran Mills {
1334dfdc2d9SRichard Tran Mills   PetscErrorCode  ierr;
1344dfdc2d9SRichard Tran Mills   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
1354dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell;
1364dfdc2d9SRichard Tran Mills 
1374dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1384dfdc2d9SRichard Tran Mills   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
1394dfdc2d9SRichard Tran Mills 
1404dfdc2d9SRichard Tran Mills   /* I disable the use of the inode routines so that the AIJSELL ones will be
1414dfdc2d9SRichard Tran Mills    * used instead, but I wonder if it might make sense (and is feasible) to
1424dfdc2d9SRichard Tran Mills    * use some of them. */
1434dfdc2d9SRichard Tran Mills   a->inode.use = PETSC_FALSE;
1444dfdc2d9SRichard Tran Mills 
1454dfdc2d9SRichard Tran Mills   /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some
1464dfdc2d9SRichard Tran Mills    * extra information and some different methods, call the AssemblyEnd
1474dfdc2d9SRichard Tran Mills    * routine for a MATSEQAIJ.
1484dfdc2d9SRichard Tran Mills    * I'm not sure if this is the best way to do this, but it avoids
1494dfdc2d9SRichard Tran Mills    * a lot of code duplication. */
1504dfdc2d9SRichard Tran Mills 
1514dfdc2d9SRichard Tran Mills   ierr = MatAssemblyEnd_SeqAIJ(A, mode);CHKERRQ(ierr);
1524dfdc2d9SRichard Tran Mills 
1534dfdc2d9SRichard Tran Mills   /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks).
1544dfdc2d9SRichard Tran Mills    * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */
1554dfdc2d9SRichard Tran Mills   aijsell = (Mat_SeqAIJSELL*) A->spptr;
1564dfdc2d9SRichard Tran Mills   if (aijsell->eager_shadow) {
1574dfdc2d9SRichard Tran Mills     /* TODO: Construct the shadow matrix here. */
1584dfdc2d9SRichard Tran Mills   }
1594dfdc2d9SRichard Tran Mills 
1604dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1614dfdc2d9SRichard Tran Mills }
1624dfdc2d9SRichard Tran Mills 
163b0e5de86SRichard Tran Mills PetscErrorCode MatMult_SeqAIJSELL(Mat A,Vec xx,Vec yy)
164b0e5de86SRichard Tran Mills {
165b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
166b0e5de86SRichard Tran Mills   PetscErrorCode    ierr;
167b0e5de86SRichard Tran Mills 
168b0e5de86SRichard Tran Mills   PetscFunctionBegin;
169b0e5de86SRichard Tran Mills 
170b0e5de86SRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
171b0e5de86SRichard Tran Mills   ierr = MatMult(aijsell->S,xx,yy);CHKERRQ(ierr);
172b0e5de86SRichard Tran Mills 
173b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
174b0e5de86SRichard Tran Mills }
175b0e5de86SRichard Tran Mills 
1764dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a
1774dfdc2d9SRichard Tran Mills  * SeqAIJSELL matrix.  This routine is called by the MatCreate_SeqAIJSELL()
1784dfdc2d9SRichard Tran Mills  * routine, but can also be used to convert an assembled SeqAIJ matrix
1794dfdc2d9SRichard Tran Mills  * into a SeqAIJSELL one. */
1804dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A,MatType type,MatReuse reuse,Mat *newmat)
1814dfdc2d9SRichard Tran Mills {
1824dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
1834dfdc2d9SRichard Tran Mills   Mat            B = *newmat;
1844dfdc2d9SRichard Tran Mills   Mat_SeqAIJ     *b;
1854dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1864dfdc2d9SRichard Tran Mills   PetscBool      set;
1874dfdc2d9SRichard Tran Mills   PetscBool      sametype;
1884dfdc2d9SRichard Tran Mills 
1894dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1904dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) {
1914dfdc2d9SRichard Tran Mills     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
1924dfdc2d9SRichard Tran Mills   }
1934dfdc2d9SRichard Tran Mills 
1944dfdc2d9SRichard Tran Mills   ierr = PetscObjectTypeCompare((PetscObject)A,type,&sametype);CHKERRQ(ierr);
1954dfdc2d9SRichard Tran Mills   if (sametype) PetscFunctionReturn(0);
1964dfdc2d9SRichard Tran Mills 
1974dfdc2d9SRichard Tran Mills   ierr     = PetscNewLog(B,&aijsell);CHKERRQ(ierr);
1984dfdc2d9SRichard Tran Mills   b        = (Mat_SeqAIJ*) B->data;
1994dfdc2d9SRichard Tran Mills   B->spptr = (void*) aijsell;
2004dfdc2d9SRichard Tran Mills 
2014dfdc2d9SRichard Tran Mills   /* Disable use of the inode routines so that the AIJSELL ones will be used instead.
2024dfdc2d9SRichard Tran Mills    * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too.
2034dfdc2d9SRichard Tran Mills    * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */
2044dfdc2d9SRichard Tran Mills   b->inode.use = PETSC_FALSE;
2054dfdc2d9SRichard Tran Mills 
2064dfdc2d9SRichard Tran Mills   /* Set function pointers for methods that we inherit from AIJ but override.
2074dfdc2d9SRichard Tran Mills    * We also parse some command line options below, since those determine some of the methods we point to. */
2084dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJSELL;
2094dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJSELL;
2104dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJSELL;
2114dfdc2d9SRichard Tran Mills 
2124dfdc2d9SRichard Tran Mills   aijsell->S = NULL;
2134dfdc2d9SRichard Tran Mills   aijsell->eager_shadow = PETSC_FALSE;
2144dfdc2d9SRichard Tran Mills 
2154dfdc2d9SRichard Tran Mills   /* Parse command line options. */
2164dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"AIJSELL Options","Mat");CHKERRQ(ierr);
2174dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBool("-mat_aijsell_eager_shadow","Eager Shadowing","None",(PetscBool)aijsell->eager_shadow,(PetscBool*)&aijsell->eager_shadow,&set);CHKERRQ(ierr);
2184dfdc2d9SRichard Tran Mills   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2194dfdc2d9SRichard Tran Mills 
2204dfdc2d9SRichard Tran Mills   /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */
2214dfdc2d9SRichard Tran Mills   if (A->assembled) {
2224dfdc2d9SRichard Tran Mills     /* TODO: Have the shadow matrix for B be built now if eager_shadow is set to true. */
2234dfdc2d9SRichard Tran Mills   }
2244dfdc2d9SRichard Tran Mills 
225b0e5de86SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJSELL;
2264dfdc2d9SRichard Tran Mills /* Commenting these out for now, as these functions are not yet implemented.
227b0e5de86SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJSELL;
228b0e5de86SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJSELL;
229b0e5de86SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL;
2304dfdc2d9SRichard Tran Mills */
2314dfdc2d9SRichard Tran Mills 
2324dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",MatConvert_SeqAIJSELL_SeqAIJ);CHKERRQ(ierr);
2334dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
2344dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
2354dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
2364dfdc2d9SRichard Tran Mills 
2374dfdc2d9SRichard Tran Mills   ierr    = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJSELL);CHKERRQ(ierr);
2384dfdc2d9SRichard Tran Mills   *newmat = B;
2394dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2404dfdc2d9SRichard Tran Mills }
2414dfdc2d9SRichard Tran Mills 
2424dfdc2d9SRichard Tran Mills /*@C
2434dfdc2d9SRichard Tran Mills    MatCreateSeqAIJSELL - Creates a sparse matrix of type SEQAIJSELL.
2444dfdc2d9SRichard Tran Mills    This type inherits from AIJ and is largely identical, but keeps a "shadow"
2454dfdc2d9SRichard Tran Mills    copy of the matrix in SEQSELL format, which is used when performing
2464dfdc2d9SRichard Tran Mills    operations for which this format is more suitable.
2474dfdc2d9SRichard Tran Mills 
2484dfdc2d9SRichard Tran Mills    Collective on MPI_Comm
2494dfdc2d9SRichard Tran Mills 
2504dfdc2d9SRichard Tran Mills    Input Parameters:
2514dfdc2d9SRichard Tran Mills +  comm - MPI communicator, set to PETSC_COMM_SELF
2524dfdc2d9SRichard Tran Mills .  m - number of rows
2534dfdc2d9SRichard Tran Mills .  n - number of columns
2544dfdc2d9SRichard Tran Mills .  nz - number of nonzeros per row (same for all rows)
2554dfdc2d9SRichard Tran Mills -  nnz - array containing the number of nonzeros in the various rows
2564dfdc2d9SRichard Tran Mills          (possibly different for each row) or NULL
2574dfdc2d9SRichard Tran Mills 
2584dfdc2d9SRichard Tran Mills    Output Parameter:
2594dfdc2d9SRichard Tran Mills .  A - the matrix
2604dfdc2d9SRichard Tran Mills 
2614dfdc2d9SRichard Tran Mills    Options Database Keys:
2624dfdc2d9SRichard 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
2634dfdc2d9SRichard Tran Mills 
2644dfdc2d9SRichard Tran Mills    Notes:
2654dfdc2d9SRichard Tran Mills    If nnz is given then nz is ignored
2664dfdc2d9SRichard Tran Mills 
2674dfdc2d9SRichard Tran Mills    Level: intermediate
2684dfdc2d9SRichard Tran Mills 
2694dfdc2d9SRichard Tran Mills .keywords: matrix, sparse, parallel
2704dfdc2d9SRichard Tran Mills 
2714dfdc2d9SRichard Tran Mills .seealso: MatCreate(), MatCreateMPIAIJSELL(), MatSetValues()
2724dfdc2d9SRichard Tran Mills @*/
2734dfdc2d9SRichard Tran Mills PetscErrorCode  MatCreateSeqAIJSELL(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
2744dfdc2d9SRichard Tran Mills {
2754dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
2764dfdc2d9SRichard Tran Mills 
2774dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2784dfdc2d9SRichard Tran Mills   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2794dfdc2d9SRichard Tran Mills   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2804dfdc2d9SRichard Tran Mills   ierr = MatSetType(*A,MATSEQAIJSELL);CHKERRQ(ierr);
2814dfdc2d9SRichard Tran Mills   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
2824dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2834dfdc2d9SRichard Tran Mills }
2844dfdc2d9SRichard Tran Mills 
2854dfdc2d9SRichard Tran Mills PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A)
2864dfdc2d9SRichard Tran Mills {
2874dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
2884dfdc2d9SRichard Tran Mills 
2894dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2904dfdc2d9SRichard Tran Mills   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
2914dfdc2d9SRichard Tran Mills   ierr = MatConvert_SeqAIJ_SeqAIJSELL(A,MATSEQAIJSELL,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
2924dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2934dfdc2d9SRichard Tran Mills }
294