xref: /petsc/src/mat/impls/aij/seq/aijsell/aijsell.c (revision 84920f4bdbf5b94e3b491b3847ee7a71b64775f1)
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);
43*84920f4bSRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",NULL);CHKERRQ(ierr);
444dfdc2d9SRichard Tran Mills 
454dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL*)B->spptr;
464dfdc2d9SRichard Tran Mills 
474dfdc2d9SRichard Tran Mills   /* Clean up the Mat_SeqAIJSELL data structure. */
484dfdc2d9SRichard Tran Mills   if(aijsell->S) {
494dfdc2d9SRichard Tran Mills     ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
504dfdc2d9SRichard Tran Mills   }
514dfdc2d9SRichard Tran Mills   ierr = PetscFree(B->spptr);CHKERRQ(ierr);
524dfdc2d9SRichard Tran Mills 
534dfdc2d9SRichard Tran Mills   /* Change the type of B to MATSEQAIJ. */
544dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ);CHKERRQ(ierr);
554dfdc2d9SRichard Tran Mills 
564dfdc2d9SRichard Tran Mills   *newmat = B;
574dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
584dfdc2d9SRichard Tran Mills }
594dfdc2d9SRichard Tran Mills 
604dfdc2d9SRichard Tran Mills PetscErrorCode MatDestroy_SeqAIJSELL(Mat A)
614dfdc2d9SRichard Tran Mills {
624dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
634dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell = (Mat_SeqAIJSELL*) A->spptr;
644dfdc2d9SRichard Tran Mills 
654dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
664dfdc2d9SRichard Tran Mills 
674dfdc2d9SRichard Tran Mills   /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an
684dfdc2d9SRichard Tran Mills    * spptr pointer. */
694dfdc2d9SRichard Tran Mills   if (aijsell) {
704dfdc2d9SRichard Tran Mills     /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */
714dfdc2d9SRichard Tran Mills     if (aijsell->S) {
724dfdc2d9SRichard Tran Mills       ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
734dfdc2d9SRichard Tran Mills     }
744dfdc2d9SRichard Tran Mills     ierr = PetscFree(A->spptr);CHKERRQ(ierr);
754dfdc2d9SRichard Tran Mills   }
764dfdc2d9SRichard Tran Mills 
774dfdc2d9SRichard Tran Mills   /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ()
784dfdc2d9SRichard Tran Mills    * to destroy everything that remains. */
794dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ);CHKERRQ(ierr);
804dfdc2d9SRichard Tran Mills   /* Note that I don't call MatSetType().  I believe this is because that
814dfdc2d9SRichard Tran Mills    * is only to be called when *building* a matrix.  I could be wrong, but
824dfdc2d9SRichard Tran Mills    * that is how things work for the SuperLU matrix class. */
834dfdc2d9SRichard Tran Mills   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
844dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
854dfdc2d9SRichard Tran Mills }
864dfdc2d9SRichard Tran Mills 
87a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed.
88a2a1850bSRichard Tran Mills  * We track the ObjectState to determine when this needs to be done. */
89b0e5de86SRichard Tran Mills PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A)
90b0e5de86SRichard Tran Mills {
91b0e5de86SRichard Tran Mills   PetscErrorCode   ierr;
92b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL   *aijsell = (Mat_SeqAIJSELL*) A->spptr;
93a2a1850bSRichard Tran Mills   PetscObjectState state;
94b0e5de86SRichard Tran Mills 
95b0e5de86SRichard Tran Mills   PetscFunctionBegin;
96b0e5de86SRichard Tran Mills 
97a2a1850bSRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&state);CHKERRQ(ierr);
98a2a1850bSRichard Tran Mills   if (aijsell->S && aijsell->state == state) {
99a2a1850bSRichard Tran Mills     /* The existing shadow matrix is up-to-date, so simply exit. */
100a2a1850bSRichard Tran Mills     PetscFunctionReturn(0);
101a2a1850bSRichard Tran Mills   }
102a2a1850bSRichard Tran Mills 
103b0e5de86SRichard Tran Mills   if (aijsell->S) {
104b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_REUSE_MATRIX,&aijsell->S);CHKERRQ(ierr);
105b0e5de86SRichard Tran Mills   } else {
106b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_INITIAL_MATRIX,&aijsell->S);CHKERRQ(ierr);
107b0e5de86SRichard Tran Mills   }
108b0e5de86SRichard Tran Mills 
109b0e5de86SRichard Tran Mills   /* Record the ObjectState so that we can tell when the shadow matrix needs updating */
110b0e5de86SRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&aijsell->state);CHKERRQ(ierr);
111b0e5de86SRichard Tran Mills 
112b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
113b0e5de86SRichard Tran Mills }
114b0e5de86SRichard Tran Mills 
1154dfdc2d9SRichard Tran Mills PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M)
1164dfdc2d9SRichard Tran Mills {
1174dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
1184dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1194dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell_dest;
1204dfdc2d9SRichard Tran Mills 
1214dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1224dfdc2d9SRichard Tran Mills   ierr = MatDuplicate_SeqAIJ(A,op,M);CHKERRQ(ierr);
1234dfdc2d9SRichard Tran Mills   aijsell      = (Mat_SeqAIJSELL*) A->spptr;
1244dfdc2d9SRichard Tran Mills   aijsell_dest = (Mat_SeqAIJSELL*) (*M)->spptr;
1254dfdc2d9SRichard Tran Mills   ierr = PetscMemcpy(aijsell_dest,aijsell,sizeof(Mat_SeqAIJSELL));CHKERRQ(ierr);
1264dfdc2d9SRichard Tran Mills   /* We don't duplicate the shadow matrix -- that will be constructed as needed. */
1274dfdc2d9SRichard Tran Mills   aijsell_dest->S = NULL;
12863663694SRichard Tran Mills   if (aijsell->eager_shadow) {
12963663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
13063663694SRichard Tran Mills   }
1314dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1324dfdc2d9SRichard Tran Mills }
1334dfdc2d9SRichard Tran Mills 
1344dfdc2d9SRichard Tran Mills PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode)
1354dfdc2d9SRichard Tran Mills {
1364dfdc2d9SRichard Tran Mills   PetscErrorCode  ierr;
1374dfdc2d9SRichard Tran Mills   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
1384dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell;
1394dfdc2d9SRichard Tran Mills 
1404dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1414dfdc2d9SRichard Tran Mills   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
1424dfdc2d9SRichard Tran Mills 
1434dfdc2d9SRichard Tran Mills   /* I disable the use of the inode routines so that the AIJSELL ones will be
1444dfdc2d9SRichard Tran Mills    * used instead, but I wonder if it might make sense (and is feasible) to
1454dfdc2d9SRichard Tran Mills    * use some of them. */
1464dfdc2d9SRichard Tran Mills   a->inode.use = PETSC_FALSE;
1474dfdc2d9SRichard Tran Mills 
1484dfdc2d9SRichard Tran Mills   /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some
1494dfdc2d9SRichard Tran Mills    * extra information and some different methods, call the AssemblyEnd
1504dfdc2d9SRichard Tran Mills    * routine for a MATSEQAIJ.
1514dfdc2d9SRichard Tran Mills    * I'm not sure if this is the best way to do this, but it avoids
1524dfdc2d9SRichard Tran Mills    * a lot of code duplication. */
1534dfdc2d9SRichard Tran Mills 
1544dfdc2d9SRichard Tran Mills   ierr = MatAssemblyEnd_SeqAIJ(A, mode);CHKERRQ(ierr);
1554dfdc2d9SRichard Tran Mills 
1564dfdc2d9SRichard Tran Mills   /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks).
1574dfdc2d9SRichard Tran Mills    * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */
1584dfdc2d9SRichard Tran Mills   aijsell = (Mat_SeqAIJSELL*) A->spptr;
1594dfdc2d9SRichard Tran Mills   if (aijsell->eager_shadow) {
16063663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1614dfdc2d9SRichard Tran Mills   }
1624dfdc2d9SRichard Tran Mills 
1634dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1644dfdc2d9SRichard Tran Mills }
1654dfdc2d9SRichard Tran Mills 
166b0e5de86SRichard Tran Mills PetscErrorCode MatMult_SeqAIJSELL(Mat A,Vec xx,Vec yy)
167b0e5de86SRichard Tran Mills {
168b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
169b0e5de86SRichard Tran Mills   PetscErrorCode    ierr;
170b0e5de86SRichard Tran Mills 
171b0e5de86SRichard Tran Mills   PetscFunctionBegin;
172b0e5de86SRichard Tran Mills 
173b0e5de86SRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1749d769819SRichard Tran Mills   ierr = MatMult_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr);
175b0e5de86SRichard Tran Mills 
176b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
177b0e5de86SRichard Tran Mills }
178b0e5de86SRichard Tran Mills 
1794da9d7bdSRichard Tran Mills PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A,Vec xx,Vec yy)
1804da9d7bdSRichard Tran Mills {
1814da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
1824da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
1834da9d7bdSRichard Tran Mills 
1844da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1854da9d7bdSRichard Tran Mills 
1864da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1874da9d7bdSRichard Tran Mills   ierr = MatMultTranspose_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr);
1884da9d7bdSRichard Tran Mills 
1894da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
1904da9d7bdSRichard Tran Mills }
1914da9d7bdSRichard Tran Mills 
1924da9d7bdSRichard Tran Mills PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz)
1934da9d7bdSRichard Tran Mills {
1944da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
1954da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
1964da9d7bdSRichard Tran Mills 
1974da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1984da9d7bdSRichard Tran Mills 
1994da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2004da9d7bdSRichard Tran Mills   ierr = MatMultAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr);
2014da9d7bdSRichard Tran Mills 
2024da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
2034da9d7bdSRichard Tran Mills }
2044da9d7bdSRichard Tran Mills 
2054da9d7bdSRichard Tran Mills PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz)
2064da9d7bdSRichard Tran Mills {
2074da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
2084da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
2094da9d7bdSRichard Tran Mills 
2104da9d7bdSRichard Tran Mills   PetscFunctionBegin;
2114da9d7bdSRichard Tran Mills 
2124da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2134da9d7bdSRichard Tran Mills   ierr = MatMultTransposeAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr);
2144da9d7bdSRichard Tran Mills 
2154da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
2164da9d7bdSRichard Tran Mills }
2174da9d7bdSRichard Tran Mills 
218*84920f4bSRichard Tran Mills /* This function prototype is needed in MatConvert_SeqAIJ_SeqAIJSELL(), below. */
219*84920f4bSRichard Tran Mills PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*);
220*84920f4bSRichard Tran Mills 
2214dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a
2224dfdc2d9SRichard Tran Mills  * SeqAIJSELL matrix.  This routine is called by the MatCreate_SeqAIJSELL()
2234dfdc2d9SRichard Tran Mills  * routine, but can also be used to convert an assembled SeqAIJ matrix
2244dfdc2d9SRichard Tran Mills  * into a SeqAIJSELL one. */
2254dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A,MatType type,MatReuse reuse,Mat *newmat)
2264dfdc2d9SRichard Tran Mills {
2274dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
2284dfdc2d9SRichard Tran Mills   Mat            B = *newmat;
2294dfdc2d9SRichard Tran Mills   Mat_SeqAIJ     *b;
2304dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
2314dfdc2d9SRichard Tran Mills   PetscBool      set;
2324dfdc2d9SRichard Tran Mills   PetscBool      sametype;
2334dfdc2d9SRichard Tran Mills 
2344dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2354dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) {
2364dfdc2d9SRichard Tran Mills     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
2374dfdc2d9SRichard Tran Mills   }
2384dfdc2d9SRichard Tran Mills 
2394dfdc2d9SRichard Tran Mills   ierr = PetscObjectTypeCompare((PetscObject)A,type,&sametype);CHKERRQ(ierr);
2404dfdc2d9SRichard Tran Mills   if (sametype) PetscFunctionReturn(0);
2414dfdc2d9SRichard Tran Mills 
2424dfdc2d9SRichard Tran Mills   ierr     = PetscNewLog(B,&aijsell);CHKERRQ(ierr);
2434dfdc2d9SRichard Tran Mills   b        = (Mat_SeqAIJ*) B->data;
2444dfdc2d9SRichard Tran Mills   B->spptr = (void*) aijsell;
2454dfdc2d9SRichard Tran Mills 
2464dfdc2d9SRichard Tran Mills   /* Disable use of the inode routines so that the AIJSELL ones will be used instead.
2474dfdc2d9SRichard Tran Mills    * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too.
2484dfdc2d9SRichard Tran Mills    * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */
2494dfdc2d9SRichard Tran Mills   b->inode.use = PETSC_FALSE;
2504dfdc2d9SRichard Tran Mills 
2514dfdc2d9SRichard Tran Mills   /* Set function pointers for methods that we inherit from AIJ but override.
2524dfdc2d9SRichard Tran Mills    * We also parse some command line options below, since those determine some of the methods we point to. */
2534dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJSELL;
2544dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJSELL;
2554dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJSELL;
2564dfdc2d9SRichard Tran Mills 
2574dfdc2d9SRichard Tran Mills   aijsell->S = NULL;
2584dfdc2d9SRichard Tran Mills   aijsell->eager_shadow = PETSC_FALSE;
2594dfdc2d9SRichard Tran Mills 
2604dfdc2d9SRichard Tran Mills   /* Parse command line options. */
2614dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"AIJSELL Options","Mat");CHKERRQ(ierr);
2624dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBool("-mat_aijsell_eager_shadow","Eager Shadowing","None",(PetscBool)aijsell->eager_shadow,(PetscBool*)&aijsell->eager_shadow,&set);CHKERRQ(ierr);
2634dfdc2d9SRichard Tran Mills   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2644dfdc2d9SRichard Tran Mills 
2654dfdc2d9SRichard Tran Mills   /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */
26663663694SRichard Tran Mills   if (A->assembled && aijsell->eager_shadow) {
26763663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2684dfdc2d9SRichard Tran Mills   }
2694dfdc2d9SRichard Tran Mills 
270b0e5de86SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJSELL;
271b0e5de86SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJSELL;
272b0e5de86SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJSELL;
273b0e5de86SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL;
2744dfdc2d9SRichard Tran Mills 
2754dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",MatConvert_SeqAIJSELL_SeqAIJ);CHKERRQ(ierr);
2764dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
2774dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
2784dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
279*84920f4bSRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr);
2804dfdc2d9SRichard Tran Mills 
2814dfdc2d9SRichard Tran Mills   ierr    = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJSELL);CHKERRQ(ierr);
2824dfdc2d9SRichard Tran Mills   *newmat = B;
2834dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
2844dfdc2d9SRichard Tran Mills }
2854dfdc2d9SRichard Tran Mills 
2864dfdc2d9SRichard Tran Mills /*@C
2874dfdc2d9SRichard Tran Mills    MatCreateSeqAIJSELL - Creates a sparse matrix of type SEQAIJSELL.
2884dfdc2d9SRichard Tran Mills    This type inherits from AIJ and is largely identical, but keeps a "shadow"
2894dfdc2d9SRichard Tran Mills    copy of the matrix in SEQSELL format, which is used when performing
2904dfdc2d9SRichard Tran Mills    operations for which this format is more suitable.
2914dfdc2d9SRichard Tran Mills 
2924dfdc2d9SRichard Tran Mills    Collective on MPI_Comm
2934dfdc2d9SRichard Tran Mills 
2944dfdc2d9SRichard Tran Mills    Input Parameters:
2954dfdc2d9SRichard Tran Mills +  comm - MPI communicator, set to PETSC_COMM_SELF
2964dfdc2d9SRichard Tran Mills .  m - number of rows
2974dfdc2d9SRichard Tran Mills .  n - number of columns
2984dfdc2d9SRichard Tran Mills .  nz - number of nonzeros per row (same for all rows)
2994dfdc2d9SRichard Tran Mills -  nnz - array containing the number of nonzeros in the various rows
3004dfdc2d9SRichard Tran Mills          (possibly different for each row) or NULL
3014dfdc2d9SRichard Tran Mills 
3024dfdc2d9SRichard Tran Mills    Output Parameter:
3034dfdc2d9SRichard Tran Mills .  A - the matrix
3044dfdc2d9SRichard Tran Mills 
3054dfdc2d9SRichard Tran Mills    Options Database Keys:
3064dfdc2d9SRichard 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
3074dfdc2d9SRichard Tran Mills 
3084dfdc2d9SRichard Tran Mills    Notes:
3094dfdc2d9SRichard Tran Mills    If nnz is given then nz is ignored
3104dfdc2d9SRichard Tran Mills 
3114dfdc2d9SRichard Tran Mills    Level: intermediate
3124dfdc2d9SRichard Tran Mills 
3134dfdc2d9SRichard Tran Mills .keywords: matrix, sparse, parallel
3144dfdc2d9SRichard Tran Mills 
3154dfdc2d9SRichard Tran Mills .seealso: MatCreate(), MatCreateMPIAIJSELL(), MatSetValues()
3164dfdc2d9SRichard Tran Mills @*/
3174dfdc2d9SRichard Tran Mills PetscErrorCode  MatCreateSeqAIJSELL(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
3184dfdc2d9SRichard Tran Mills {
3194dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
3204dfdc2d9SRichard Tran Mills 
3214dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
3224dfdc2d9SRichard Tran Mills   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3234dfdc2d9SRichard Tran Mills   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3244dfdc2d9SRichard Tran Mills   ierr = MatSetType(*A,MATSEQAIJSELL);CHKERRQ(ierr);
3254dfdc2d9SRichard Tran Mills   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3264dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
3274dfdc2d9SRichard Tran Mills }
3284dfdc2d9SRichard Tran Mills 
3294dfdc2d9SRichard Tran Mills PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A)
3304dfdc2d9SRichard Tran Mills {
3314dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
3324dfdc2d9SRichard Tran Mills 
3334dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
3344dfdc2d9SRichard Tran Mills   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
3354dfdc2d9SRichard Tran Mills   ierr = MatConvert_SeqAIJ_SeqAIJSELL(A,MATSEQAIJSELL,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
3364dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
3374dfdc2d9SRichard Tran Mills }
338