1793850ffSBarry Smith #define PETSCMAT_DLL 2793850ffSBarry Smith 3*7c4f633dSBarry Smith #include "private/matimpl.h" /*I "petscmat.h" I*/ 4793850ffSBarry Smith 5793850ffSBarry Smith typedef struct _Mat_CompositeLink *Mat_CompositeLink; 6793850ffSBarry Smith struct _Mat_CompositeLink { 7793850ffSBarry Smith Mat mat; 86d7c1e57SBarry Smith Vec work; 96d7c1e57SBarry Smith Mat_CompositeLink next,prev; 10793850ffSBarry Smith }; 11793850ffSBarry Smith 12793850ffSBarry Smith typedef struct { 136d7c1e57SBarry Smith MatCompositeType type; 146d7c1e57SBarry Smith Mat_CompositeLink head,tail; 15793850ffSBarry Smith Vec work; 16793850ffSBarry Smith } Mat_Composite; 17793850ffSBarry Smith 18793850ffSBarry Smith #undef __FUNCT__ 19793850ffSBarry Smith #define __FUNCT__ "MatDestroy_Composite" 20793850ffSBarry Smith PetscErrorCode MatDestroy_Composite(Mat mat) 21793850ffSBarry Smith { 22793850ffSBarry Smith PetscErrorCode ierr; 232c33bbaeSSatish Balay Mat_Composite *shell = (Mat_Composite*)mat->data; 246d7c1e57SBarry Smith Mat_CompositeLink next = shell->head,oldnext; 25793850ffSBarry Smith 26793850ffSBarry Smith PetscFunctionBegin; 27793850ffSBarry Smith while (next) { 28793850ffSBarry Smith ierr = MatDestroy(next->mat);CHKERRQ(ierr); 296d7c1e57SBarry Smith if (next->work && (!next->next || next->work != next->next->work)) { 306d7c1e57SBarry Smith ierr = VecDestroy(next->work);CHKERRQ(ierr); 316d7c1e57SBarry Smith } 326d7c1e57SBarry Smith oldnext = next; 33793850ffSBarry Smith next = next->next; 346d7c1e57SBarry Smith ierr = PetscFree(oldnext);CHKERRQ(ierr); 35793850ffSBarry Smith } 36793850ffSBarry Smith if (shell->work) {ierr = VecDestroy(shell->work);CHKERRQ(ierr);} 37793850ffSBarry Smith ierr = PetscFree(shell);CHKERRQ(ierr); 38793850ffSBarry Smith mat->data = 0; 39793850ffSBarry Smith PetscFunctionReturn(0); 40793850ffSBarry Smith } 41793850ffSBarry Smith 42793850ffSBarry Smith #undef __FUNCT__ 436d7c1e57SBarry Smith #define __FUNCT__ "MatMult_Composite_Multiplicative" 446d7c1e57SBarry Smith PetscErrorCode MatMult_Composite_Multiplicative(Mat A,Vec x,Vec y) 456d7c1e57SBarry Smith { 466d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 476d7c1e57SBarry Smith Mat_CompositeLink next = shell->head; 486d7c1e57SBarry Smith PetscErrorCode ierr; 496d7c1e57SBarry Smith Vec in,out; 506d7c1e57SBarry Smith 516d7c1e57SBarry Smith PetscFunctionBegin; 526d7c1e57SBarry Smith if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 536d7c1e57SBarry Smith in = x; 546d7c1e57SBarry Smith while (next->next) { 556d7c1e57SBarry Smith if (!next->work) { /* should reuse previous work if the same size */ 566d7c1e57SBarry Smith ierr = MatGetVecs(next->mat,PETSC_NULL,&next->work);CHKERRQ(ierr); 576d7c1e57SBarry Smith } 586d7c1e57SBarry Smith out = next->work; 596d7c1e57SBarry Smith ierr = MatMult(next->mat,in,out);CHKERRQ(ierr); 606d7c1e57SBarry Smith in = out; 616d7c1e57SBarry Smith next = next->next; 626d7c1e57SBarry Smith } 636d7c1e57SBarry Smith ierr = MatMult(next->mat,in,y);CHKERRQ(ierr); 646d7c1e57SBarry Smith PetscFunctionReturn(0); 656d7c1e57SBarry Smith } 666d7c1e57SBarry Smith 676d7c1e57SBarry Smith #undef __FUNCT__ 686d7c1e57SBarry Smith #define __FUNCT__ "MatMultTranspose_Composite_Multiplicative" 696d7c1e57SBarry Smith PetscErrorCode MatMultTranspose_Composite_Multiplicative(Mat A,Vec x,Vec y) 706d7c1e57SBarry Smith { 716d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 726d7c1e57SBarry Smith Mat_CompositeLink tail = shell->tail; 736d7c1e57SBarry Smith PetscErrorCode ierr; 746d7c1e57SBarry Smith Vec in,out; 756d7c1e57SBarry Smith 766d7c1e57SBarry Smith PetscFunctionBegin; 776d7c1e57SBarry Smith if (!tail) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 786d7c1e57SBarry Smith in = x; 796d7c1e57SBarry Smith while (tail->prev) { 806d7c1e57SBarry Smith if (!tail->prev->work) { /* should reuse previous work if the same size */ 816d7c1e57SBarry Smith ierr = MatGetVecs(tail->mat,PETSC_NULL,&tail->prev->work);CHKERRQ(ierr); 826d7c1e57SBarry Smith } 836d7c1e57SBarry Smith out = tail->prev->work; 846d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,out);CHKERRQ(ierr); 856d7c1e57SBarry Smith in = out; 866d7c1e57SBarry Smith tail = tail->prev; 876d7c1e57SBarry Smith } 886d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,y);CHKERRQ(ierr); 896d7c1e57SBarry Smith PetscFunctionReturn(0); 906d7c1e57SBarry Smith } 916d7c1e57SBarry Smith 926d7c1e57SBarry Smith #undef __FUNCT__ 93793850ffSBarry Smith #define __FUNCT__ "MatMult_Composite" 94793850ffSBarry Smith PetscErrorCode MatMult_Composite(Mat A,Vec x,Vec y) 95793850ffSBarry Smith { 96793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 97793850ffSBarry Smith Mat_CompositeLink next = shell->head; 98793850ffSBarry Smith PetscErrorCode ierr; 99793850ffSBarry Smith 100793850ffSBarry Smith PetscFunctionBegin; 101793850ffSBarry Smith if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 102793850ffSBarry Smith ierr = MatMult(next->mat,x,y);CHKERRQ(ierr); 103793850ffSBarry Smith while ((next = next->next)) { 104793850ffSBarry Smith ierr = MatMultAdd(next->mat,x,y,y);CHKERRQ(ierr); 105793850ffSBarry Smith } 106793850ffSBarry Smith PetscFunctionReturn(0); 107793850ffSBarry Smith } 108793850ffSBarry Smith 109793850ffSBarry Smith #undef __FUNCT__ 110793850ffSBarry Smith #define __FUNCT__ "MatMultTranspose_Composite" 111793850ffSBarry Smith PetscErrorCode MatMultTranspose_Composite(Mat A,Vec x,Vec y) 112793850ffSBarry Smith { 113793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 114793850ffSBarry Smith Mat_CompositeLink next = shell->head; 115793850ffSBarry Smith PetscErrorCode ierr; 116793850ffSBarry Smith 117793850ffSBarry Smith PetscFunctionBegin; 118793850ffSBarry Smith if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 119793850ffSBarry Smith ierr = MatMultTranspose(next->mat,x,y);CHKERRQ(ierr); 120793850ffSBarry Smith while ((next = next->next)) { 121793850ffSBarry Smith ierr = MatMultTransposeAdd(next->mat,x,y,y);CHKERRQ(ierr); 122793850ffSBarry Smith } 123793850ffSBarry Smith PetscFunctionReturn(0); 124793850ffSBarry Smith } 125793850ffSBarry Smith 126793850ffSBarry Smith #undef __FUNCT__ 127793850ffSBarry Smith #define __FUNCT__ "MatGetDiagonal_Composite" 128793850ffSBarry Smith PetscErrorCode MatGetDiagonal_Composite(Mat A,Vec v) 129793850ffSBarry Smith { 130793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 131793850ffSBarry Smith Mat_CompositeLink next = shell->head; 132793850ffSBarry Smith PetscErrorCode ierr; 133793850ffSBarry Smith 134793850ffSBarry Smith PetscFunctionBegin; 135793850ffSBarry Smith if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 136793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,v);CHKERRQ(ierr); 137793850ffSBarry Smith if (next->next && !shell->work) { 138793850ffSBarry Smith ierr = VecDuplicate(v,&shell->work);CHKERRQ(ierr); 139793850ffSBarry Smith } 140793850ffSBarry Smith while ((next = next->next)) { 141793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,shell->work);CHKERRQ(ierr); 142793850ffSBarry Smith ierr = VecAXPY(v,1.0,shell->work);CHKERRQ(ierr); 143793850ffSBarry Smith } 144793850ffSBarry Smith PetscFunctionReturn(0); 145793850ffSBarry Smith } 146793850ffSBarry Smith 147793850ffSBarry Smith #undef __FUNCT__ 148793850ffSBarry Smith #define __FUNCT__ "MatAssemblyEnd_Composite" 149793850ffSBarry Smith PetscErrorCode MatAssemblyEnd_Composite(Mat Y,MatAssemblyType t) 150793850ffSBarry Smith { 151b52f573bSBarry Smith PetscErrorCode ierr; 152b52f573bSBarry Smith PetscTruth flg; 153b52f573bSBarry Smith 154793850ffSBarry Smith PetscFunctionBegin; 1557adad957SLisandro Dalcin ierr = PetscOptionsHasName(((PetscObject)Y)->prefix,"-mat_composite_merge",&flg);CHKERRQ(ierr); 156b52f573bSBarry Smith if (flg) { 157b52f573bSBarry Smith ierr = MatCompositeMerge(Y);CHKERRQ(ierr); 158b52f573bSBarry Smith } 159793850ffSBarry Smith PetscFunctionReturn(0); 160793850ffSBarry Smith } 161793850ffSBarry Smith 162793850ffSBarry Smith 163793850ffSBarry Smith static struct _MatOps MatOps_Values = {0, 164793850ffSBarry Smith 0, 165793850ffSBarry Smith 0, 166793850ffSBarry Smith MatMult_Composite, 167793850ffSBarry Smith 0, 168793850ffSBarry Smith /* 5*/ MatMultTranspose_Composite, 169793850ffSBarry Smith 0, 170793850ffSBarry Smith 0, 171793850ffSBarry Smith 0, 172793850ffSBarry Smith 0, 173793850ffSBarry Smith /*10*/ 0, 174793850ffSBarry Smith 0, 175793850ffSBarry Smith 0, 176793850ffSBarry Smith 0, 177793850ffSBarry Smith 0, 178793850ffSBarry Smith /*15*/ 0, 179793850ffSBarry Smith 0, 180793850ffSBarry Smith MatGetDiagonal_Composite, 181793850ffSBarry Smith 0, 182793850ffSBarry Smith 0, 183793850ffSBarry Smith /*20*/ 0, 184793850ffSBarry Smith MatAssemblyEnd_Composite, 185793850ffSBarry Smith 0, 186793850ffSBarry Smith 0, 187793850ffSBarry Smith 0, 188793850ffSBarry Smith /*25*/ 0, 189793850ffSBarry Smith 0, 190793850ffSBarry Smith 0, 191793850ffSBarry Smith 0, 192793850ffSBarry Smith 0, 193793850ffSBarry Smith /*30*/ 0, 194793850ffSBarry Smith 0, 195793850ffSBarry Smith 0, 196793850ffSBarry Smith 0, 197793850ffSBarry Smith 0, 198793850ffSBarry Smith /*35*/ 0, 199793850ffSBarry Smith 0, 200793850ffSBarry Smith 0, 201793850ffSBarry Smith 0, 202793850ffSBarry Smith 0, 203793850ffSBarry Smith /*40*/ 0, 204793850ffSBarry Smith 0, 205793850ffSBarry Smith 0, 206793850ffSBarry Smith 0, 207793850ffSBarry Smith 0, 208793850ffSBarry Smith /*45*/ 0, 209793850ffSBarry Smith 0, 210793850ffSBarry Smith 0, 211793850ffSBarry Smith 0, 212793850ffSBarry Smith 0, 213793850ffSBarry Smith /*50*/ 0, 214793850ffSBarry Smith 0, 215793850ffSBarry Smith 0, 216793850ffSBarry Smith 0, 217793850ffSBarry Smith 0, 218793850ffSBarry Smith /*55*/ 0, 219793850ffSBarry Smith 0, 220793850ffSBarry Smith 0, 221793850ffSBarry Smith 0, 222793850ffSBarry Smith 0, 223793850ffSBarry Smith /*60*/ 0, 224793850ffSBarry Smith MatDestroy_Composite, 225793850ffSBarry Smith 0, 226793850ffSBarry Smith 0, 227793850ffSBarry Smith 0, 228793850ffSBarry Smith /*65*/ 0, 229793850ffSBarry Smith 0, 230793850ffSBarry Smith 0, 231793850ffSBarry Smith 0, 232793850ffSBarry Smith 0, 233793850ffSBarry Smith /*70*/ 0, 234793850ffSBarry Smith 0, 235793850ffSBarry Smith 0, 236793850ffSBarry Smith 0, 237793850ffSBarry Smith 0, 238793850ffSBarry Smith /*75*/ 0, 239793850ffSBarry Smith 0, 240793850ffSBarry Smith 0, 241793850ffSBarry Smith 0, 242793850ffSBarry Smith 0, 243793850ffSBarry Smith /*80*/ 0, 244793850ffSBarry Smith 0, 245793850ffSBarry Smith 0, 246793850ffSBarry Smith 0, 247793850ffSBarry Smith 0, 248793850ffSBarry Smith /*85*/ 0, 249793850ffSBarry Smith 0, 250793850ffSBarry Smith 0, 251793850ffSBarry Smith 0, 252793850ffSBarry Smith 0, 253793850ffSBarry Smith /*90*/ 0, 254793850ffSBarry Smith 0, 255793850ffSBarry Smith 0, 256793850ffSBarry Smith 0, 257793850ffSBarry Smith 0, 258793850ffSBarry Smith /*95*/ 0, 259793850ffSBarry Smith 0, 260793850ffSBarry Smith 0, 261793850ffSBarry Smith 0}; 262793850ffSBarry Smith 263793850ffSBarry Smith /*MC 2646d7c1e57SBarry Smith MATCOMPOSITE - A matrix defined by the sum (or product) of one or more matrices (all matrices are of same size and parallel layout). 2656d7c1e57SBarry Smith 2666d7c1e57SBarry Smith Notes: to use the product of the matrices call MatCompositeSetType(mat,MAT_COMPOSITE_MULTIPLICATIVE); 267793850ffSBarry Smith 268793850ffSBarry Smith Level: advanced 269793850ffSBarry Smith 2706d7c1e57SBarry Smith .seealso: MatCreateComposite(), MatCompositeAddMat(), MatSetType(), MatCompositeMerge(), MatCompositeSetType(), MatCompositeType 271793850ffSBarry Smith M*/ 272793850ffSBarry Smith 273793850ffSBarry Smith EXTERN_C_BEGIN 274793850ffSBarry Smith #undef __FUNCT__ 275793850ffSBarry Smith #define __FUNCT__ "MatCreate_Composite" 276793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Composite(Mat A) 277793850ffSBarry Smith { 278793850ffSBarry Smith Mat_Composite *b; 279793850ffSBarry Smith PetscErrorCode ierr; 280793850ffSBarry Smith 281793850ffSBarry Smith PetscFunctionBegin; 28238f2d2fdSLisandro Dalcin ierr = PetscNewLog(A,Mat_Composite,&b);CHKERRQ(ierr); 283793850ffSBarry Smith A->data = (void*)b; 28438f2d2fdSLisandro Dalcin ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 285793850ffSBarry Smith 286d0f46423SBarry Smith ierr = PetscMapSetBlockSize(A->rmap,1);CHKERRQ(ierr); 287d0f46423SBarry Smith ierr = PetscMapSetBlockSize(A->cmap,1);CHKERRQ(ierr); 288d0f46423SBarry Smith ierr = PetscMapSetUp(A->rmap);CHKERRQ(ierr); 289d0f46423SBarry Smith ierr = PetscMapSetUp(A->cmap);CHKERRQ(ierr); 290793850ffSBarry Smith 291793850ffSBarry Smith A->assembled = PETSC_TRUE; 292793850ffSBarry Smith A->preallocated = PETSC_FALSE; 2936d7c1e57SBarry Smith b->type = MAT_COMPOSITE_ADDITIVE; 294793850ffSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr); 295793850ffSBarry Smith PetscFunctionReturn(0); 296793850ffSBarry Smith } 297793850ffSBarry Smith EXTERN_C_END 298793850ffSBarry Smith 299793850ffSBarry Smith #undef __FUNCT__ 300793850ffSBarry Smith #define __FUNCT__ "MatCreateComposite" 301793850ffSBarry Smith /*@C 302793850ffSBarry Smith MatCreateComposite - Creates a matrix as the sum of zero or more matrices 303793850ffSBarry Smith 304793850ffSBarry Smith Collective on MPI_Comm 305793850ffSBarry Smith 306793850ffSBarry Smith Input Parameters: 307793850ffSBarry Smith + comm - MPI communicator 308793850ffSBarry Smith . nmat - number of matrices to put in 309793850ffSBarry Smith - mats - the matrices 310793850ffSBarry Smith 311793850ffSBarry Smith Output Parameter: 312793850ffSBarry Smith . A - the matrix 313793850ffSBarry Smith 314793850ffSBarry Smith Level: advanced 315793850ffSBarry Smith 316793850ffSBarry Smith Notes: 317793850ffSBarry Smith Alternative construction 318793850ffSBarry Smith $ MatCreate(comm,&mat); 319793850ffSBarry Smith $ MatSetSizes(mat,m,n,M,N); 320793850ffSBarry Smith $ MatSetType(mat,MATCOMPOSITE); 321793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[0]); 322793850ffSBarry Smith $ .... 323793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[nmat-1]); 324b52f573bSBarry Smith $ MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); 325b52f573bSBarry Smith $ MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); 326793850ffSBarry Smith 3276d7c1e57SBarry Smith For the multiplicative form the product is mat[nmat-1]*mat[nmat-2]*....*mat[0] 3286d7c1e57SBarry Smith 3296d7c1e57SBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCompositeMerge(), MatCompositeSetType(), MatCompositeType 330793850ffSBarry Smith 331793850ffSBarry Smith @*/ 332793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreateComposite(MPI_Comm comm,PetscInt nmat,const Mat *mats,Mat *mat) 333793850ffSBarry Smith { 334793850ffSBarry Smith PetscErrorCode ierr; 335793850ffSBarry Smith PetscInt m,n,M,N,i; 336793850ffSBarry Smith 337793850ffSBarry Smith PetscFunctionBegin; 338793850ffSBarry Smith if (nmat < 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Must pass in at least one matrix"); 339f3f84630SBarry Smith PetscValidPointer(mat,3); 340793850ffSBarry Smith 341793850ffSBarry Smith ierr = MatGetLocalSize(mats[0],&m,&n);CHKERRQ(ierr); 342793850ffSBarry Smith ierr = MatGetSize(mats[0],&M,&N);CHKERRQ(ierr); 343793850ffSBarry Smith ierr = MatCreate(comm,mat);CHKERRQ(ierr); 344793850ffSBarry Smith ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); 345793850ffSBarry Smith ierr = MatSetType(*mat,MATCOMPOSITE);CHKERRQ(ierr); 346793850ffSBarry Smith for (i=0; i<nmat; i++) { 347793850ffSBarry Smith ierr = MatCompositeAddMat(*mat,mats[i]);CHKERRQ(ierr); 348793850ffSBarry Smith } 349b52f573bSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 350b52f573bSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 351793850ffSBarry Smith PetscFunctionReturn(0); 352793850ffSBarry Smith } 353793850ffSBarry Smith 354793850ffSBarry Smith #undef __FUNCT__ 355793850ffSBarry Smith #define __FUNCT__ "MatCompositeAddMat" 356793850ffSBarry Smith /*@ 357793850ffSBarry Smith MatCompositeAddMat - add another matrix to a composite matrix 358793850ffSBarry Smith 359793850ffSBarry Smith Collective on Mat 360793850ffSBarry Smith 361793850ffSBarry Smith Input Parameters: 362793850ffSBarry Smith + mat - the composite matrix 363793850ffSBarry Smith - smat - the partial matrix 364793850ffSBarry Smith 365793850ffSBarry Smith Level: advanced 366793850ffSBarry Smith 367793850ffSBarry Smith .seealso: MatCreateComposite() 368793850ffSBarry Smith @*/ 369793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCompositeAddMat(Mat mat,Mat smat) 370793850ffSBarry Smith { 37138f2d2fdSLisandro Dalcin Mat_Composite *shell; 372793850ffSBarry Smith PetscErrorCode ierr; 373793850ffSBarry Smith Mat_CompositeLink ilink,next; 374793850ffSBarry Smith 375793850ffSBarry Smith PetscFunctionBegin; 376793850ffSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE,1); 377793850ffSBarry Smith PetscValidHeaderSpecific(smat,MAT_COOKIE,2); 37838f2d2fdSLisandro Dalcin ierr = PetscNewLog(mat,struct _Mat_CompositeLink,&ilink);CHKERRQ(ierr); 379793850ffSBarry Smith ilink->next = 0; 380793850ffSBarry Smith ierr = PetscObjectReference((PetscObject)smat);CHKERRQ(ierr); 381c3122656SLisandro Dalcin ilink->mat = smat; 382793850ffSBarry Smith 38338f2d2fdSLisandro Dalcin shell = (Mat_Composite*)mat->data; 384793850ffSBarry Smith next = shell->head; 385793850ffSBarry Smith if (!next) { 386793850ffSBarry Smith shell->head = ilink; 387793850ffSBarry Smith } else { 388793850ffSBarry Smith while (next->next) { 389793850ffSBarry Smith next = next->next; 390793850ffSBarry Smith } 391793850ffSBarry Smith next->next = ilink; 3926d7c1e57SBarry Smith ilink->prev = next; 3936d7c1e57SBarry Smith } 3946d7c1e57SBarry Smith shell->tail = ilink; 3956d7c1e57SBarry Smith PetscFunctionReturn(0); 3966d7c1e57SBarry Smith } 3976d7c1e57SBarry Smith 3986d7c1e57SBarry Smith #undef __FUNCT__ 3996d7c1e57SBarry Smith #define __FUNCT__ "MatCompositeSetType" 4006d7c1e57SBarry Smith /*@C 4016d7c1e57SBarry Smith MatCompositeSetType - Indicates if the matrix is defined as the sum of a set of matrices or the product 4026d7c1e57SBarry Smith 4036d7c1e57SBarry Smith Collective on MPI_Comm 4046d7c1e57SBarry Smith 4056d7c1e57SBarry Smith Input Parameters: 4066d7c1e57SBarry Smith . mat - the composite matrix 4076d7c1e57SBarry Smith 4086d7c1e57SBarry Smith 4096d7c1e57SBarry Smith Level: advanced 4106d7c1e57SBarry Smith 4116d7c1e57SBarry Smith Notes: 4126d7c1e57SBarry Smith The MatType of the resulting matrix will be the same as the MatType of the FIRST 4136d7c1e57SBarry Smith matrix in the composite matrix. 4146d7c1e57SBarry Smith 4156d7c1e57SBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MATCOMPOSITE 4166d7c1e57SBarry Smith 4176d7c1e57SBarry Smith @*/ 4186d7c1e57SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCompositeSetType(Mat mat,MatCompositeType type) 4196d7c1e57SBarry Smith { 4206d7c1e57SBarry Smith Mat_Composite *b = (Mat_Composite*)mat->data; 4216d7c1e57SBarry Smith PetscTruth flg; 4226d7c1e57SBarry Smith PetscErrorCode ierr; 4236d7c1e57SBarry Smith 4246d7c1e57SBarry Smith PetscFunctionBegin; 4256d7c1e57SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATCOMPOSITE,&flg);CHKERRQ(ierr); 4266d7c1e57SBarry Smith if (!flg) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Can only use with composite matrix"); 4276d7c1e57SBarry Smith if (type == MAT_COMPOSITE_MULTIPLICATIVE) { 4286d7c1e57SBarry Smith mat->ops->getdiagonal = 0; 4296d7c1e57SBarry Smith mat->ops->mult = MatMult_Composite_Multiplicative; 4306d7c1e57SBarry Smith mat->ops->multtranspose = MatMultTranspose_Composite_Multiplicative; 4316d7c1e57SBarry Smith b->type = MAT_COMPOSITE_MULTIPLICATIVE; 4326d7c1e57SBarry Smith } else { 4336d7c1e57SBarry Smith mat->ops->getdiagonal = MatGetDiagonal_Composite; 4346d7c1e57SBarry Smith mat->ops->mult = MatMult_Composite; 4356d7c1e57SBarry Smith mat->ops->multtranspose = MatMultTranspose_Composite; 4366d7c1e57SBarry Smith b->type = MAT_COMPOSITE_ADDITIVE; 437793850ffSBarry Smith } 438793850ffSBarry Smith PetscFunctionReturn(0); 439793850ffSBarry Smith } 440793850ffSBarry Smith 4416d7c1e57SBarry Smith 442b52f573bSBarry Smith #undef __FUNCT__ 443b52f573bSBarry Smith #define __FUNCT__ "MatCompositeMerge" 444b52f573bSBarry Smith /*@C 445b52f573bSBarry Smith MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix 446b52f573bSBarry Smith by summing all the matrices inside the composite matrix. 447b52f573bSBarry Smith 448b52f573bSBarry Smith Collective on MPI_Comm 449b52f573bSBarry Smith 450b52f573bSBarry Smith Input Parameters: 451b52f573bSBarry Smith . mat - the composite matrix 452b52f573bSBarry Smith 453b52f573bSBarry Smith 454b52f573bSBarry Smith Options Database: 455b52f573bSBarry Smith . -mat_composite_merge (you must call MatAssemblyBegin()/MatAssemblyEnd() to have this checked) 456b52f573bSBarry Smith 457b52f573bSBarry Smith Level: advanced 458b52f573bSBarry Smith 459b52f573bSBarry Smith Notes: 460b52f573bSBarry Smith The MatType of the resulting matrix will be the same as the MatType of the FIRST 461b52f573bSBarry Smith matrix in the composite matrix. 462b52f573bSBarry Smith 463b52f573bSBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MATCOMPOSITE 464b52f573bSBarry Smith 465b52f573bSBarry Smith @*/ 466b52f573bSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCompositeMerge(Mat mat) 467b52f573bSBarry Smith { 468b52f573bSBarry Smith Mat_Composite *shell = (Mat_Composite*)mat->data; 4696d7c1e57SBarry Smith Mat_CompositeLink next = shell->head, prev = shell->tail; 470b52f573bSBarry Smith PetscErrorCode ierr; 4716d7c1e57SBarry Smith Mat tmat,newmat; 472b52f573bSBarry Smith 473b52f573bSBarry Smith PetscFunctionBegin; 474b52f573bSBarry Smith if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 475b52f573bSBarry Smith 476b52f573bSBarry Smith PetscFunctionBegin; 4776d7c1e57SBarry Smith if (shell->type == MAT_COMPOSITE_ADDITIVE) { 478b52f573bSBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 479b52f573bSBarry Smith while ((next = next->next)) { 480b52f573bSBarry Smith ierr = MatAXPY(tmat,1.0,next->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 481b52f573bSBarry Smith } 4826d7c1e57SBarry Smith } else { 4836d7c1e57SBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4846d7c1e57SBarry Smith while ((prev = prev->prev)) { 4856d7c1e57SBarry Smith ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 4866d7c1e57SBarry Smith ierr = MatDestroy(tmat);CHKERRQ(ierr); 4876d7c1e57SBarry Smith tmat = newmat; 4886d7c1e57SBarry Smith } 4896d7c1e57SBarry Smith } 4906d7c1e57SBarry Smith ierr = MatHeaderReplace(mat,tmat);CHKERRQ(ierr); 491b52f573bSBarry Smith PetscFunctionReturn(0); 492b52f573bSBarry Smith } 493