1793850ffSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3793850ffSBarry Smith 4793850ffSBarry Smith typedef struct _Mat_CompositeLink *Mat_CompositeLink; 5793850ffSBarry Smith struct _Mat_CompositeLink { 6793850ffSBarry Smith Mat mat; 76d7c1e57SBarry Smith Vec work; 86d7c1e57SBarry Smith Mat_CompositeLink next,prev; 9793850ffSBarry Smith }; 10793850ffSBarry Smith 11793850ffSBarry Smith typedef struct { 126d7c1e57SBarry Smith MatCompositeType type; 136d7c1e57SBarry Smith Mat_CompositeLink head,tail; 14793850ffSBarry Smith Vec work; 15e4fc5df0SBarry Smith PetscScalar scale; /* scale factor supplied with MatScale() */ 16e4fc5df0SBarry Smith Vec left,right; /* left and right diagonal scaling provided with MatDiagonalScale() */ 17e4fc5df0SBarry Smith Vec leftwork,rightwork; 186a7ede75SJakub Kruzik PetscInt nmat; 19*04d534ceSJakub Kruzik PetscBool mergefromright; 20793850ffSBarry Smith } Mat_Composite; 21793850ffSBarry Smith 22793850ffSBarry Smith PetscErrorCode MatDestroy_Composite(Mat mat) 23793850ffSBarry Smith { 24793850ffSBarry Smith PetscErrorCode ierr; 252c33bbaeSSatish Balay Mat_Composite *shell = (Mat_Composite*)mat->data; 266d7c1e57SBarry Smith Mat_CompositeLink next = shell->head,oldnext; 27793850ffSBarry Smith 28793850ffSBarry Smith PetscFunctionBegin; 29793850ffSBarry Smith while (next) { 306bf464f9SBarry Smith ierr = MatDestroy(&next->mat);CHKERRQ(ierr); 316d7c1e57SBarry Smith if (next->work && (!next->next || next->work != next->next->work)) { 326bf464f9SBarry Smith ierr = VecDestroy(&next->work);CHKERRQ(ierr); 336d7c1e57SBarry Smith } 346d7c1e57SBarry Smith oldnext = next; 35793850ffSBarry Smith next = next->next; 366d7c1e57SBarry Smith ierr = PetscFree(oldnext);CHKERRQ(ierr); 37793850ffSBarry Smith } 386bf464f9SBarry Smith ierr = VecDestroy(&shell->work);CHKERRQ(ierr); 396bf464f9SBarry Smith ierr = VecDestroy(&shell->left);CHKERRQ(ierr); 406bf464f9SBarry Smith ierr = VecDestroy(&shell->right);CHKERRQ(ierr); 416bf464f9SBarry Smith ierr = VecDestroy(&shell->leftwork);CHKERRQ(ierr); 426bf464f9SBarry Smith ierr = VecDestroy(&shell->rightwork);CHKERRQ(ierr); 436bf464f9SBarry Smith ierr = PetscFree(mat->data);CHKERRQ(ierr); 44793850ffSBarry Smith PetscFunctionReturn(0); 45793850ffSBarry Smith } 46793850ffSBarry Smith 476d7c1e57SBarry Smith PetscErrorCode MatMult_Composite_Multiplicative(Mat A,Vec x,Vec y) 486d7c1e57SBarry Smith { 496d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 506d7c1e57SBarry Smith Mat_CompositeLink next = shell->head; 516d7c1e57SBarry Smith PetscErrorCode ierr; 526d7c1e57SBarry Smith Vec in,out; 536d7c1e57SBarry Smith 546d7c1e57SBarry Smith PetscFunctionBegin; 55e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 566d7c1e57SBarry Smith in = x; 57e4fc5df0SBarry Smith if (shell->right) { 58e4fc5df0SBarry Smith if (!shell->rightwork) { 59e4fc5df0SBarry Smith ierr = VecDuplicate(shell->right,&shell->rightwork);CHKERRQ(ierr); 60e4fc5df0SBarry Smith } 61e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->rightwork,shell->right,in);CHKERRQ(ierr); 62e4fc5df0SBarry Smith in = shell->rightwork; 63e4fc5df0SBarry Smith } 646d7c1e57SBarry Smith while (next->next) { 656d7c1e57SBarry Smith if (!next->work) { /* should reuse previous work if the same size */ 662a7a6963SBarry Smith ierr = MatCreateVecs(next->mat,NULL,&next->work);CHKERRQ(ierr); 676d7c1e57SBarry Smith } 686d7c1e57SBarry Smith out = next->work; 696d7c1e57SBarry Smith ierr = MatMult(next->mat,in,out);CHKERRQ(ierr); 706d7c1e57SBarry Smith in = out; 716d7c1e57SBarry Smith next = next->next; 726d7c1e57SBarry Smith } 736d7c1e57SBarry Smith ierr = MatMult(next->mat,in,y);CHKERRQ(ierr); 74e4fc5df0SBarry Smith if (shell->left) { 75e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->left,y);CHKERRQ(ierr); 76e4fc5df0SBarry Smith } 77e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 786d7c1e57SBarry Smith PetscFunctionReturn(0); 796d7c1e57SBarry Smith } 806d7c1e57SBarry Smith 816d7c1e57SBarry Smith PetscErrorCode MatMultTranspose_Composite_Multiplicative(Mat A,Vec x,Vec y) 826d7c1e57SBarry Smith { 836d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 846d7c1e57SBarry Smith Mat_CompositeLink tail = shell->tail; 856d7c1e57SBarry Smith PetscErrorCode ierr; 866d7c1e57SBarry Smith Vec in,out; 876d7c1e57SBarry Smith 886d7c1e57SBarry Smith PetscFunctionBegin; 89e32f2f54SBarry Smith if (!tail) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 906d7c1e57SBarry Smith in = x; 91e4fc5df0SBarry Smith if (shell->left) { 92e4fc5df0SBarry Smith if (!shell->leftwork) { 93e4fc5df0SBarry Smith ierr = VecDuplicate(shell->left,&shell->leftwork);CHKERRQ(ierr); 94e4fc5df0SBarry Smith } 95e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->leftwork,shell->left,in);CHKERRQ(ierr); 96e4fc5df0SBarry Smith in = shell->leftwork; 97e4fc5df0SBarry Smith } 986d7c1e57SBarry Smith while (tail->prev) { 996d7c1e57SBarry Smith if (!tail->prev->work) { /* should reuse previous work if the same size */ 1002a7a6963SBarry Smith ierr = MatCreateVecs(tail->mat,NULL,&tail->prev->work);CHKERRQ(ierr); 1016d7c1e57SBarry Smith } 1026d7c1e57SBarry Smith out = tail->prev->work; 1036d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,out);CHKERRQ(ierr); 1046d7c1e57SBarry Smith in = out; 1056d7c1e57SBarry Smith tail = tail->prev; 1066d7c1e57SBarry Smith } 1076d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,y);CHKERRQ(ierr); 108e4fc5df0SBarry Smith if (shell->right) { 109e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->right,y);CHKERRQ(ierr); 110e4fc5df0SBarry Smith } 111e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 1126d7c1e57SBarry Smith PetscFunctionReturn(0); 1136d7c1e57SBarry Smith } 1146d7c1e57SBarry Smith 115793850ffSBarry Smith PetscErrorCode MatMult_Composite(Mat A,Vec x,Vec y) 116793850ffSBarry Smith { 117793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 118793850ffSBarry Smith Mat_CompositeLink next = shell->head; 119793850ffSBarry Smith PetscErrorCode ierr; 120e4fc5df0SBarry Smith Vec in; 121793850ffSBarry Smith 122793850ffSBarry Smith PetscFunctionBegin; 123e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 124e4fc5df0SBarry Smith in = x; 125e4fc5df0SBarry Smith if (shell->right) { 126e4fc5df0SBarry Smith if (!shell->rightwork) { 127e4fc5df0SBarry Smith ierr = VecDuplicate(shell->right,&shell->rightwork);CHKERRQ(ierr); 128793850ffSBarry Smith } 129e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->rightwork,shell->right,in);CHKERRQ(ierr); 130e4fc5df0SBarry Smith in = shell->rightwork; 131e4fc5df0SBarry Smith } 132e4fc5df0SBarry Smith ierr = MatMult(next->mat,in,y);CHKERRQ(ierr); 133e4fc5df0SBarry Smith while ((next = next->next)) { 134e4fc5df0SBarry Smith ierr = MatMultAdd(next->mat,in,y,y);CHKERRQ(ierr); 135e4fc5df0SBarry Smith } 136e4fc5df0SBarry Smith if (shell->left) { 137e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->left,y);CHKERRQ(ierr); 138e4fc5df0SBarry Smith } 139e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 140793850ffSBarry Smith PetscFunctionReturn(0); 141793850ffSBarry Smith } 142793850ffSBarry Smith 143793850ffSBarry Smith PetscErrorCode MatMultTranspose_Composite(Mat A,Vec x,Vec y) 144793850ffSBarry Smith { 145793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 146793850ffSBarry Smith Mat_CompositeLink next = shell->head; 147793850ffSBarry Smith PetscErrorCode ierr; 148e4fc5df0SBarry Smith Vec in; 149793850ffSBarry Smith 150793850ffSBarry Smith PetscFunctionBegin; 151e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 152e4fc5df0SBarry Smith in = x; 153e4fc5df0SBarry Smith if (shell->left) { 154e4fc5df0SBarry Smith if (!shell->leftwork) { 155e4fc5df0SBarry Smith ierr = VecDuplicate(shell->left,&shell->leftwork);CHKERRQ(ierr); 156793850ffSBarry Smith } 157e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->leftwork,shell->left,in);CHKERRQ(ierr); 158e4fc5df0SBarry Smith in = shell->leftwork; 159e4fc5df0SBarry Smith } 160e4fc5df0SBarry Smith ierr = MatMultTranspose(next->mat,in,y);CHKERRQ(ierr); 161e4fc5df0SBarry Smith while ((next = next->next)) { 162e4fc5df0SBarry Smith ierr = MatMultTransposeAdd(next->mat,in,y,y);CHKERRQ(ierr); 163e4fc5df0SBarry Smith } 164e4fc5df0SBarry Smith if (shell->right) { 165e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->right,y);CHKERRQ(ierr); 166e4fc5df0SBarry Smith } 167e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 168793850ffSBarry Smith PetscFunctionReturn(0); 169793850ffSBarry Smith } 170793850ffSBarry Smith 171793850ffSBarry Smith PetscErrorCode MatGetDiagonal_Composite(Mat A,Vec v) 172793850ffSBarry Smith { 173793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 174793850ffSBarry Smith Mat_CompositeLink next = shell->head; 175793850ffSBarry Smith PetscErrorCode ierr; 176793850ffSBarry Smith 177793850ffSBarry Smith PetscFunctionBegin; 178e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 179e32f2f54SBarry Smith if (shell->right || shell->left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get diagonal if left or right scaling"); 180e4fc5df0SBarry Smith 181793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,v);CHKERRQ(ierr); 182793850ffSBarry Smith if (next->next && !shell->work) { 183793850ffSBarry Smith ierr = VecDuplicate(v,&shell->work);CHKERRQ(ierr); 184793850ffSBarry Smith } 185793850ffSBarry Smith while ((next = next->next)) { 186793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,shell->work);CHKERRQ(ierr); 187793850ffSBarry Smith ierr = VecAXPY(v,1.0,shell->work);CHKERRQ(ierr); 188793850ffSBarry Smith } 189e4fc5df0SBarry Smith ierr = VecScale(v,shell->scale);CHKERRQ(ierr); 190793850ffSBarry Smith PetscFunctionReturn(0); 191793850ffSBarry Smith } 192793850ffSBarry Smith 193793850ffSBarry Smith PetscErrorCode MatAssemblyEnd_Composite(Mat Y,MatAssemblyType t) 194793850ffSBarry Smith { 195b52f573bSBarry Smith PetscErrorCode ierr; 196ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 197b52f573bSBarry Smith 198793850ffSBarry Smith PetscFunctionBegin; 199c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)Y)->options,((PetscObject)Y)->prefix,"-mat_composite_merge",&flg,NULL);CHKERRQ(ierr); 200b52f573bSBarry Smith if (flg) { 201b52f573bSBarry Smith ierr = MatCompositeMerge(Y);CHKERRQ(ierr); 202b52f573bSBarry Smith } 203793850ffSBarry Smith PetscFunctionReturn(0); 204793850ffSBarry Smith } 205793850ffSBarry Smith 206e4fc5df0SBarry Smith PetscErrorCode MatScale_Composite(Mat inA,PetscScalar alpha) 207e4fc5df0SBarry Smith { 208e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 209e4fc5df0SBarry Smith 210e4fc5df0SBarry Smith PetscFunctionBegin; 211321429dbSBarry Smith a->scale *= alpha; 212e4fc5df0SBarry Smith PetscFunctionReturn(0); 213e4fc5df0SBarry Smith } 214e4fc5df0SBarry Smith 215e4fc5df0SBarry Smith PetscErrorCode MatDiagonalScale_Composite(Mat inA,Vec left,Vec right) 216e4fc5df0SBarry Smith { 217e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 218e4fc5df0SBarry Smith PetscErrorCode ierr; 219e4fc5df0SBarry Smith 220e4fc5df0SBarry Smith PetscFunctionBegin; 221e4fc5df0SBarry Smith if (left) { 222321429dbSBarry Smith if (!a->left) { 223e4fc5df0SBarry Smith ierr = VecDuplicate(left,&a->left);CHKERRQ(ierr); 224e4fc5df0SBarry Smith ierr = VecCopy(left,a->left);CHKERRQ(ierr); 225321429dbSBarry Smith } else { 226321429dbSBarry Smith ierr = VecPointwiseMult(a->left,left,a->left);CHKERRQ(ierr); 227321429dbSBarry Smith } 228e4fc5df0SBarry Smith } 229e4fc5df0SBarry Smith if (right) { 230321429dbSBarry Smith if (!a->right) { 231e4fc5df0SBarry Smith ierr = VecDuplicate(right,&a->right);CHKERRQ(ierr); 232e4fc5df0SBarry Smith ierr = VecCopy(right,a->right);CHKERRQ(ierr); 233321429dbSBarry Smith } else { 234321429dbSBarry Smith ierr = VecPointwiseMult(a->right,right,a->right);CHKERRQ(ierr); 235321429dbSBarry Smith } 236e4fc5df0SBarry Smith } 237e4fc5df0SBarry Smith PetscFunctionReturn(0); 238e4fc5df0SBarry Smith } 239793850ffSBarry Smith 2402c0821f3SBarry Smith /*@ 241793850ffSBarry Smith MatCreateComposite - Creates a matrix as the sum of zero or more matrices 242793850ffSBarry Smith 243793850ffSBarry Smith Collective on MPI_Comm 244793850ffSBarry Smith 245793850ffSBarry Smith Input Parameters: 246793850ffSBarry Smith + comm - MPI communicator 247793850ffSBarry Smith . nmat - number of matrices to put in 248793850ffSBarry Smith - mats - the matrices 249793850ffSBarry Smith 250793850ffSBarry Smith Output Parameter: 251db36af27SMatthew G. Knepley . mat - the matrix 252793850ffSBarry Smith 253793850ffSBarry Smith Level: advanced 254793850ffSBarry Smith 255793850ffSBarry Smith Notes: 256793850ffSBarry Smith Alternative construction 257793850ffSBarry Smith $ MatCreate(comm,&mat); 258793850ffSBarry Smith $ MatSetSizes(mat,m,n,M,N); 259793850ffSBarry Smith $ MatSetType(mat,MATCOMPOSITE); 260793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[0]); 261793850ffSBarry Smith $ .... 262793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[nmat-1]); 263b52f573bSBarry Smith $ MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); 264b52f573bSBarry Smith $ MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); 265793850ffSBarry Smith 2666d7c1e57SBarry Smith For the multiplicative form the product is mat[nmat-1]*mat[nmat-2]*....*mat[0] 2676d7c1e57SBarry Smith 2686d7c1e57SBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCompositeMerge(), MatCompositeSetType(), MatCompositeType 269793850ffSBarry Smith 270793850ffSBarry Smith @*/ 2717087cfbeSBarry Smith PetscErrorCode MatCreateComposite(MPI_Comm comm,PetscInt nmat,const Mat *mats,Mat *mat) 272793850ffSBarry Smith { 273793850ffSBarry Smith PetscErrorCode ierr; 274793850ffSBarry Smith PetscInt m,n,M,N,i; 275793850ffSBarry Smith 276793850ffSBarry Smith PetscFunctionBegin; 277e32f2f54SBarry Smith if (nmat < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in at least one matrix"); 278f3f84630SBarry Smith PetscValidPointer(mat,3); 279793850ffSBarry Smith 280c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[0],PETSC_IGNORE,&n);CHKERRQ(ierr); 281c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[nmat-1],&m,PETSC_IGNORE);CHKERRQ(ierr); 282c4f13f43SJakub Kruzik ierr = MatGetSize(mats[0],PETSC_IGNORE,&N);CHKERRQ(ierr); 283c4f13f43SJakub Kruzik ierr = MatGetSize(mats[nmat-1],&M,PETSC_IGNORE);CHKERRQ(ierr); 284793850ffSBarry Smith ierr = MatCreate(comm,mat);CHKERRQ(ierr); 285793850ffSBarry Smith ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); 286793850ffSBarry Smith ierr = MatSetType(*mat,MATCOMPOSITE);CHKERRQ(ierr); 287793850ffSBarry Smith for (i=0; i<nmat; i++) { 288793850ffSBarry Smith ierr = MatCompositeAddMat(*mat,mats[i]);CHKERRQ(ierr); 289793850ffSBarry Smith } 290b52f573bSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 291b52f573bSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 292793850ffSBarry Smith PetscFunctionReturn(0); 293793850ffSBarry Smith } 294793850ffSBarry Smith 295d7f81bf2SJakub Kruzik 296d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeAddMat_Composite(Mat mat,Mat smat) 297d7f81bf2SJakub Kruzik { 298d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 299d7f81bf2SJakub Kruzik Mat_CompositeLink ilink,next = shell->head; 300d7f81bf2SJakub Kruzik PetscErrorCode ierr; 301d7f81bf2SJakub Kruzik 302d7f81bf2SJakub Kruzik PetscFunctionBegin; 303d7f81bf2SJakub Kruzik ierr = PetscNewLog(mat,&ilink);CHKERRQ(ierr); 304d7f81bf2SJakub Kruzik ilink->next = 0; 305d7f81bf2SJakub Kruzik ierr = PetscObjectReference((PetscObject)smat);CHKERRQ(ierr); 306d7f81bf2SJakub Kruzik ilink->mat = smat; 307d7f81bf2SJakub Kruzik 308d7f81bf2SJakub Kruzik if (!next) shell->head = ilink; 309d7f81bf2SJakub Kruzik else { 310d7f81bf2SJakub Kruzik while (next->next) { 311d7f81bf2SJakub Kruzik next = next->next; 312d7f81bf2SJakub Kruzik } 313d7f81bf2SJakub Kruzik next->next = ilink; 314d7f81bf2SJakub Kruzik ilink->prev = next; 315d7f81bf2SJakub Kruzik } 316d7f81bf2SJakub Kruzik shell->tail = ilink; 317d7f81bf2SJakub Kruzik shell->nmat += 1; 318d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 319d7f81bf2SJakub Kruzik } 320d7f81bf2SJakub Kruzik 321793850ffSBarry Smith /*@ 322793850ffSBarry Smith MatCompositeAddMat - add another matrix to a composite matrix 323793850ffSBarry Smith 324793850ffSBarry Smith Collective on Mat 325793850ffSBarry Smith 326793850ffSBarry Smith Input Parameters: 327793850ffSBarry Smith + mat - the composite matrix 328793850ffSBarry Smith - smat - the partial matrix 329793850ffSBarry Smith 330793850ffSBarry Smith Level: advanced 331793850ffSBarry Smith 332793850ffSBarry Smith .seealso: MatCreateComposite() 333793850ffSBarry Smith @*/ 3347087cfbeSBarry Smith PetscErrorCode MatCompositeAddMat(Mat mat,Mat smat) 335793850ffSBarry Smith { 336793850ffSBarry Smith PetscErrorCode ierr; 337793850ffSBarry Smith 338793850ffSBarry Smith PetscFunctionBegin; 3390700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3400700a824SBarry Smith PetscValidHeaderSpecific(smat,MAT_CLASSID,2); 341d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeAddMat_C",(Mat,Mat),(mat,smat));CHKERRQ(ierr); 342d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 343d7f81bf2SJakub Kruzik } 344793850ffSBarry Smith 345d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeSetType_Composite(Mat mat,MatCompositeType type) 346d7f81bf2SJakub Kruzik { 347d7f81bf2SJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 348d7f81bf2SJakub Kruzik 349d7f81bf2SJakub Kruzik PetscFunctionBegin; 350d7f81bf2SJakub Kruzik if (type == MAT_COMPOSITE_MULTIPLICATIVE) { 351d7f81bf2SJakub Kruzik mat->ops->getdiagonal = 0; 352d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite_Multiplicative; 353d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite_Multiplicative; 354d7f81bf2SJakub Kruzik b->type = MAT_COMPOSITE_MULTIPLICATIVE; 355d7f81bf2SJakub Kruzik } else { 356d7f81bf2SJakub Kruzik mat->ops->getdiagonal = MatGetDiagonal_Composite; 357d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite; 358d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite; 359d7f81bf2SJakub Kruzik b->type = MAT_COMPOSITE_ADDITIVE; 360793850ffSBarry Smith } 3616d7c1e57SBarry Smith PetscFunctionReturn(0); 3626d7c1e57SBarry Smith } 3636d7c1e57SBarry Smith 3642c0821f3SBarry Smith /*@ 3656d7c1e57SBarry Smith MatCompositeSetType - Indicates if the matrix is defined as the sum of a set of matrices or the product 3666d7c1e57SBarry Smith 3676d7c1e57SBarry Smith Collective on MPI_Comm 3686d7c1e57SBarry Smith 3696d7c1e57SBarry Smith Input Parameters: 3706d7c1e57SBarry Smith . mat - the composite matrix 3716d7c1e57SBarry Smith 3726d7c1e57SBarry Smith 3736d7c1e57SBarry Smith Level: advanced 3746d7c1e57SBarry Smith 3756d7c1e57SBarry Smith Notes: 3766d7c1e57SBarry Smith The MatType of the resulting matrix will be the same as the MatType of the FIRST 3776d7c1e57SBarry Smith matrix in the composite matrix. 3786d7c1e57SBarry Smith 3796d7c1e57SBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MATCOMPOSITE 3806d7c1e57SBarry Smith 3816d7c1e57SBarry Smith @*/ 3827087cfbeSBarry Smith PetscErrorCode MatCompositeSetType(Mat mat,MatCompositeType type) 3836d7c1e57SBarry Smith { 3846d7c1e57SBarry Smith PetscErrorCode ierr; 3856d7c1e57SBarry Smith 3866d7c1e57SBarry Smith PetscFunctionBegin; 387d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 388d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetType_C",(Mat,MatCompositeType),(mat,type));CHKERRQ(ierr); 389793850ffSBarry Smith PetscFunctionReturn(0); 390793850ffSBarry Smith } 391793850ffSBarry Smith 392d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeMerge_Composite(Mat mat) 393b52f573bSBarry Smith { 394b52f573bSBarry Smith Mat_Composite *shell = (Mat_Composite*)mat->data; 3956d7c1e57SBarry Smith Mat_CompositeLink next = shell->head, prev = shell->tail; 396b52f573bSBarry Smith PetscErrorCode ierr; 3976d7c1e57SBarry Smith Mat tmat,newmat; 3981ba60692SJed Brown Vec left,right; 3991ba60692SJed Brown PetscScalar scale; 400b52f573bSBarry Smith 401b52f573bSBarry Smith PetscFunctionBegin; 402e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 403b52f573bSBarry Smith 404b52f573bSBarry Smith PetscFunctionBegin; 4056d7c1e57SBarry Smith if (shell->type == MAT_COMPOSITE_ADDITIVE) { 406b52f573bSBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 407b52f573bSBarry Smith while ((next = next->next)) { 408b52f573bSBarry Smith ierr = MatAXPY(tmat,1.0,next->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 409b52f573bSBarry Smith } 4106d7c1e57SBarry Smith } else { 411*04d534ceSJakub Kruzik if (shell->mergefromright) { 4126d7c1e57SBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 413b6cfcaf5SJakub Kruzik while ((next = next->next)) { 414b6cfcaf5SJakub Kruzik ierr = MatMatMult(next->mat,tmat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 4156bf464f9SBarry Smith ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4166d7c1e57SBarry Smith tmat = newmat; 4176d7c1e57SBarry Smith } 418*04d534ceSJakub Kruzik } else { 419*04d534ceSJakub Kruzik ierr = MatDuplicate(prev->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 420*04d534ceSJakub Kruzik while ((prev = prev->prev)) { 421*04d534ceSJakub Kruzik ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 422*04d534ceSJakub Kruzik ierr = MatDestroy(&tmat);CHKERRQ(ierr); 423*04d534ceSJakub Kruzik tmat = newmat; 424*04d534ceSJakub Kruzik } 425*04d534ceSJakub Kruzik } 4266d7c1e57SBarry Smith } 4271ba60692SJed Brown 4281ba60692SJed Brown scale = shell->scale; 4291ba60692SJed Brown if ((left = shell->left)) {ierr = PetscObjectReference((PetscObject)left);CHKERRQ(ierr);} 4301ba60692SJed Brown if ((right = shell->right)) {ierr = PetscObjectReference((PetscObject)right);CHKERRQ(ierr);} 4311ba60692SJed Brown 43228be2f97SBarry Smith ierr = MatHeaderReplace(mat,&tmat);CHKERRQ(ierr); 4331ba60692SJed Brown 4341ba60692SJed Brown ierr = MatDiagonalScale(mat,left,right);CHKERRQ(ierr); 4351ba60692SJed Brown ierr = MatScale(mat,scale);CHKERRQ(ierr); 4361ba60692SJed Brown ierr = VecDestroy(&left);CHKERRQ(ierr); 4371ba60692SJed Brown ierr = VecDestroy(&right);CHKERRQ(ierr); 438b52f573bSBarry Smith PetscFunctionReturn(0); 439b52f573bSBarry Smith } 4406a7ede75SJakub Kruzik 4416a7ede75SJakub Kruzik /*@ 442d7f81bf2SJakub Kruzik MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix 443d7f81bf2SJakub Kruzik by summing all the matrices inside the composite matrix. 444d7f81bf2SJakub Kruzik 445d7f81bf2SJakub Kruzik Collective on MPI_Comm 446d7f81bf2SJakub Kruzik 447d7f81bf2SJakub Kruzik Input Parameters: 448d7f81bf2SJakub Kruzik . mat - the composite matrix 449d7f81bf2SJakub Kruzik 450d7f81bf2SJakub Kruzik 451d7f81bf2SJakub Kruzik Options Database: 452d7f81bf2SJakub Kruzik . -mat_composite_merge (you must call MatAssemblyBegin()/MatAssemblyEnd() to have this checked) 453d7f81bf2SJakub Kruzik 454d7f81bf2SJakub Kruzik Level: advanced 455d7f81bf2SJakub Kruzik 456d7f81bf2SJakub Kruzik Notes: 457d7f81bf2SJakub Kruzik The MatType of the resulting matrix will be the same as the MatType of the FIRST 458d7f81bf2SJakub Kruzik matrix in the composite matrix. 459d7f81bf2SJakub Kruzik 460*04d534ceSJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeSetMergeFromRight(), MATCOMPOSITE 461d7f81bf2SJakub Kruzik 462d7f81bf2SJakub Kruzik @*/ 463d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeMerge(Mat mat) 464d7f81bf2SJakub Kruzik { 465d7f81bf2SJakub Kruzik PetscErrorCode ierr; 466d7f81bf2SJakub Kruzik 467d7f81bf2SJakub Kruzik PetscFunctionBegin; 468d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 469d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeMerge_C",(Mat),(mat));CHKERRQ(ierr); 470d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 471d7f81bf2SJakub Kruzik } 472d7f81bf2SJakub Kruzik 473d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetNMat_Composite(Mat mat,PetscInt *nmat) 474d7f81bf2SJakub Kruzik { 475d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 476d7f81bf2SJakub Kruzik 477d7f81bf2SJakub Kruzik PetscFunctionBegin; 478d7f81bf2SJakub Kruzik *nmat = shell->nmat; 479d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 480d7f81bf2SJakub Kruzik } 481d7f81bf2SJakub Kruzik 482d7f81bf2SJakub Kruzik /*@ 4836a7ede75SJakub Kruzik MatCompositeGetNMat - Returns the number of matrices in composite. 4846a7ede75SJakub Kruzik 4856a7ede75SJakub Kruzik Not Collective 4866a7ede75SJakub Kruzik 4876a7ede75SJakub Kruzik Input Parameter: 488d7f81bf2SJakub Kruzik . mat - the composite matrix 4896a7ede75SJakub Kruzik 4906a7ede75SJakub Kruzik Output Parameter: 4916a7ede75SJakub Kruzik . size - the local size 4926a7ede75SJakub Kruzik . nmat - number of matrices in composite 4936a7ede75SJakub Kruzik 4948b5c3584SJakub Kruzik Level: advanced 4956a7ede75SJakub Kruzik 4968b5c3584SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat() 4976a7ede75SJakub Kruzik 4986a7ede75SJakub Kruzik @*/ 499d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetNMat(Mat mat,PetscInt *nmat) 5006a7ede75SJakub Kruzik { 501d7f81bf2SJakub Kruzik PetscErrorCode ierr; 5026a7ede75SJakub Kruzik 5036a7ede75SJakub Kruzik PetscFunctionBegin; 504d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5056a7ede75SJakub Kruzik PetscValidPointer(nmat,2); 506d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetNMat_C",(Mat,PetscInt*),(mat,nmat));CHKERRQ(ierr); 507d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 508d7f81bf2SJakub Kruzik } 509d7f81bf2SJakub Kruzik 510d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetMat_Composite(Mat mat,PetscInt i,Mat *Ai) 511d7f81bf2SJakub Kruzik { 512d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 513d7f81bf2SJakub Kruzik Mat_CompositeLink ilink; 514d7f81bf2SJakub Kruzik PetscInt k; 515d7f81bf2SJakub Kruzik 516d7f81bf2SJakub Kruzik PetscFunctionBegin; 517d7f81bf2SJakub Kruzik if (i >= shell->nmat) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"index out of range: %d >= %d",i,shell->nmat); 518d7f81bf2SJakub Kruzik ilink = shell->head; 519d7f81bf2SJakub Kruzik for (k=0; k<i; k++) { 520d7f81bf2SJakub Kruzik ilink = ilink->next; 521d7f81bf2SJakub Kruzik } 522d7f81bf2SJakub Kruzik *Ai = ilink->mat; 5236a7ede75SJakub Kruzik PetscFunctionReturn(0); 5246a7ede75SJakub Kruzik } 5256a7ede75SJakub Kruzik 5268b5c3584SJakub Kruzik /*@ 5278b5c3584SJakub Kruzik MatCompositeGetMat - Returns the ith matrix from composite. 5288b5c3584SJakub Kruzik 5298b5c3584SJakub Kruzik Logically Collective on Mat 5308b5c3584SJakub Kruzik 5318b5c3584SJakub Kruzik Input Parameter: 532d7f81bf2SJakub Kruzik + mat - the composite matrix 5338b5c3584SJakub Kruzik - i - the number of requested matrix 5348b5c3584SJakub Kruzik 5358b5c3584SJakub Kruzik Output Parameter: 5368b5c3584SJakub Kruzik . Ai - ith matrix in composite 5378b5c3584SJakub Kruzik 5388b5c3584SJakub Kruzik Level: advanced 5398b5c3584SJakub Kruzik 5408b5c3584SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetNMat() 5418b5c3584SJakub Kruzik 5428b5c3584SJakub Kruzik @*/ 543d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetMat(Mat mat,PetscInt i,Mat *Ai) 5448b5c3584SJakub Kruzik { 545d7f81bf2SJakub Kruzik PetscErrorCode ierr; 5468b5c3584SJakub Kruzik 5478b5c3584SJakub Kruzik PetscFunctionBegin; 548d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 549d7f81bf2SJakub Kruzik PetscValidLogicalCollectiveInt(mat,i,2); 5508b5c3584SJakub Kruzik PetscValidPointer(Ai,3); 551d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetMat_C",(Mat,PetscInt,Mat*),(mat,i,Ai));CHKERRQ(ierr); 5528b5c3584SJakub Kruzik PetscFunctionReturn(0); 5538b5c3584SJakub Kruzik } 5548b5c3584SJakub Kruzik 555*04d534ceSJakub Kruzik static PetscErrorCode MatCompositeSetMergeFromRight_Composite(Mat mat,PetscBool flg) 556*04d534ceSJakub Kruzik { 557*04d534ceSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 558*04d534ceSJakub Kruzik 559*04d534ceSJakub Kruzik PetscFunctionBegin; 560*04d534ceSJakub Kruzik shell->mergefromright = flg; 561*04d534ceSJakub Kruzik PetscFunctionReturn(0); 562*04d534ceSJakub Kruzik } 563*04d534ceSJakub Kruzik 564*04d534ceSJakub Kruzik /*@ 565*04d534ceSJakub Kruzik MatCompositeSetMergeFromRight - Sets MatCompositeMerge() to start from right. 566*04d534ceSJakub Kruzik 567*04d534ceSJakub Kruzik Logically Collective on Mat 568*04d534ceSJakub Kruzik 569*04d534ceSJakub Kruzik Input Parameter: 570*04d534ceSJakub Kruzik + mat - the composite matrix 571*04d534ceSJakub Kruzik - flg - if true (default) the merge starts with the first added matrix (mat[0]) 572*04d534ceSJakub Kruzik 573*04d534ceSJakub Kruzik Level: advanced 574*04d534ceSJakub Kruzik 575*04d534ceSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeMerge() 576*04d534ceSJakub Kruzik 577*04d534ceSJakub Kruzik @*/ 578*04d534ceSJakub Kruzik PetscErrorCode MatCompositeSetMergeFromRight(Mat mat,PetscBool flg) 579*04d534ceSJakub Kruzik { 580*04d534ceSJakub Kruzik PetscErrorCode ierr; 581*04d534ceSJakub Kruzik 582*04d534ceSJakub Kruzik PetscFunctionBegin; 583*04d534ceSJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 584*04d534ceSJakub Kruzik PetscValidLogicalCollectiveBool(mat,flg,2); 585*04d534ceSJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetMergeFromRight_C",(Mat,PetscBool),(mat,flg));CHKERRQ(ierr); 586*04d534ceSJakub Kruzik PetscFunctionReturn(0); 587*04d534ceSJakub Kruzik } 588*04d534ceSJakub Kruzik 58941cd0125SJakub Kruzik static struct _MatOps MatOps_Values = {0, 59041cd0125SJakub Kruzik 0, 59141cd0125SJakub Kruzik 0, 59241cd0125SJakub Kruzik MatMult_Composite, 59341cd0125SJakub Kruzik 0, 59441cd0125SJakub Kruzik /* 5*/ MatMultTranspose_Composite, 59541cd0125SJakub Kruzik 0, 59641cd0125SJakub Kruzik 0, 59741cd0125SJakub Kruzik 0, 59841cd0125SJakub Kruzik 0, 59941cd0125SJakub Kruzik /* 10*/ 0, 60041cd0125SJakub Kruzik 0, 60141cd0125SJakub Kruzik 0, 60241cd0125SJakub Kruzik 0, 60341cd0125SJakub Kruzik 0, 60441cd0125SJakub Kruzik /* 15*/ 0, 60541cd0125SJakub Kruzik 0, 60641cd0125SJakub Kruzik MatGetDiagonal_Composite, 60741cd0125SJakub Kruzik MatDiagonalScale_Composite, 60841cd0125SJakub Kruzik 0, 60941cd0125SJakub Kruzik /* 20*/ 0, 61041cd0125SJakub Kruzik MatAssemblyEnd_Composite, 61141cd0125SJakub Kruzik 0, 61241cd0125SJakub Kruzik 0, 61341cd0125SJakub Kruzik /* 24*/ 0, 61441cd0125SJakub Kruzik 0, 61541cd0125SJakub Kruzik 0, 61641cd0125SJakub Kruzik 0, 61741cd0125SJakub Kruzik 0, 61841cd0125SJakub Kruzik /* 29*/ 0, 61941cd0125SJakub Kruzik 0, 62041cd0125SJakub Kruzik 0, 62141cd0125SJakub Kruzik 0, 62241cd0125SJakub Kruzik 0, 62341cd0125SJakub Kruzik /* 34*/ 0, 62441cd0125SJakub Kruzik 0, 62541cd0125SJakub Kruzik 0, 62641cd0125SJakub Kruzik 0, 62741cd0125SJakub Kruzik 0, 62841cd0125SJakub Kruzik /* 39*/ 0, 62941cd0125SJakub Kruzik 0, 63041cd0125SJakub Kruzik 0, 63141cd0125SJakub Kruzik 0, 63241cd0125SJakub Kruzik 0, 63341cd0125SJakub Kruzik /* 44*/ 0, 63441cd0125SJakub Kruzik MatScale_Composite, 63541cd0125SJakub Kruzik MatShift_Basic, 63641cd0125SJakub Kruzik 0, 63741cd0125SJakub Kruzik 0, 63841cd0125SJakub Kruzik /* 49*/ 0, 63941cd0125SJakub Kruzik 0, 64041cd0125SJakub Kruzik 0, 64141cd0125SJakub Kruzik 0, 64241cd0125SJakub Kruzik 0, 64341cd0125SJakub Kruzik /* 54*/ 0, 64441cd0125SJakub Kruzik 0, 64541cd0125SJakub Kruzik 0, 64641cd0125SJakub Kruzik 0, 64741cd0125SJakub Kruzik 0, 64841cd0125SJakub Kruzik /* 59*/ 0, 64941cd0125SJakub Kruzik MatDestroy_Composite, 65041cd0125SJakub Kruzik 0, 65141cd0125SJakub Kruzik 0, 65241cd0125SJakub Kruzik 0, 65341cd0125SJakub Kruzik /* 64*/ 0, 65441cd0125SJakub Kruzik 0, 65541cd0125SJakub Kruzik 0, 65641cd0125SJakub Kruzik 0, 65741cd0125SJakub Kruzik 0, 65841cd0125SJakub Kruzik /* 69*/ 0, 65941cd0125SJakub Kruzik 0, 66041cd0125SJakub Kruzik 0, 66141cd0125SJakub Kruzik 0, 66241cd0125SJakub Kruzik 0, 66341cd0125SJakub Kruzik /* 74*/ 0, 66441cd0125SJakub Kruzik 0, 66541cd0125SJakub Kruzik 0, 66641cd0125SJakub Kruzik 0, 66741cd0125SJakub Kruzik 0, 66841cd0125SJakub Kruzik /* 79*/ 0, 66941cd0125SJakub Kruzik 0, 67041cd0125SJakub Kruzik 0, 67141cd0125SJakub Kruzik 0, 67241cd0125SJakub Kruzik 0, 67341cd0125SJakub Kruzik /* 84*/ 0, 67441cd0125SJakub Kruzik 0, 67541cd0125SJakub Kruzik 0, 67641cd0125SJakub Kruzik 0, 67741cd0125SJakub Kruzik 0, 67841cd0125SJakub Kruzik /* 89*/ 0, 67941cd0125SJakub Kruzik 0, 68041cd0125SJakub Kruzik 0, 68141cd0125SJakub Kruzik 0, 68241cd0125SJakub Kruzik 0, 68341cd0125SJakub Kruzik /* 94*/ 0, 68441cd0125SJakub Kruzik 0, 68541cd0125SJakub Kruzik 0, 68641cd0125SJakub Kruzik 0, 68741cd0125SJakub Kruzik 0, 68841cd0125SJakub Kruzik /*99*/ 0, 68941cd0125SJakub Kruzik 0, 69041cd0125SJakub Kruzik 0, 69141cd0125SJakub Kruzik 0, 69241cd0125SJakub Kruzik 0, 69341cd0125SJakub Kruzik /*104*/ 0, 69441cd0125SJakub Kruzik 0, 69541cd0125SJakub Kruzik 0, 69641cd0125SJakub Kruzik 0, 69741cd0125SJakub Kruzik 0, 69841cd0125SJakub Kruzik /*109*/ 0, 69941cd0125SJakub Kruzik 0, 70041cd0125SJakub Kruzik 0, 70141cd0125SJakub Kruzik 0, 70241cd0125SJakub Kruzik 0, 70341cd0125SJakub Kruzik /*114*/ 0, 70441cd0125SJakub Kruzik 0, 70541cd0125SJakub Kruzik 0, 70641cd0125SJakub Kruzik 0, 70741cd0125SJakub Kruzik 0, 70841cd0125SJakub Kruzik /*119*/ 0, 70941cd0125SJakub Kruzik 0, 71041cd0125SJakub Kruzik 0, 71141cd0125SJakub Kruzik 0, 71241cd0125SJakub Kruzik 0, 71341cd0125SJakub Kruzik /*124*/ 0, 71441cd0125SJakub Kruzik 0, 71541cd0125SJakub Kruzik 0, 71641cd0125SJakub Kruzik 0, 71741cd0125SJakub Kruzik 0, 71841cd0125SJakub Kruzik /*129*/ 0, 71941cd0125SJakub Kruzik 0, 72041cd0125SJakub Kruzik 0, 72141cd0125SJakub Kruzik 0, 72241cd0125SJakub Kruzik 0, 72341cd0125SJakub Kruzik /*134*/ 0, 72441cd0125SJakub Kruzik 0, 72541cd0125SJakub Kruzik 0, 72641cd0125SJakub Kruzik 0, 72741cd0125SJakub Kruzik 0, 72841cd0125SJakub Kruzik /*139*/ 0, 72941cd0125SJakub Kruzik 0, 73041cd0125SJakub Kruzik 0 73141cd0125SJakub Kruzik }; 73241cd0125SJakub Kruzik 73341cd0125SJakub Kruzik /*MC 73441cd0125SJakub Kruzik MATCOMPOSITE - A matrix defined by the sum (or product) of one or more matrices. 73541cd0125SJakub Kruzik The matrices need to have a correct size and parallel layout for the sum or product to be valid. 73641cd0125SJakub Kruzik 73741cd0125SJakub Kruzik Notes: 73841cd0125SJakub Kruzik to use the product of the matrices call MatCompositeSetType(mat,MAT_COMPOSITE_MULTIPLICATIVE); 73941cd0125SJakub Kruzik 74041cd0125SJakub Kruzik Level: advanced 74141cd0125SJakub Kruzik 742*04d534ceSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeAddMat(), MatSetType(), MatCompositeSetType(), MatCompositeMerge(), MatCompositeSetMergeFromRight(), MatCompositeGetNmat(), MatCompositeGetMat() 74341cd0125SJakub Kruzik M*/ 74441cd0125SJakub Kruzik 74541cd0125SJakub Kruzik PETSC_EXTERN PetscErrorCode MatCreate_Composite(Mat A) 74641cd0125SJakub Kruzik { 74741cd0125SJakub Kruzik Mat_Composite *b; 74841cd0125SJakub Kruzik PetscErrorCode ierr; 74941cd0125SJakub Kruzik 75041cd0125SJakub Kruzik PetscFunctionBegin; 75141cd0125SJakub Kruzik ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 75241cd0125SJakub Kruzik A->data = (void*)b; 75341cd0125SJakub Kruzik ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 75441cd0125SJakub Kruzik 75541cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 75641cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 75741cd0125SJakub Kruzik 75841cd0125SJakub Kruzik A->assembled = PETSC_TRUE; 75941cd0125SJakub Kruzik A->preallocated = PETSC_TRUE; 76041cd0125SJakub Kruzik b->type = MAT_COMPOSITE_ADDITIVE; 76141cd0125SJakub Kruzik b->scale = 1.0; 76241cd0125SJakub Kruzik b->nmat = 0; 763*04d534ceSJakub Kruzik b->mergefromright = PETSC_TRUE; 76441cd0125SJakub Kruzik 76541cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeAddMat_C",MatCompositeAddMat_Composite);CHKERRQ(ierr); 76641cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetType_C",MatCompositeSetType_Composite);CHKERRQ(ierr); 76741cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeMerge_C",MatCompositeMerge_Composite);CHKERRQ(ierr); 76841cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetNMat_C",MatCompositeGetNMat_Composite);CHKERRQ(ierr); 76941cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetMat_C",MatCompositeGetMat_Composite);CHKERRQ(ierr); 770*04d534ceSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetMergeFromRight_C",MatCompositeSetMergeFromRight_Composite);CHKERRQ(ierr); 77141cd0125SJakub Kruzik 77241cd0125SJakub Kruzik ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr); 77341cd0125SJakub Kruzik PetscFunctionReturn(0); 77441cd0125SJakub Kruzik } 77541cd0125SJakub Kruzik 776