xref: /petsc/src/mat/impls/aij/seq/aijsell/aijsell.c (revision 8197ac2484d58342c7734cb037687452116844c8)
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 
11597d2e73SRichard Tran Mills /* Logging support */
12597d2e73SRichard Tran Mills PetscLogEvent MAT_Convert;
13597d2e73SRichard Tran Mills 
144dfdc2d9SRichard Tran Mills typedef struct {
154dfdc2d9SRichard Tran Mills   Mat S; /* The SELL formatted "shadow" matrix. */
164dfdc2d9SRichard Tran Mills   PetscBool eager_shadow;
174dfdc2d9SRichard Tran Mills   PetscObjectState state; /* State of the matrix when shadow matrix was last constructed. */
184dfdc2d9SRichard Tran Mills } Mat_SeqAIJSELL;
194dfdc2d9SRichard Tran Mills 
204dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJSELL_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat)
214dfdc2d9SRichard Tran Mills {
224dfdc2d9SRichard Tran Mills   /* This routine is only called to convert a MATAIJSELL to its base PETSc type, */
234dfdc2d9SRichard Tran Mills   /* so we will ignore 'MatType type'. */
244dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
254dfdc2d9SRichard Tran Mills   Mat            B        = *newmat;
264dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL*) A->spptr;
274dfdc2d9SRichard Tran Mills 
284dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
294dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) {
304dfdc2d9SRichard Tran Mills     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
314dfdc2d9SRichard Tran Mills   }
324dfdc2d9SRichard Tran Mills 
334dfdc2d9SRichard Tran Mills   /* Reset the original function pointers. */
344dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJ;
354dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJ;
364dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJ;
374dfdc2d9SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJ;
384dfdc2d9SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJ;
394dfdc2d9SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJ;
404dfdc2d9SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJ;
41af22a668SRichard Tran Mills   B->ops->sor              = MatSOR_SeqAIJ;
424dfdc2d9SRichard Tran Mills 
434dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",NULL);CHKERRQ(ierr);
444dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
454dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
464dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr);
4784920f4bSRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",NULL);CHKERRQ(ierr);
484dfdc2d9SRichard Tran Mills 
494dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL*)B->spptr;
504dfdc2d9SRichard Tran Mills 
514dfdc2d9SRichard Tran Mills   /* Clean up the Mat_SeqAIJSELL data structure. */
524dfdc2d9SRichard Tran Mills   if(aijsell->S) {
534dfdc2d9SRichard Tran Mills     ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
544dfdc2d9SRichard Tran Mills   }
554dfdc2d9SRichard Tran Mills   ierr = PetscFree(B->spptr);CHKERRQ(ierr);
564dfdc2d9SRichard Tran Mills 
574dfdc2d9SRichard Tran Mills   /* Change the type of B to MATSEQAIJ. */
584dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ);CHKERRQ(ierr);
594dfdc2d9SRichard Tran Mills 
604dfdc2d9SRichard Tran Mills   *newmat = B;
614dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
624dfdc2d9SRichard Tran Mills }
634dfdc2d9SRichard Tran Mills 
644dfdc2d9SRichard Tran Mills PetscErrorCode MatDestroy_SeqAIJSELL(Mat A)
654dfdc2d9SRichard Tran Mills {
664dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
674dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell = (Mat_SeqAIJSELL*) A->spptr;
684dfdc2d9SRichard Tran Mills 
694dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
704dfdc2d9SRichard Tran Mills 
714dfdc2d9SRichard Tran Mills   /* If MatHeaderMerge() was used, then this SeqAIJSELL matrix will not have an
724dfdc2d9SRichard Tran Mills    * spptr pointer. */
734dfdc2d9SRichard Tran Mills   if (aijsell) {
744dfdc2d9SRichard Tran Mills     /* Clean up everything in the Mat_SeqAIJSELL data structure, then free A->spptr. */
754dfdc2d9SRichard Tran Mills     if (aijsell->S) {
764dfdc2d9SRichard Tran Mills       ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr);
774dfdc2d9SRichard Tran Mills     }
784dfdc2d9SRichard Tran Mills     ierr = PetscFree(A->spptr);CHKERRQ(ierr);
794dfdc2d9SRichard Tran Mills   }
804dfdc2d9SRichard Tran Mills 
814dfdc2d9SRichard Tran Mills   /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ()
824dfdc2d9SRichard Tran Mills    * to destroy everything that remains. */
834dfdc2d9SRichard Tran Mills   ierr = PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ);CHKERRQ(ierr);
844dfdc2d9SRichard Tran Mills   /* Note that I don't call MatSetType().  I believe this is because that
854dfdc2d9SRichard Tran Mills    * is only to be called when *building* a matrix.  I could be wrong, but
864dfdc2d9SRichard Tran Mills    * that is how things work for the SuperLU matrix class. */
874dfdc2d9SRichard Tran Mills   ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr);
884dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
894dfdc2d9SRichard Tran Mills }
904dfdc2d9SRichard Tran Mills 
91a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed.
92a2a1850bSRichard Tran Mills  * We track the ObjectState to determine when this needs to be done. */
93b0e5de86SRichard Tran Mills PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A)
94b0e5de86SRichard Tran Mills {
95b0e5de86SRichard Tran Mills   PetscErrorCode   ierr;
96b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL   *aijsell = (Mat_SeqAIJSELL*) A->spptr;
97a2a1850bSRichard Tran Mills   PetscObjectState state;
98b0e5de86SRichard Tran Mills 
99b0e5de86SRichard Tran Mills   PetscFunctionBegin;
100b0e5de86SRichard Tran Mills 
101a2a1850bSRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&state);CHKERRQ(ierr);
102a2a1850bSRichard Tran Mills   if (aijsell->S && aijsell->state == state) {
103a2a1850bSRichard Tran Mills     /* The existing shadow matrix is up-to-date, so simply exit. */
104a2a1850bSRichard Tran Mills     PetscFunctionReturn(0);
105a2a1850bSRichard Tran Mills   }
106a2a1850bSRichard Tran Mills 
107597d2e73SRichard Tran Mills   ierr = PetscLogEventBegin(MAT_Convert,A,0,0,0);CHKERRQ(ierr);
108b0e5de86SRichard Tran Mills   if (aijsell->S) {
109b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_REUSE_MATRIX,&aijsell->S);CHKERRQ(ierr);
110b0e5de86SRichard Tran Mills   } else {
111b0e5de86SRichard Tran Mills     ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_INITIAL_MATRIX,&aijsell->S);CHKERRQ(ierr);
112b0e5de86SRichard Tran Mills   }
113597d2e73SRichard Tran Mills   ierr = PetscLogEventEnd(MAT_Convert,A,0,0,0);CHKERRQ(ierr);
114b0e5de86SRichard Tran Mills 
115b0e5de86SRichard Tran Mills   /* Record the ObjectState so that we can tell when the shadow matrix needs updating */
116b0e5de86SRichard Tran Mills   ierr = PetscObjectStateGet((PetscObject)A,&aijsell->state);CHKERRQ(ierr);
117b0e5de86SRichard Tran Mills 
118b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
119b0e5de86SRichard Tran Mills }
120b0e5de86SRichard Tran Mills 
1214dfdc2d9SRichard Tran Mills PetscErrorCode MatDuplicate_SeqAIJSELL(Mat A, MatDuplicateOption op, Mat *M)
1224dfdc2d9SRichard Tran Mills {
1234dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
1244dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
1254dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell_dest;
1264dfdc2d9SRichard Tran Mills 
1274dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1284dfdc2d9SRichard Tran Mills   ierr = MatDuplicate_SeqAIJ(A,op,M);CHKERRQ(ierr);
1294dfdc2d9SRichard Tran Mills   aijsell      = (Mat_SeqAIJSELL*) A->spptr;
1304dfdc2d9SRichard Tran Mills   aijsell_dest = (Mat_SeqAIJSELL*) (*M)->spptr;
1314dfdc2d9SRichard Tran Mills   ierr = PetscMemcpy(aijsell_dest,aijsell,sizeof(Mat_SeqAIJSELL));CHKERRQ(ierr);
1324dfdc2d9SRichard Tran Mills   /* We don't duplicate the shadow matrix -- that will be constructed as needed. */
1334dfdc2d9SRichard Tran Mills   aijsell_dest->S = NULL;
13463663694SRichard Tran Mills   if (aijsell->eager_shadow) {
13563663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
13663663694SRichard Tran Mills   }
1374dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1384dfdc2d9SRichard Tran Mills }
1394dfdc2d9SRichard Tran Mills 
1404dfdc2d9SRichard Tran Mills PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode)
1414dfdc2d9SRichard Tran Mills {
1424dfdc2d9SRichard Tran Mills   PetscErrorCode  ierr;
1434dfdc2d9SRichard Tran Mills   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
1444dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL  *aijsell;
1454dfdc2d9SRichard Tran Mills 
1464dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
1474dfdc2d9SRichard Tran Mills   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0);
1484dfdc2d9SRichard Tran Mills 
1494dfdc2d9SRichard Tran Mills   /* I disable the use of the inode routines so that the AIJSELL ones will be
1504dfdc2d9SRichard Tran Mills    * used instead, but I wonder if it might make sense (and is feasible) to
1514dfdc2d9SRichard Tran Mills    * use some of them. */
1524dfdc2d9SRichard Tran Mills   a->inode.use = PETSC_FALSE;
1534dfdc2d9SRichard Tran Mills 
1544dfdc2d9SRichard Tran Mills   /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some
1554dfdc2d9SRichard Tran Mills    * extra information and some different methods, call the AssemblyEnd
1564dfdc2d9SRichard Tran Mills    * routine for a MATSEQAIJ.
1574dfdc2d9SRichard Tran Mills    * I'm not sure if this is the best way to do this, but it avoids
1584dfdc2d9SRichard Tran Mills    * a lot of code duplication. */
1594dfdc2d9SRichard Tran Mills 
1604dfdc2d9SRichard Tran Mills   ierr = MatAssemblyEnd_SeqAIJ(A, mode);CHKERRQ(ierr);
1614dfdc2d9SRichard Tran Mills 
1624dfdc2d9SRichard Tran Mills   /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks).
1634dfdc2d9SRichard Tran Mills    * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */
1644dfdc2d9SRichard Tran Mills   aijsell = (Mat_SeqAIJSELL*) A->spptr;
1654dfdc2d9SRichard Tran Mills   if (aijsell->eager_shadow) {
16663663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1674dfdc2d9SRichard Tran Mills   }
1684dfdc2d9SRichard Tran Mills 
1694dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
1704dfdc2d9SRichard Tran Mills }
1714dfdc2d9SRichard Tran Mills 
172b0e5de86SRichard Tran Mills PetscErrorCode MatMult_SeqAIJSELL(Mat A,Vec xx,Vec yy)
173b0e5de86SRichard Tran Mills {
174b0e5de86SRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
175b0e5de86SRichard Tran Mills   PetscErrorCode    ierr;
176b0e5de86SRichard Tran Mills 
177b0e5de86SRichard Tran Mills   PetscFunctionBegin;
178b0e5de86SRichard Tran Mills 
179b0e5de86SRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1809d769819SRichard Tran Mills   ierr = MatMult_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr);
181b0e5de86SRichard Tran Mills 
182b0e5de86SRichard Tran Mills   PetscFunctionReturn(0);
183b0e5de86SRichard Tran Mills }
184b0e5de86SRichard Tran Mills 
1854da9d7bdSRichard Tran Mills PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A,Vec xx,Vec yy)
1864da9d7bdSRichard Tran Mills {
1874da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
1884da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
1894da9d7bdSRichard Tran Mills 
1904da9d7bdSRichard Tran Mills   PetscFunctionBegin;
1914da9d7bdSRichard Tran Mills 
1924da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
1934da9d7bdSRichard Tran Mills   ierr = MatMultTranspose_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr);
1944da9d7bdSRichard Tran Mills 
1954da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
1964da9d7bdSRichard Tran Mills }
1974da9d7bdSRichard Tran Mills 
1984da9d7bdSRichard Tran Mills PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz)
1994da9d7bdSRichard Tran Mills {
2004da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
2014da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
2024da9d7bdSRichard Tran Mills 
2034da9d7bdSRichard Tran Mills   PetscFunctionBegin;
2044da9d7bdSRichard Tran Mills 
2054da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2064da9d7bdSRichard Tran Mills   ierr = MatMultAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr);
2074da9d7bdSRichard Tran Mills 
2084da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
2094da9d7bdSRichard Tran Mills }
2104da9d7bdSRichard Tran Mills 
2114da9d7bdSRichard Tran Mills PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz)
2124da9d7bdSRichard Tran Mills {
2134da9d7bdSRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
2144da9d7bdSRichard Tran Mills   PetscErrorCode    ierr;
2154da9d7bdSRichard Tran Mills 
2164da9d7bdSRichard Tran Mills   PetscFunctionBegin;
2174da9d7bdSRichard Tran Mills 
2184da9d7bdSRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2194da9d7bdSRichard Tran Mills   ierr = MatMultTransposeAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr);
2204da9d7bdSRichard Tran Mills 
2214da9d7bdSRichard Tran Mills   PetscFunctionReturn(0);
2224da9d7bdSRichard Tran Mills }
2234da9d7bdSRichard Tran Mills 
224af22a668SRichard Tran Mills PetscErrorCode MatSOR_SeqAIJSELL(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx)
225af22a668SRichard Tran Mills {
226af22a668SRichard Tran Mills   Mat_SeqAIJSELL    *aijsell=(Mat_SeqAIJSELL*)A->spptr;
227af22a668SRichard Tran Mills   PetscErrorCode    ierr;
228af22a668SRichard Tran Mills 
229af22a668SRichard Tran Mills   PetscFunctionBegin;
230af22a668SRichard Tran Mills 
231af22a668SRichard Tran Mills   ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
232af22a668SRichard Tran Mills   ierr = MatSOR_SeqSELL(aijsell->S,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr);
233af22a668SRichard Tran Mills 
234af22a668SRichard Tran Mills   PetscFunctionReturn(0);
235af22a668SRichard Tran Mills }
236af22a668SRichard Tran Mills 
23784920f4bSRichard Tran Mills /* This function prototype is needed in MatConvert_SeqAIJ_SeqAIJSELL(), below. */
23884920f4bSRichard Tran Mills PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*);
23984920f4bSRichard Tran Mills 
2404dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a
2414dfdc2d9SRichard Tran Mills  * SeqAIJSELL matrix.  This routine is called by the MatCreate_SeqAIJSELL()
2424dfdc2d9SRichard Tran Mills  * routine, but can also be used to convert an assembled SeqAIJ matrix
2434dfdc2d9SRichard Tran Mills  * into a SeqAIJSELL one. */
2444dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A,MatType type,MatReuse reuse,Mat *newmat)
2454dfdc2d9SRichard Tran Mills {
2464dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
2474dfdc2d9SRichard Tran Mills   Mat            B = *newmat;
2484dfdc2d9SRichard Tran Mills   Mat_SeqAIJ     *b;
2494dfdc2d9SRichard Tran Mills   Mat_SeqAIJSELL *aijsell;
2504dfdc2d9SRichard Tran Mills   PetscBool      set;
2514dfdc2d9SRichard Tran Mills   PetscBool      sametype;
2524dfdc2d9SRichard Tran Mills 
2534dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
2544dfdc2d9SRichard Tran Mills   if (reuse == MAT_INITIAL_MATRIX) {
2554dfdc2d9SRichard Tran Mills     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
2564dfdc2d9SRichard Tran Mills   }
2574dfdc2d9SRichard Tran Mills 
2584dfdc2d9SRichard Tran Mills   ierr = PetscObjectTypeCompare((PetscObject)A,type,&sametype);CHKERRQ(ierr);
2594dfdc2d9SRichard Tran Mills   if (sametype) PetscFunctionReturn(0);
2604dfdc2d9SRichard Tran Mills 
2614dfdc2d9SRichard Tran Mills   ierr     = PetscNewLog(B,&aijsell);CHKERRQ(ierr);
2624dfdc2d9SRichard Tran Mills   b        = (Mat_SeqAIJ*) B->data;
2634dfdc2d9SRichard Tran Mills   B->spptr = (void*) aijsell;
2644dfdc2d9SRichard Tran Mills 
2654dfdc2d9SRichard Tran Mills   /* Disable use of the inode routines so that the AIJSELL ones will be used instead.
2664dfdc2d9SRichard Tran Mills    * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too.
2674dfdc2d9SRichard Tran Mills    * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */
2684dfdc2d9SRichard Tran Mills   b->inode.use = PETSC_FALSE;
2694dfdc2d9SRichard Tran Mills 
2704dfdc2d9SRichard Tran Mills   /* Set function pointers for methods that we inherit from AIJ but override.
2714dfdc2d9SRichard Tran Mills    * We also parse some command line options below, since those determine some of the methods we point to. */
2724dfdc2d9SRichard Tran Mills   B->ops->duplicate        = MatDuplicate_SeqAIJSELL;
2734dfdc2d9SRichard Tran Mills   B->ops->assemblyend      = MatAssemblyEnd_SeqAIJSELL;
2744dfdc2d9SRichard Tran Mills   B->ops->destroy          = MatDestroy_SeqAIJSELL;
2754dfdc2d9SRichard Tran Mills 
2764dfdc2d9SRichard Tran Mills   aijsell->S = NULL;
2774dfdc2d9SRichard Tran Mills   aijsell->eager_shadow = PETSC_FALSE;
2784dfdc2d9SRichard Tran Mills 
2794dfdc2d9SRichard Tran Mills   /* Parse command line options. */
2804dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"AIJSELL Options","Mat");CHKERRQ(ierr);
2814dfdc2d9SRichard Tran Mills   ierr = PetscOptionsBool("-mat_aijsell_eager_shadow","Eager Shadowing","None",(PetscBool)aijsell->eager_shadow,(PetscBool*)&aijsell->eager_shadow,&set);CHKERRQ(ierr);
2824dfdc2d9SRichard Tran Mills   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2834dfdc2d9SRichard Tran Mills 
2844dfdc2d9SRichard Tran Mills   /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */
28563663694SRichard Tran Mills   if (A->assembled && aijsell->eager_shadow) {
28663663694SRichard Tran Mills     ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr);
2874dfdc2d9SRichard Tran Mills   }
2884dfdc2d9SRichard Tran Mills 
289b0e5de86SRichard Tran Mills   B->ops->mult             = MatMult_SeqAIJSELL;
290b0e5de86SRichard Tran Mills   B->ops->multtranspose    = MatMultTranspose_SeqAIJSELL;
291b0e5de86SRichard Tran Mills   B->ops->multadd          = MatMultAdd_SeqAIJSELL;
292b0e5de86SRichard Tran Mills   B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL;
293af22a668SRichard Tran Mills   B->ops->sor              = MatSOR_SeqAIJSELL;
2944dfdc2d9SRichard Tran Mills 
2954dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",MatConvert_SeqAIJSELL_SeqAIJ);CHKERRQ(ierr);
2964dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr);
2974dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr);
2984dfdc2d9SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr);
29984920f4bSRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr);
3004dfdc2d9SRichard Tran Mills 
3014dfdc2d9SRichard Tran Mills   ierr    = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJSELL);CHKERRQ(ierr);
3024dfdc2d9SRichard Tran Mills   *newmat = B;
3034dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
3044dfdc2d9SRichard Tran Mills }
3054dfdc2d9SRichard Tran Mills 
3064dfdc2d9SRichard Tran Mills /*@C
3074dfdc2d9SRichard Tran Mills    MatCreateSeqAIJSELL - Creates a sparse matrix of type SEQAIJSELL.
3084dfdc2d9SRichard Tran Mills    This type inherits from AIJ and is largely identical, but keeps a "shadow"
309*8197ac24SRichard Tran Mills    copy of the matrix in SEQSELL format, which is used when this format
310*8197ac24SRichard Tran Mills    may be more suitable for a requested operation. Currently, SEQSELL format
311*8197ac24SRichard Tran Mills    is used for MatMult, MatMultTranspose, MatMultAdd, MatMultTransposeAdd,
312*8197ac24SRichard Tran Mills    and MatSOR operations.
3134dfdc2d9SRichard Tran Mills 
3144dfdc2d9SRichard Tran Mills    Collective on MPI_Comm
3154dfdc2d9SRichard Tran Mills 
3164dfdc2d9SRichard Tran Mills    Input Parameters:
3174dfdc2d9SRichard Tran Mills +  comm - MPI communicator, set to PETSC_COMM_SELF
3184dfdc2d9SRichard Tran Mills .  m - number of rows
3194dfdc2d9SRichard Tran Mills .  n - number of columns
3204dfdc2d9SRichard Tran Mills .  nz - number of nonzeros per row (same for all rows)
3214dfdc2d9SRichard Tran Mills -  nnz - array containing the number of nonzeros in the various rows
3224dfdc2d9SRichard Tran Mills          (possibly different for each row) or NULL
3234dfdc2d9SRichard Tran Mills 
3244dfdc2d9SRichard Tran Mills    Output Parameter:
3254dfdc2d9SRichard Tran Mills .  A - the matrix
3264dfdc2d9SRichard Tran Mills 
3274dfdc2d9SRichard Tran Mills    Options Database Keys:
3284dfdc2d9SRichard 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
3294dfdc2d9SRichard Tran Mills 
3304dfdc2d9SRichard Tran Mills    Notes:
3314dfdc2d9SRichard Tran Mills    If nnz is given then nz is ignored
3324dfdc2d9SRichard Tran Mills 
3334dfdc2d9SRichard Tran Mills    Level: intermediate
3344dfdc2d9SRichard Tran Mills 
3354dfdc2d9SRichard Tran Mills .keywords: matrix, sparse, parallel
3364dfdc2d9SRichard Tran Mills 
3374dfdc2d9SRichard Tran Mills .seealso: MatCreate(), MatCreateMPIAIJSELL(), MatSetValues()
3384dfdc2d9SRichard Tran Mills @*/
3394dfdc2d9SRichard Tran Mills PetscErrorCode  MatCreateSeqAIJSELL(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A)
3404dfdc2d9SRichard Tran Mills {
3414dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
3424dfdc2d9SRichard Tran Mills 
3434dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
3444dfdc2d9SRichard Tran Mills   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3454dfdc2d9SRichard Tran Mills   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3464dfdc2d9SRichard Tran Mills   ierr = MatSetType(*A,MATSEQAIJSELL);CHKERRQ(ierr);
3474dfdc2d9SRichard Tran Mills   ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr);
3484dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
3494dfdc2d9SRichard Tran Mills }
3504dfdc2d9SRichard Tran Mills 
3514dfdc2d9SRichard Tran Mills PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A)
3524dfdc2d9SRichard Tran Mills {
3534dfdc2d9SRichard Tran Mills   PetscErrorCode ierr;
3544dfdc2d9SRichard Tran Mills 
3554dfdc2d9SRichard Tran Mills   PetscFunctionBegin;
3564dfdc2d9SRichard Tran Mills   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
3574dfdc2d9SRichard Tran Mills   ierr = MatConvert_SeqAIJ_SeqAIJSELL(A,MATSEQAIJSELL,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
3584dfdc2d9SRichard Tran Mills   PetscFunctionReturn(0);
3594dfdc2d9SRichard Tran Mills }
360