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; 38af22a668SRichard Tran Mills B->ops->sor = MatSOR_SeqAIJ; 394dfdc2d9SRichard Tran Mills 404dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",NULL);CHKERRQ(ierr); 414dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr); 424dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr); 434dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",NULL);CHKERRQ(ierr); 4484920f4bSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",NULL);CHKERRQ(ierr); 454dfdc2d9SRichard Tran Mills 464dfdc2d9SRichard Tran Mills if (reuse == MAT_INITIAL_MATRIX) aijsell = (Mat_SeqAIJSELL*)B->spptr; 474dfdc2d9SRichard Tran Mills 48*8cde19baSRichard Tran Mills /* Clean up the Mat_SeqAIJSELL data structure. 49*8cde19baSRichard 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. */ 504dfdc2d9SRichard Tran Mills ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr); 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 ierr = MatDestroy(&aijsell->S);CHKERRQ(ierr); 724dfdc2d9SRichard Tran Mills ierr = PetscFree(A->spptr);CHKERRQ(ierr); 734dfdc2d9SRichard Tran Mills } 744dfdc2d9SRichard Tran Mills 754dfdc2d9SRichard Tran Mills /* Change the type of A back to SEQAIJ and use MatDestroy_SeqAIJ() 764dfdc2d9SRichard Tran Mills * to destroy everything that remains. */ 774dfdc2d9SRichard Tran Mills ierr = PetscObjectChangeTypeName((PetscObject)A, MATSEQAIJ);CHKERRQ(ierr); 784dfdc2d9SRichard Tran Mills /* Note that I don't call MatSetType(). I believe this is because that 794dfdc2d9SRichard Tran Mills * is only to be called when *building* a matrix. I could be wrong, but 804dfdc2d9SRichard Tran Mills * that is how things work for the SuperLU matrix class. */ 814dfdc2d9SRichard Tran Mills ierr = MatDestroy_SeqAIJ(A);CHKERRQ(ierr); 824dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 834dfdc2d9SRichard Tran Mills } 844dfdc2d9SRichard Tran Mills 85a2a1850bSRichard Tran Mills /* Build or update the shadow matrix if and only if needed. 86a2a1850bSRichard Tran Mills * We track the ObjectState to determine when this needs to be done. */ 87b0e5de86SRichard Tran Mills PETSC_INTERN PetscErrorCode MatSeqAIJSELL_build_shadow(Mat A) 88b0e5de86SRichard Tran Mills { 89b0e5de86SRichard Tran Mills PetscErrorCode ierr; 90b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL*) A->spptr; 91a2a1850bSRichard Tran Mills PetscObjectState state; 92b0e5de86SRichard Tran Mills 93b0e5de86SRichard Tran Mills PetscFunctionBegin; 94a2a1850bSRichard Tran Mills ierr = PetscObjectStateGet((PetscObject)A,&state);CHKERRQ(ierr); 95a2a1850bSRichard Tran Mills if (aijsell->S && aijsell->state == state) { 96a2a1850bSRichard Tran Mills /* The existing shadow matrix is up-to-date, so simply exit. */ 97a2a1850bSRichard Tran Mills PetscFunctionReturn(0); 98a2a1850bSRichard Tran Mills } 99a2a1850bSRichard Tran Mills 100597d2e73SRichard Tran Mills ierr = PetscLogEventBegin(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 101b0e5de86SRichard Tran Mills if (aijsell->S) { 102b0e5de86SRichard Tran Mills ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_REUSE_MATRIX,&aijsell->S);CHKERRQ(ierr); 103b0e5de86SRichard Tran Mills } else { 104b0e5de86SRichard Tran Mills ierr = MatConvert_SeqAIJ_SeqSELL(A,MATSEQSELL,MAT_INITIAL_MATRIX,&aijsell->S);CHKERRQ(ierr); 105b0e5de86SRichard Tran Mills } 106597d2e73SRichard Tran Mills ierr = PetscLogEventEnd(MAT_Convert,A,0,0,0);CHKERRQ(ierr); 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; 12763663694SRichard Tran Mills if (aijsell->eager_shadow) { 12863663694SRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 12963663694SRichard Tran Mills } 1304dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 1314dfdc2d9SRichard Tran Mills } 1324dfdc2d9SRichard Tran Mills 1334dfdc2d9SRichard Tran Mills PetscErrorCode MatAssemblyEnd_SeqAIJSELL(Mat A, MatAssemblyType mode) 1344dfdc2d9SRichard Tran Mills { 1354dfdc2d9SRichard Tran Mills PetscErrorCode ierr; 1364dfdc2d9SRichard Tran Mills Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 137*8cde19baSRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL*)A->spptr; 1384dfdc2d9SRichard Tran Mills 1394dfdc2d9SRichard Tran Mills PetscFunctionBegin; 1404dfdc2d9SRichard Tran Mills if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1414dfdc2d9SRichard Tran Mills 1424dfdc2d9SRichard Tran Mills /* I disable the use of the inode routines so that the AIJSELL ones will be 1434dfdc2d9SRichard Tran Mills * used instead, but I wonder if it might make sense (and is feasible) to 1444dfdc2d9SRichard Tran Mills * use some of them. */ 1454dfdc2d9SRichard Tran Mills a->inode.use = PETSC_FALSE; 1464dfdc2d9SRichard Tran Mills 1474dfdc2d9SRichard Tran Mills /* Since a MATSEQAIJSELL matrix is really just a MATSEQAIJ with some 1484dfdc2d9SRichard Tran Mills * extra information and some different methods, call the AssemblyEnd 1494dfdc2d9SRichard Tran Mills * routine for a MATSEQAIJ. 1504dfdc2d9SRichard Tran Mills * I'm not sure if this is the best way to do this, but it avoids 1514dfdc2d9SRichard Tran Mills * a lot of code duplication. */ 1524dfdc2d9SRichard Tran Mills 1534dfdc2d9SRichard Tran Mills ierr = MatAssemblyEnd_SeqAIJ(A, mode);CHKERRQ(ierr); 1544dfdc2d9SRichard Tran Mills 1554dfdc2d9SRichard Tran Mills /* If the user has requested "eager" shadowing, create the SELL shadow matrix (if needed; the function checks). 1564dfdc2d9SRichard Tran Mills * (The default is to take a "lazy" approach, deferring this until something like MatMult() is called.) */ 1574dfdc2d9SRichard Tran Mills if (aijsell->eager_shadow) { 15863663694SRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 1594dfdc2d9SRichard Tran Mills } 1604dfdc2d9SRichard Tran Mills 1614dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 1624dfdc2d9SRichard Tran Mills } 1634dfdc2d9SRichard Tran Mills 164b0e5de86SRichard Tran Mills PetscErrorCode MatMult_SeqAIJSELL(Mat A,Vec xx,Vec yy) 165b0e5de86SRichard Tran Mills { 166b0e5de86SRichard Tran Mills Mat_SeqAIJSELL *aijsell = (Mat_SeqAIJSELL*)A->spptr; 167b0e5de86SRichard Tran Mills PetscErrorCode ierr; 168b0e5de86SRichard Tran Mills 169b0e5de86SRichard Tran Mills PetscFunctionBegin; 170b0e5de86SRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 1719d769819SRichard Tran Mills ierr = MatMult_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr); 172b0e5de86SRichard Tran Mills PetscFunctionReturn(0); 173b0e5de86SRichard Tran Mills } 174b0e5de86SRichard Tran Mills 1754da9d7bdSRichard Tran Mills PetscErrorCode MatMultTranspose_SeqAIJSELL(Mat A,Vec xx,Vec yy) 1764da9d7bdSRichard Tran Mills { 1774da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell=(Mat_SeqAIJSELL*)A->spptr; 1784da9d7bdSRichard Tran Mills PetscErrorCode ierr; 1794da9d7bdSRichard Tran Mills 1804da9d7bdSRichard Tran Mills PetscFunctionBegin; 1814da9d7bdSRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 1824da9d7bdSRichard Tran Mills ierr = MatMultTranspose_SeqSELL(aijsell->S,xx,yy);CHKERRQ(ierr); 1834da9d7bdSRichard Tran Mills PetscFunctionReturn(0); 1844da9d7bdSRichard Tran Mills } 1854da9d7bdSRichard Tran Mills 1864da9d7bdSRichard Tran Mills PetscErrorCode MatMultAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz) 1874da9d7bdSRichard Tran Mills { 1884da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell=(Mat_SeqAIJSELL*)A->spptr; 1894da9d7bdSRichard Tran Mills PetscErrorCode ierr; 1904da9d7bdSRichard Tran Mills 1914da9d7bdSRichard Tran Mills PetscFunctionBegin; 1924da9d7bdSRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 1934da9d7bdSRichard Tran Mills ierr = MatMultAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr); 1944da9d7bdSRichard Tran Mills PetscFunctionReturn(0); 1954da9d7bdSRichard Tran Mills } 1964da9d7bdSRichard Tran Mills 1974da9d7bdSRichard Tran Mills PetscErrorCode MatMultTransposeAdd_SeqAIJSELL(Mat A,Vec xx,Vec yy,Vec zz) 1984da9d7bdSRichard Tran Mills { 1994da9d7bdSRichard Tran Mills Mat_SeqAIJSELL *aijsell=(Mat_SeqAIJSELL*)A->spptr; 2004da9d7bdSRichard Tran Mills PetscErrorCode ierr; 2014da9d7bdSRichard Tran Mills 2024da9d7bdSRichard Tran Mills PetscFunctionBegin; 2034da9d7bdSRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 2044da9d7bdSRichard Tran Mills ierr = MatMultTransposeAdd_SeqSELL(aijsell->S,xx,yy,zz);CHKERRQ(ierr); 2054da9d7bdSRichard Tran Mills PetscFunctionReturn(0); 2064da9d7bdSRichard Tran Mills } 2074da9d7bdSRichard Tran Mills 208af22a668SRichard Tran Mills PetscErrorCode MatSOR_SeqAIJSELL(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 209af22a668SRichard Tran Mills { 210af22a668SRichard Tran Mills Mat_SeqAIJSELL *aijsell=(Mat_SeqAIJSELL*)A->spptr; 211af22a668SRichard Tran Mills PetscErrorCode ierr; 212af22a668SRichard Tran Mills 213af22a668SRichard Tran Mills PetscFunctionBegin; 214af22a668SRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 215af22a668SRichard Tran Mills ierr = MatSOR_SeqSELL(aijsell->S,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 216af22a668SRichard Tran Mills PetscFunctionReturn(0); 217af22a668SRichard Tran Mills } 218af22a668SRichard Tran Mills 21984920f4bSRichard Tran Mills /* This function prototype is needed in MatConvert_SeqAIJ_SeqAIJSELL(), below. */ 22084920f4bSRichard Tran Mills PETSC_INTERN PetscErrorCode MatPtAP_IS_XAIJ(Mat,Mat,MatReuse,PetscReal,Mat*); 22184920f4bSRichard Tran Mills 2224dfdc2d9SRichard Tran Mills /* MatConvert_SeqAIJ_SeqAIJSELL converts a SeqAIJ matrix into a 2234dfdc2d9SRichard Tran Mills * SeqAIJSELL matrix. This routine is called by the MatCreate_SeqAIJSELL() 2244dfdc2d9SRichard Tran Mills * routine, but can also be used to convert an assembled SeqAIJ matrix 2254dfdc2d9SRichard Tran Mills * into a SeqAIJSELL one. */ 2264dfdc2d9SRichard Tran Mills PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJSELL(Mat A,MatType type,MatReuse reuse,Mat *newmat) 2274dfdc2d9SRichard Tran Mills { 2284dfdc2d9SRichard Tran Mills PetscErrorCode ierr; 2294dfdc2d9SRichard Tran Mills Mat B = *newmat; 2304dfdc2d9SRichard Tran Mills Mat_SeqAIJ *b; 2314dfdc2d9SRichard Tran Mills Mat_SeqAIJSELL *aijsell; 2324dfdc2d9SRichard Tran Mills PetscBool set; 2334dfdc2d9SRichard Tran Mills PetscBool sametype; 2344dfdc2d9SRichard Tran Mills 2354dfdc2d9SRichard Tran Mills PetscFunctionBegin; 2364dfdc2d9SRichard Tran Mills if (reuse == MAT_INITIAL_MATRIX) { 2374dfdc2d9SRichard Tran Mills ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 2384dfdc2d9SRichard Tran Mills } 2394dfdc2d9SRichard Tran Mills 2404dfdc2d9SRichard Tran Mills ierr = PetscObjectTypeCompare((PetscObject)A,type,&sametype);CHKERRQ(ierr); 2414dfdc2d9SRichard Tran Mills if (sametype) PetscFunctionReturn(0); 2424dfdc2d9SRichard Tran Mills 2434dfdc2d9SRichard Tran Mills ierr = PetscNewLog(B,&aijsell);CHKERRQ(ierr); 2444dfdc2d9SRichard Tran Mills b = (Mat_SeqAIJ*) B->data; 2454dfdc2d9SRichard Tran Mills B->spptr = (void*) aijsell; 2464dfdc2d9SRichard Tran Mills 2474dfdc2d9SRichard Tran Mills /* Disable use of the inode routines so that the AIJSELL ones will be used instead. 2484dfdc2d9SRichard Tran Mills * This happens in MatAssemblyEnd_SeqAIJSELL as well, but the assembly end may not be called, so set it here, too. 2494dfdc2d9SRichard Tran Mills * As noted elsewhere, I wonder if it might make sense and be feasible to use some of the inode routines. */ 2504dfdc2d9SRichard Tran Mills b->inode.use = PETSC_FALSE; 2514dfdc2d9SRichard Tran Mills 2524dfdc2d9SRichard Tran Mills /* Set function pointers for methods that we inherit from AIJ but override. 2534dfdc2d9SRichard Tran Mills * We also parse some command line options below, since those determine some of the methods we point to. */ 2544dfdc2d9SRichard Tran Mills B->ops->duplicate = MatDuplicate_SeqAIJSELL; 2554dfdc2d9SRichard Tran Mills B->ops->assemblyend = MatAssemblyEnd_SeqAIJSELL; 2564dfdc2d9SRichard Tran Mills B->ops->destroy = MatDestroy_SeqAIJSELL; 2574dfdc2d9SRichard Tran Mills 2584dfdc2d9SRichard Tran Mills aijsell->S = NULL; 2594dfdc2d9SRichard Tran Mills aijsell->eager_shadow = PETSC_FALSE; 2604dfdc2d9SRichard Tran Mills 2614dfdc2d9SRichard Tran Mills /* Parse command line options. */ 2624dfdc2d9SRichard Tran Mills ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"AIJSELL Options","Mat");CHKERRQ(ierr); 2634dfdc2d9SRichard Tran Mills ierr = PetscOptionsBool("-mat_aijsell_eager_shadow","Eager Shadowing","None",(PetscBool)aijsell->eager_shadow,(PetscBool*)&aijsell->eager_shadow,&set);CHKERRQ(ierr); 2644dfdc2d9SRichard Tran Mills ierr = PetscOptionsEnd();CHKERRQ(ierr); 2654dfdc2d9SRichard Tran Mills 2664dfdc2d9SRichard Tran Mills /* If A has already been assembled and eager shadowing is specified, build the shadow matrix. */ 26763663694SRichard Tran Mills if (A->assembled && aijsell->eager_shadow) { 26863663694SRichard Tran Mills ierr = MatSeqAIJSELL_build_shadow(A);CHKERRQ(ierr); 2694dfdc2d9SRichard Tran Mills } 2704dfdc2d9SRichard Tran Mills 271b0e5de86SRichard Tran Mills B->ops->mult = MatMult_SeqAIJSELL; 272b0e5de86SRichard Tran Mills B->ops->multtranspose = MatMultTranspose_SeqAIJSELL; 273b0e5de86SRichard Tran Mills B->ops->multadd = MatMultAdd_SeqAIJSELL; 274b0e5de86SRichard Tran Mills B->ops->multtransposeadd = MatMultTransposeAdd_SeqAIJSELL; 275af22a668SRichard Tran Mills B->ops->sor = MatSOR_SeqAIJSELL; 2764dfdc2d9SRichard Tran Mills 2774dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijsell_seqaij_C",MatConvert_SeqAIJSELL_SeqAIJ);CHKERRQ(ierr); 2784dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaijsell_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 2794dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaijsell_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 2804dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaijsell_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 28184920f4bSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_is_seqaijsell_C",MatPtAP_IS_XAIJ);CHKERRQ(ierr); 2824dfdc2d9SRichard Tran Mills 2834dfdc2d9SRichard Tran Mills ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJSELL);CHKERRQ(ierr); 2844dfdc2d9SRichard Tran Mills *newmat = B; 2854dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 2864dfdc2d9SRichard Tran Mills } 2874dfdc2d9SRichard Tran Mills 2884dfdc2d9SRichard Tran Mills /*@C 2894dfdc2d9SRichard Tran Mills MatCreateSeqAIJSELL - Creates a sparse matrix of type SEQAIJSELL. 2904dfdc2d9SRichard Tran Mills This type inherits from AIJ and is largely identical, but keeps a "shadow" 2918197ac24SRichard Tran Mills copy of the matrix in SEQSELL format, which is used when this format 2928197ac24SRichard Tran Mills may be more suitable for a requested operation. Currently, SEQSELL format 2938197ac24SRichard Tran Mills is used for MatMult, MatMultTranspose, MatMultAdd, MatMultTransposeAdd, 2948197ac24SRichard Tran Mills and MatSOR operations. 295ca9cdca7SRichard Tran Mills Because SEQAIJSELL is a subtype of SEQAIJ, the option "-mat_seqaij_type seqaijsell" can be used to make 296ca9cdca7SRichard Tran Mills sequential AIJ matrices default to being instances of MATSEQAIJSELL. 2974dfdc2d9SRichard Tran Mills 2984dfdc2d9SRichard Tran Mills Collective on MPI_Comm 2994dfdc2d9SRichard Tran Mills 3004dfdc2d9SRichard Tran Mills Input Parameters: 3014dfdc2d9SRichard Tran Mills + comm - MPI communicator, set to PETSC_COMM_SELF 3024dfdc2d9SRichard Tran Mills . m - number of rows 3034dfdc2d9SRichard Tran Mills . n - number of columns 3044dfdc2d9SRichard Tran Mills . nz - number of nonzeros per row (same for all rows) 3054dfdc2d9SRichard Tran Mills - nnz - array containing the number of nonzeros in the various rows 3064dfdc2d9SRichard Tran Mills (possibly different for each row) or NULL 3074dfdc2d9SRichard Tran Mills 3084dfdc2d9SRichard Tran Mills Output Parameter: 3094dfdc2d9SRichard Tran Mills . A - the matrix 3104dfdc2d9SRichard Tran Mills 3114dfdc2d9SRichard Tran Mills Options Database Keys: 3124dfdc2d9SRichard 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 3134dfdc2d9SRichard Tran Mills 3144dfdc2d9SRichard Tran Mills Notes: 3154dfdc2d9SRichard Tran Mills If nnz is given then nz is ignored 3164dfdc2d9SRichard Tran Mills 3174dfdc2d9SRichard Tran Mills Level: intermediate 3184dfdc2d9SRichard Tran Mills 319ca9cdca7SRichard Tran Mills .keywords: matrix, sparse 3204dfdc2d9SRichard Tran Mills 3214dfdc2d9SRichard Tran Mills .seealso: MatCreate(), MatCreateMPIAIJSELL(), MatSetValues() 3224dfdc2d9SRichard Tran Mills @*/ 3234dfdc2d9SRichard Tran Mills PetscErrorCode MatCreateSeqAIJSELL(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 3244dfdc2d9SRichard Tran Mills { 3254dfdc2d9SRichard Tran Mills PetscErrorCode ierr; 3264dfdc2d9SRichard Tran Mills 3274dfdc2d9SRichard Tran Mills PetscFunctionBegin; 3284dfdc2d9SRichard Tran Mills ierr = MatCreate(comm,A);CHKERRQ(ierr); 3294dfdc2d9SRichard Tran Mills ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3304dfdc2d9SRichard Tran Mills ierr = MatSetType(*A,MATSEQAIJSELL);CHKERRQ(ierr); 3314dfdc2d9SRichard Tran Mills ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3324dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 3334dfdc2d9SRichard Tran Mills } 3344dfdc2d9SRichard Tran Mills 3354dfdc2d9SRichard Tran Mills PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJSELL(Mat A) 3364dfdc2d9SRichard Tran Mills { 3374dfdc2d9SRichard Tran Mills PetscErrorCode ierr; 3384dfdc2d9SRichard Tran Mills 3394dfdc2d9SRichard Tran Mills PetscFunctionBegin; 3404dfdc2d9SRichard Tran Mills ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr); 3414dfdc2d9SRichard Tran Mills ierr = MatConvert_SeqAIJ_SeqAIJSELL(A,MATSEQAIJSELL,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 3424dfdc2d9SRichard Tran Mills PetscFunctionReturn(0); 3434dfdc2d9SRichard Tran Mills } 344