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; 1904d534ceSJakub 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 1717bf3a71bSJakub Kruzik PetscErrorCode MatMultAdd_Composite(Mat A,Vec x,Vec y,Vec z) 1727bf3a71bSJakub Kruzik { 1737bf3a71bSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)A->data; 1747bf3a71bSJakub Kruzik PetscErrorCode ierr; 1757bf3a71bSJakub Kruzik 1767bf3a71bSJakub Kruzik PetscFunctionBegin; 1777bf3a71bSJakub Kruzik if (y != z) { 1787bf3a71bSJakub Kruzik ierr = MatMult(A,x,z);CHKERRQ(ierr); 1797bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,y);CHKERRQ(ierr); 1807bf3a71bSJakub Kruzik } else { 1817bf3a71bSJakub Kruzik if (!shell->leftwork) { 1827bf3a71bSJakub Kruzik ierr = VecDuplicate(z,&shell->leftwork);CHKERRQ(ierr); 1837bf3a71bSJakub Kruzik } 1847bf3a71bSJakub Kruzik ierr = MatMult(A,x,shell->leftwork);CHKERRQ(ierr); 1857bf3a71bSJakub Kruzik ierr = VecCopy(y,z);CHKERRQ(ierr); 1867bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,shell->leftwork);CHKERRQ(ierr); 1877bf3a71bSJakub Kruzik } 1887bf3a71bSJakub Kruzik PetscFunctionReturn(0); 1897bf3a71bSJakub Kruzik } 1907bf3a71bSJakub Kruzik 1917bf3a71bSJakub Kruzik PetscErrorCode MatMultTransposeAdd_Composite(Mat A,Vec x,Vec y, Vec z) 1927bf3a71bSJakub Kruzik { 1937bf3a71bSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)A->data; 1947bf3a71bSJakub Kruzik PetscErrorCode ierr; 1957bf3a71bSJakub Kruzik 1967bf3a71bSJakub Kruzik PetscFunctionBegin; 1977bf3a71bSJakub Kruzik if (y != z) { 1987bf3a71bSJakub Kruzik ierr = MatMultTranspose(A,x,z);CHKERRQ(ierr); 1997bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,y);CHKERRQ(ierr); 2007bf3a71bSJakub Kruzik } else { 2017bf3a71bSJakub Kruzik if (!shell->rightwork) { 2027bf3a71bSJakub Kruzik ierr = VecDuplicate(z,&shell->rightwork);CHKERRQ(ierr); 2037bf3a71bSJakub Kruzik } 2047bf3a71bSJakub Kruzik ierr = MatMultTranspose(A,x,shell->rightwork);CHKERRQ(ierr); 2057bf3a71bSJakub Kruzik ierr = VecCopy(y,z);CHKERRQ(ierr); 2067bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,shell->rightwork);CHKERRQ(ierr); 2077bf3a71bSJakub Kruzik } 2087bf3a71bSJakub Kruzik PetscFunctionReturn(0); 2097bf3a71bSJakub Kruzik } 2107bf3a71bSJakub Kruzik 211793850ffSBarry Smith PetscErrorCode MatGetDiagonal_Composite(Mat A,Vec v) 212793850ffSBarry Smith { 213793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 214793850ffSBarry Smith Mat_CompositeLink next = shell->head; 215793850ffSBarry Smith PetscErrorCode ierr; 216793850ffSBarry Smith 217793850ffSBarry Smith PetscFunctionBegin; 218e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 219e32f2f54SBarry Smith if (shell->right || shell->left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get diagonal if left or right scaling"); 220e4fc5df0SBarry Smith 221793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,v);CHKERRQ(ierr); 222793850ffSBarry Smith if (next->next && !shell->work) { 223793850ffSBarry Smith ierr = VecDuplicate(v,&shell->work);CHKERRQ(ierr); 224793850ffSBarry Smith } 225793850ffSBarry Smith while ((next = next->next)) { 226793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,shell->work);CHKERRQ(ierr); 227793850ffSBarry Smith ierr = VecAXPY(v,1.0,shell->work);CHKERRQ(ierr); 228793850ffSBarry Smith } 229e4fc5df0SBarry Smith ierr = VecScale(v,shell->scale);CHKERRQ(ierr); 230793850ffSBarry Smith PetscFunctionReturn(0); 231793850ffSBarry Smith } 232793850ffSBarry Smith 233793850ffSBarry Smith PetscErrorCode MatAssemblyEnd_Composite(Mat Y,MatAssemblyType t) 234793850ffSBarry Smith { 235b52f573bSBarry Smith PetscErrorCode ierr; 236ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 237b52f573bSBarry Smith 238793850ffSBarry Smith PetscFunctionBegin; 239c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject)Y)->options,((PetscObject)Y)->prefix,"-mat_composite_merge",&flg,NULL);CHKERRQ(ierr); 240b52f573bSBarry Smith if (flg) { 241b52f573bSBarry Smith ierr = MatCompositeMerge(Y);CHKERRQ(ierr); 242b52f573bSBarry Smith } 243793850ffSBarry Smith PetscFunctionReturn(0); 244793850ffSBarry Smith } 245793850ffSBarry Smith 246e4fc5df0SBarry Smith PetscErrorCode MatScale_Composite(Mat inA,PetscScalar alpha) 247e4fc5df0SBarry Smith { 248e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 249e4fc5df0SBarry Smith 250e4fc5df0SBarry Smith PetscFunctionBegin; 251321429dbSBarry Smith a->scale *= alpha; 252e4fc5df0SBarry Smith PetscFunctionReturn(0); 253e4fc5df0SBarry Smith } 254e4fc5df0SBarry Smith 255e4fc5df0SBarry Smith PetscErrorCode MatDiagonalScale_Composite(Mat inA,Vec left,Vec right) 256e4fc5df0SBarry Smith { 257e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 258e4fc5df0SBarry Smith PetscErrorCode ierr; 259e4fc5df0SBarry Smith 260e4fc5df0SBarry Smith PetscFunctionBegin; 261e4fc5df0SBarry Smith if (left) { 262321429dbSBarry Smith if (!a->left) { 263e4fc5df0SBarry Smith ierr = VecDuplicate(left,&a->left);CHKERRQ(ierr); 264e4fc5df0SBarry Smith ierr = VecCopy(left,a->left);CHKERRQ(ierr); 265321429dbSBarry Smith } else { 266321429dbSBarry Smith ierr = VecPointwiseMult(a->left,left,a->left);CHKERRQ(ierr); 267321429dbSBarry Smith } 268e4fc5df0SBarry Smith } 269e4fc5df0SBarry Smith if (right) { 270321429dbSBarry Smith if (!a->right) { 271e4fc5df0SBarry Smith ierr = VecDuplicate(right,&a->right);CHKERRQ(ierr); 272e4fc5df0SBarry Smith ierr = VecCopy(right,a->right);CHKERRQ(ierr); 273321429dbSBarry Smith } else { 274321429dbSBarry Smith ierr = VecPointwiseMult(a->right,right,a->right);CHKERRQ(ierr); 275321429dbSBarry Smith } 276e4fc5df0SBarry Smith } 277e4fc5df0SBarry Smith PetscFunctionReturn(0); 278e4fc5df0SBarry Smith } 279793850ffSBarry Smith 2802c0821f3SBarry Smith /*@ 2818bd739bdSJakub Kruzik MatCreateComposite - Creates a matrix as the sum or product of one or more matrices 282793850ffSBarry Smith 283793850ffSBarry Smith Collective on MPI_Comm 284793850ffSBarry Smith 285793850ffSBarry Smith Input Parameters: 286793850ffSBarry Smith + comm - MPI communicator 287793850ffSBarry Smith . nmat - number of matrices to put in 288793850ffSBarry Smith - mats - the matrices 289793850ffSBarry Smith 290793850ffSBarry Smith Output Parameter: 291db36af27SMatthew G. Knepley . mat - the matrix 292793850ffSBarry Smith 293793850ffSBarry Smith Level: advanced 294793850ffSBarry Smith 295793850ffSBarry Smith Notes: 296793850ffSBarry Smith Alternative construction 297793850ffSBarry Smith $ MatCreate(comm,&mat); 298793850ffSBarry Smith $ MatSetSizes(mat,m,n,M,N); 299793850ffSBarry Smith $ MatSetType(mat,MATCOMPOSITE); 300793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[0]); 301793850ffSBarry Smith $ .... 302793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[nmat-1]); 303b52f573bSBarry Smith $ MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); 304b52f573bSBarry Smith $ MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); 305793850ffSBarry Smith 3066d7c1e57SBarry Smith For the multiplicative form the product is mat[nmat-1]*mat[nmat-2]*....*mat[0] 3076d7c1e57SBarry Smith 3086dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCompositeGetMat(), MatCompositeMerge(), MatCompositeSetType(), MATCOMPOSITE 309793850ffSBarry Smith 310793850ffSBarry Smith @*/ 3117087cfbeSBarry Smith PetscErrorCode MatCreateComposite(MPI_Comm comm,PetscInt nmat,const Mat *mats,Mat *mat) 312793850ffSBarry Smith { 313793850ffSBarry Smith PetscErrorCode ierr; 314793850ffSBarry Smith PetscInt m,n,M,N,i; 315793850ffSBarry Smith 316793850ffSBarry Smith PetscFunctionBegin; 317e32f2f54SBarry Smith if (nmat < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in at least one matrix"); 318f3f84630SBarry Smith PetscValidPointer(mat,3); 319793850ffSBarry Smith 320c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[0],PETSC_IGNORE,&n);CHKERRQ(ierr); 321c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[nmat-1],&m,PETSC_IGNORE);CHKERRQ(ierr); 322c4f13f43SJakub Kruzik ierr = MatGetSize(mats[0],PETSC_IGNORE,&N);CHKERRQ(ierr); 323c4f13f43SJakub Kruzik ierr = MatGetSize(mats[nmat-1],&M,PETSC_IGNORE);CHKERRQ(ierr); 324793850ffSBarry Smith ierr = MatCreate(comm,mat);CHKERRQ(ierr); 325793850ffSBarry Smith ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); 326793850ffSBarry Smith ierr = MatSetType(*mat,MATCOMPOSITE);CHKERRQ(ierr); 327793850ffSBarry Smith for (i=0; i<nmat; i++) { 328793850ffSBarry Smith ierr = MatCompositeAddMat(*mat,mats[i]);CHKERRQ(ierr); 329793850ffSBarry Smith } 330b52f573bSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 331b52f573bSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 332793850ffSBarry Smith PetscFunctionReturn(0); 333793850ffSBarry Smith } 334793850ffSBarry Smith 335d7f81bf2SJakub Kruzik 336d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeAddMat_Composite(Mat mat,Mat smat) 337d7f81bf2SJakub Kruzik { 338d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 339d7f81bf2SJakub Kruzik Mat_CompositeLink ilink,next = shell->head; 340d7f81bf2SJakub Kruzik PetscErrorCode ierr; 341d7f81bf2SJakub Kruzik 342d7f81bf2SJakub Kruzik PetscFunctionBegin; 343d7f81bf2SJakub Kruzik ierr = PetscNewLog(mat,&ilink);CHKERRQ(ierr); 344d7f81bf2SJakub Kruzik ilink->next = 0; 345d7f81bf2SJakub Kruzik ierr = PetscObjectReference((PetscObject)smat);CHKERRQ(ierr); 346d7f81bf2SJakub Kruzik ilink->mat = smat; 347d7f81bf2SJakub Kruzik 348d7f81bf2SJakub Kruzik if (!next) shell->head = ilink; 349d7f81bf2SJakub Kruzik else { 350d7f81bf2SJakub Kruzik while (next->next) { 351d7f81bf2SJakub Kruzik next = next->next; 352d7f81bf2SJakub Kruzik } 353d7f81bf2SJakub Kruzik next->next = ilink; 354d7f81bf2SJakub Kruzik ilink->prev = next; 355d7f81bf2SJakub Kruzik } 356d7f81bf2SJakub Kruzik shell->tail = ilink; 357d7f81bf2SJakub Kruzik shell->nmat += 1; 358d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 359d7f81bf2SJakub Kruzik } 360d7f81bf2SJakub Kruzik 361793850ffSBarry Smith /*@ 3628bd739bdSJakub Kruzik MatCompositeAddMat - Add another matrix to a composite matrix. 363793850ffSBarry Smith 364793850ffSBarry Smith Collective on Mat 365793850ffSBarry Smith 366793850ffSBarry Smith Input Parameters: 367793850ffSBarry Smith + mat - the composite matrix 368793850ffSBarry Smith - smat - the partial matrix 369793850ffSBarry Smith 370793850ffSBarry Smith Level: advanced 371793850ffSBarry Smith 3728bd739bdSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat(), MATCOMPOSITE 373793850ffSBarry Smith @*/ 3747087cfbeSBarry Smith PetscErrorCode MatCompositeAddMat(Mat mat,Mat smat) 375793850ffSBarry Smith { 376793850ffSBarry Smith PetscErrorCode ierr; 377793850ffSBarry Smith 378793850ffSBarry Smith PetscFunctionBegin; 3790700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3800700a824SBarry Smith PetscValidHeaderSpecific(smat,MAT_CLASSID,2); 381d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeAddMat_C",(Mat,Mat),(mat,smat));CHKERRQ(ierr); 382d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 383d7f81bf2SJakub Kruzik } 384793850ffSBarry Smith 385d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeSetType_Composite(Mat mat,MatCompositeType type) 386d7f81bf2SJakub Kruzik { 387d7f81bf2SJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 388d7f81bf2SJakub Kruzik 389d7f81bf2SJakub Kruzik PetscFunctionBegin; 390ced1ac25SJakub Kruzik b->type = type; 391d7f81bf2SJakub Kruzik if (type == MAT_COMPOSITE_MULTIPLICATIVE) { 392d7f81bf2SJakub Kruzik mat->ops->getdiagonal = 0; 393d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite_Multiplicative; 394d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite_Multiplicative; 395d7f81bf2SJakub Kruzik } else { 396d7f81bf2SJakub Kruzik mat->ops->getdiagonal = MatGetDiagonal_Composite; 397d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite; 398d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite; 399793850ffSBarry Smith } 4006d7c1e57SBarry Smith PetscFunctionReturn(0); 4016d7c1e57SBarry Smith } 4026d7c1e57SBarry Smith 4032c0821f3SBarry Smith /*@ 4048bd739bdSJakub Kruzik MatCompositeSetType - Indicates if the matrix is defined as the sum of a set of matrices or the product. 4056d7c1e57SBarry Smith 4066d7c1e57SBarry Smith Collective on MPI_Comm 4076d7c1e57SBarry Smith 4086d7c1e57SBarry Smith Input Parameters: 4096d7c1e57SBarry Smith . mat - the composite matrix 4106d7c1e57SBarry Smith 4116d7c1e57SBarry Smith Level: advanced 4126d7c1e57SBarry Smith 4136dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeGetType(), MATCOMPOSITE 4146d7c1e57SBarry Smith 4156d7c1e57SBarry Smith @*/ 4167087cfbeSBarry Smith PetscErrorCode MatCompositeSetType(Mat mat,MatCompositeType type) 4176d7c1e57SBarry Smith { 4186d7c1e57SBarry Smith PetscErrorCode ierr; 4196d7c1e57SBarry Smith 4206d7c1e57SBarry Smith PetscFunctionBegin; 421d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 422d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetType_C",(Mat,MatCompositeType),(mat,type));CHKERRQ(ierr); 423793850ffSBarry Smith PetscFunctionReturn(0); 424793850ffSBarry Smith } 425793850ffSBarry Smith 4266dbc55e5SJakub Kruzik static PetscErrorCode MatCompositeGetType_Composite(Mat mat,MatCompositeType *type) 4276dbc55e5SJakub Kruzik { 4286dbc55e5SJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 4296dbc55e5SJakub Kruzik 4306dbc55e5SJakub Kruzik PetscFunctionBegin; 4316dbc55e5SJakub Kruzik *type = b->type; 4326dbc55e5SJakub Kruzik PetscFunctionReturn(0); 4336dbc55e5SJakub Kruzik } 4346dbc55e5SJakub Kruzik 4356dbc55e5SJakub Kruzik /*@ 4366dbc55e5SJakub Kruzik MatCompositeGetType - Returns type of composite. 4376dbc55e5SJakub Kruzik 4386dbc55e5SJakub Kruzik Not Collective 4396dbc55e5SJakub Kruzik 4406dbc55e5SJakub Kruzik Input Parameter: 4416dbc55e5SJakub Kruzik . mat - the composite matrix 4426dbc55e5SJakub Kruzik 4436dbc55e5SJakub Kruzik Output Parameter: 4446dbc55e5SJakub Kruzik . type - type of composite 4456dbc55e5SJakub Kruzik 4466dbc55e5SJakub Kruzik Level: advanced 4476dbc55e5SJakub Kruzik 4486dbc55e5SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeSetType(), MATCOMPOSITE 4496dbc55e5SJakub Kruzik 4506dbc55e5SJakub Kruzik @*/ 4516dbc55e5SJakub Kruzik PetscErrorCode MatCompositeGetType(Mat mat,MatCompositeType *type) 4526dbc55e5SJakub Kruzik { 4536dbc55e5SJakub Kruzik PetscErrorCode ierr; 4546dbc55e5SJakub Kruzik 4556dbc55e5SJakub Kruzik PetscFunctionBegin; 4566dbc55e5SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4576dbc55e5SJakub Kruzik PetscValidPointer(type,2); 4586dbc55e5SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetType_C",(Mat,MatCompositeType*),(mat,type));CHKERRQ(ierr); 4596dbc55e5SJakub Kruzik PetscFunctionReturn(0); 4606dbc55e5SJakub Kruzik } 4616dbc55e5SJakub Kruzik 462d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeMerge_Composite(Mat mat) 463b52f573bSBarry Smith { 464b52f573bSBarry Smith Mat_Composite *shell = (Mat_Composite*)mat->data; 4656d7c1e57SBarry Smith Mat_CompositeLink next = shell->head, prev = shell->tail; 466b52f573bSBarry Smith PetscErrorCode ierr; 4676d7c1e57SBarry Smith Mat tmat,newmat; 4681ba60692SJed Brown Vec left,right; 4691ba60692SJed Brown PetscScalar scale; 470b52f573bSBarry Smith 471b52f573bSBarry Smith PetscFunctionBegin; 472e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 473b52f573bSBarry Smith 474b52f573bSBarry Smith PetscFunctionBegin; 4756d7c1e57SBarry Smith if (shell->type == MAT_COMPOSITE_ADDITIVE) { 476b52f573bSBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 477b52f573bSBarry Smith while ((next = next->next)) { 478b52f573bSBarry Smith ierr = MatAXPY(tmat,1.0,next->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 479b52f573bSBarry Smith } 4806d7c1e57SBarry Smith } else { 48104d534ceSJakub Kruzik if (shell->mergefromright) { 4826d7c1e57SBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 483b6cfcaf5SJakub Kruzik while ((next = next->next)) { 484b6cfcaf5SJakub Kruzik ierr = MatMatMult(next->mat,tmat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 4856bf464f9SBarry Smith ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4866d7c1e57SBarry Smith tmat = newmat; 4876d7c1e57SBarry Smith } 48804d534ceSJakub Kruzik } else { 48904d534ceSJakub Kruzik ierr = MatDuplicate(prev->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 49004d534ceSJakub Kruzik while ((prev = prev->prev)) { 49104d534ceSJakub Kruzik ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 49204d534ceSJakub Kruzik ierr = MatDestroy(&tmat);CHKERRQ(ierr); 49304d534ceSJakub Kruzik tmat = newmat; 49404d534ceSJakub Kruzik } 49504d534ceSJakub Kruzik } 4966d7c1e57SBarry Smith } 4971ba60692SJed Brown 4981ba60692SJed Brown scale = shell->scale; 4991ba60692SJed Brown if ((left = shell->left)) {ierr = PetscObjectReference((PetscObject)left);CHKERRQ(ierr);} 5001ba60692SJed Brown if ((right = shell->right)) {ierr = PetscObjectReference((PetscObject)right);CHKERRQ(ierr);} 5011ba60692SJed Brown 50228be2f97SBarry Smith ierr = MatHeaderReplace(mat,&tmat);CHKERRQ(ierr); 5031ba60692SJed Brown 5041ba60692SJed Brown ierr = MatDiagonalScale(mat,left,right);CHKERRQ(ierr); 5051ba60692SJed Brown ierr = MatScale(mat,scale);CHKERRQ(ierr); 5061ba60692SJed Brown ierr = VecDestroy(&left);CHKERRQ(ierr); 5071ba60692SJed Brown ierr = VecDestroy(&right);CHKERRQ(ierr); 508b52f573bSBarry Smith PetscFunctionReturn(0); 509b52f573bSBarry Smith } 5106a7ede75SJakub Kruzik 5116a7ede75SJakub Kruzik /*@ 512d7f81bf2SJakub Kruzik MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix 5138bd739bdSJakub Kruzik by summing or computing the product of all the matrices inside the composite matrix. 514d7f81bf2SJakub Kruzik 515d7f81bf2SJakub Kruzik Collective on MPI_Comm 516d7f81bf2SJakub Kruzik 517d7f81bf2SJakub Kruzik Input Parameters: 518d7f81bf2SJakub Kruzik . mat - the composite matrix 519d7f81bf2SJakub Kruzik 520d7f81bf2SJakub Kruzik 521d7f81bf2SJakub Kruzik Options Database: 522d7f81bf2SJakub Kruzik . -mat_composite_merge (you must call MatAssemblyBegin()/MatAssemblyEnd() to have this checked) 523d7f81bf2SJakub Kruzik 524d7f81bf2SJakub Kruzik Level: advanced 525d7f81bf2SJakub Kruzik 526d7f81bf2SJakub Kruzik Notes: 527d7f81bf2SJakub Kruzik The MatType of the resulting matrix will be the same as the MatType of the FIRST 528d7f81bf2SJakub Kruzik matrix in the composite matrix. 529d7f81bf2SJakub Kruzik 53004d534ceSJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeSetMergeFromRight(), MATCOMPOSITE 531d7f81bf2SJakub Kruzik 532d7f81bf2SJakub Kruzik @*/ 533d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeMerge(Mat mat) 534d7f81bf2SJakub Kruzik { 535d7f81bf2SJakub Kruzik PetscErrorCode ierr; 536d7f81bf2SJakub Kruzik 537d7f81bf2SJakub Kruzik PetscFunctionBegin; 538d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 539d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeMerge_C",(Mat),(mat));CHKERRQ(ierr); 540d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 541d7f81bf2SJakub Kruzik } 542d7f81bf2SJakub Kruzik 543*6d0add67SJakub Kruzik static PetscErrorCode MatCompositeGetNumberMat_Composite(Mat mat,PetscInt *nmat) 544d7f81bf2SJakub Kruzik { 545d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 546d7f81bf2SJakub Kruzik 547d7f81bf2SJakub Kruzik PetscFunctionBegin; 548d7f81bf2SJakub Kruzik *nmat = shell->nmat; 549d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 550d7f81bf2SJakub Kruzik } 551d7f81bf2SJakub Kruzik 552d7f81bf2SJakub Kruzik /*@ 553*6d0add67SJakub Kruzik MatCompositeGetNumberMat - Returns the number of matrices in the composite matrix. 5546a7ede75SJakub Kruzik 5556a7ede75SJakub Kruzik Not Collective 5566a7ede75SJakub Kruzik 5576a7ede75SJakub Kruzik Input Parameter: 558d7f81bf2SJakub Kruzik . mat - the composite matrix 5596a7ede75SJakub Kruzik 5606a7ede75SJakub Kruzik Output Parameter: 561*6d0add67SJakub Kruzik . nmat - number of matrices in the composite matrix 5626a7ede75SJakub Kruzik 5638b5c3584SJakub Kruzik Level: advanced 5646a7ede75SJakub Kruzik 5658bd739bdSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat(), MATCOMPOSITE 5666a7ede75SJakub Kruzik 5676a7ede75SJakub Kruzik @*/ 568*6d0add67SJakub Kruzik PetscErrorCode MatCompositeGetNumberMat(Mat mat,PetscInt *nmat) 5696a7ede75SJakub Kruzik { 570d7f81bf2SJakub Kruzik PetscErrorCode ierr; 5716a7ede75SJakub Kruzik 5726a7ede75SJakub Kruzik PetscFunctionBegin; 573d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5746a7ede75SJakub Kruzik PetscValidPointer(nmat,2); 575*6d0add67SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetNumberMat_C",(Mat,PetscInt*),(mat,nmat));CHKERRQ(ierr); 576d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 577d7f81bf2SJakub Kruzik } 578d7f81bf2SJakub Kruzik 579d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetMat_Composite(Mat mat,PetscInt i,Mat *Ai) 580d7f81bf2SJakub Kruzik { 581d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 582d7f81bf2SJakub Kruzik Mat_CompositeLink ilink; 583d7f81bf2SJakub Kruzik PetscInt k; 584d7f81bf2SJakub Kruzik 585d7f81bf2SJakub Kruzik PetscFunctionBegin; 586d7f81bf2SJakub Kruzik if (i >= shell->nmat) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"index out of range: %d >= %d",i,shell->nmat); 587d7f81bf2SJakub Kruzik ilink = shell->head; 588d7f81bf2SJakub Kruzik for (k=0; k<i; k++) { 589d7f81bf2SJakub Kruzik ilink = ilink->next; 590d7f81bf2SJakub Kruzik } 591d7f81bf2SJakub Kruzik *Ai = ilink->mat; 5926a7ede75SJakub Kruzik PetscFunctionReturn(0); 5936a7ede75SJakub Kruzik } 5946a7ede75SJakub Kruzik 5958b5c3584SJakub Kruzik /*@ 5968bd739bdSJakub Kruzik MatCompositeGetMat - Returns the ith matrix from the composite matrix. 5978b5c3584SJakub Kruzik 5988b5c3584SJakub Kruzik Logically Collective on Mat 5998b5c3584SJakub Kruzik 6008b5c3584SJakub Kruzik Input Parameter: 601d7f81bf2SJakub Kruzik + mat - the composite matrix 6028b5c3584SJakub Kruzik - i - the number of requested matrix 6038b5c3584SJakub Kruzik 6048b5c3584SJakub Kruzik Output Parameter: 6058b5c3584SJakub Kruzik . Ai - ith matrix in composite 6068b5c3584SJakub Kruzik 6078b5c3584SJakub Kruzik Level: advanced 6088b5c3584SJakub Kruzik 609*6d0add67SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetNumberMat(), MatCompositeAddMat(), MATCOMPOSITE 6108b5c3584SJakub Kruzik 6118b5c3584SJakub Kruzik @*/ 612d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetMat(Mat mat,PetscInt i,Mat *Ai) 6138b5c3584SJakub Kruzik { 614d7f81bf2SJakub Kruzik PetscErrorCode ierr; 6158b5c3584SJakub Kruzik 6168b5c3584SJakub Kruzik PetscFunctionBegin; 617d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 618d7f81bf2SJakub Kruzik PetscValidLogicalCollectiveInt(mat,i,2); 6198b5c3584SJakub Kruzik PetscValidPointer(Ai,3); 620d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetMat_C",(Mat,PetscInt,Mat*),(mat,i,Ai));CHKERRQ(ierr); 6218b5c3584SJakub Kruzik PetscFunctionReturn(0); 6228b5c3584SJakub Kruzik } 6238b5c3584SJakub Kruzik 62404d534ceSJakub Kruzik static PetscErrorCode MatCompositeSetMergeFromRight_Composite(Mat mat,PetscBool flg) 62504d534ceSJakub Kruzik { 62604d534ceSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 62704d534ceSJakub Kruzik 62804d534ceSJakub Kruzik PetscFunctionBegin; 62904d534ceSJakub Kruzik shell->mergefromright = flg; 63004d534ceSJakub Kruzik PetscFunctionReturn(0); 63104d534ceSJakub Kruzik } 63204d534ceSJakub Kruzik 63304d534ceSJakub Kruzik /*@ 63404d534ceSJakub Kruzik MatCompositeSetMergeFromRight - Sets MatCompositeMerge() to start from right. 63504d534ceSJakub Kruzik 63604d534ceSJakub Kruzik Logically Collective on Mat 63704d534ceSJakub Kruzik 63804d534ceSJakub Kruzik Input Parameter: 63904d534ceSJakub Kruzik + mat - the composite matrix 64004d534ceSJakub Kruzik - flg - if true (default) the merge starts with the first added matrix (mat[0]) 64104d534ceSJakub Kruzik 64204d534ceSJakub Kruzik Level: advanced 64304d534ceSJakub Kruzik 6448bd739bdSJakub Kruzik Notes: 6458bd739bdSJakub Kruzik Has an effect only if the composite matrix is multiplicative. 6468bd739bdSJakub Kruzik 6478bd739bdSJakub Kruzik The resulting matrix is the same regardles of the flg. Only the order of operation is changed. 6488bd739bdSJakub Kruzik If flg is true the order of the merge is mat[nmat-1]*(mat[nmat-2]*(...*(mat[1]*mat[0]))) 6498bd739bdSJakub Kruzik otherwise the order is (((mat[nmat-1]*mat[nmat-2])*mat[nmat-3])*...)*mat[0]. 6508bd739bdSJakub Kruzik 6518bd739bdSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeMerge(), MATCOMPOSITE 65204d534ceSJakub Kruzik 65304d534ceSJakub Kruzik @*/ 65404d534ceSJakub Kruzik PetscErrorCode MatCompositeSetMergeFromRight(Mat mat,PetscBool flg) 65504d534ceSJakub Kruzik { 65604d534ceSJakub Kruzik PetscErrorCode ierr; 65704d534ceSJakub Kruzik 65804d534ceSJakub Kruzik PetscFunctionBegin; 65904d534ceSJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 66004d534ceSJakub Kruzik PetscValidLogicalCollectiveBool(mat,flg,2); 66104d534ceSJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetMergeFromRight_C",(Mat,PetscBool),(mat,flg));CHKERRQ(ierr); 66204d534ceSJakub Kruzik PetscFunctionReturn(0); 66304d534ceSJakub Kruzik } 66404d534ceSJakub Kruzik 66541cd0125SJakub Kruzik static struct _MatOps MatOps_Values = {0, 66641cd0125SJakub Kruzik 0, 66741cd0125SJakub Kruzik 0, 66841cd0125SJakub Kruzik MatMult_Composite, 6697bf3a71bSJakub Kruzik MatMultAdd_Composite, 67041cd0125SJakub Kruzik /* 5*/ MatMultTranspose_Composite, 6717bf3a71bSJakub Kruzik MatMultTransposeAdd_Composite, 67241cd0125SJakub Kruzik 0, 67341cd0125SJakub Kruzik 0, 67441cd0125SJakub Kruzik 0, 67541cd0125SJakub Kruzik /* 10*/ 0, 67641cd0125SJakub Kruzik 0, 67741cd0125SJakub Kruzik 0, 67841cd0125SJakub Kruzik 0, 67941cd0125SJakub Kruzik 0, 68041cd0125SJakub Kruzik /* 15*/ 0, 68141cd0125SJakub Kruzik 0, 68241cd0125SJakub Kruzik MatGetDiagonal_Composite, 68341cd0125SJakub Kruzik MatDiagonalScale_Composite, 68441cd0125SJakub Kruzik 0, 68541cd0125SJakub Kruzik /* 20*/ 0, 68641cd0125SJakub Kruzik MatAssemblyEnd_Composite, 68741cd0125SJakub Kruzik 0, 68841cd0125SJakub Kruzik 0, 68941cd0125SJakub Kruzik /* 24*/ 0, 69041cd0125SJakub Kruzik 0, 69141cd0125SJakub Kruzik 0, 69241cd0125SJakub Kruzik 0, 69341cd0125SJakub Kruzik 0, 69441cd0125SJakub Kruzik /* 29*/ 0, 69541cd0125SJakub Kruzik 0, 69641cd0125SJakub Kruzik 0, 69741cd0125SJakub Kruzik 0, 69841cd0125SJakub Kruzik 0, 69941cd0125SJakub Kruzik /* 34*/ 0, 70041cd0125SJakub Kruzik 0, 70141cd0125SJakub Kruzik 0, 70241cd0125SJakub Kruzik 0, 70341cd0125SJakub Kruzik 0, 70441cd0125SJakub Kruzik /* 39*/ 0, 70541cd0125SJakub Kruzik 0, 70641cd0125SJakub Kruzik 0, 70741cd0125SJakub Kruzik 0, 70841cd0125SJakub Kruzik 0, 70941cd0125SJakub Kruzik /* 44*/ 0, 71041cd0125SJakub Kruzik MatScale_Composite, 71141cd0125SJakub Kruzik MatShift_Basic, 71241cd0125SJakub Kruzik 0, 71341cd0125SJakub Kruzik 0, 71441cd0125SJakub Kruzik /* 49*/ 0, 71541cd0125SJakub Kruzik 0, 71641cd0125SJakub Kruzik 0, 71741cd0125SJakub Kruzik 0, 71841cd0125SJakub Kruzik 0, 71941cd0125SJakub Kruzik /* 54*/ 0, 72041cd0125SJakub Kruzik 0, 72141cd0125SJakub Kruzik 0, 72241cd0125SJakub Kruzik 0, 72341cd0125SJakub Kruzik 0, 72441cd0125SJakub Kruzik /* 59*/ 0, 72541cd0125SJakub Kruzik MatDestroy_Composite, 72641cd0125SJakub Kruzik 0, 72741cd0125SJakub Kruzik 0, 72841cd0125SJakub Kruzik 0, 72941cd0125SJakub Kruzik /* 64*/ 0, 73041cd0125SJakub Kruzik 0, 73141cd0125SJakub Kruzik 0, 73241cd0125SJakub Kruzik 0, 73341cd0125SJakub Kruzik 0, 73441cd0125SJakub Kruzik /* 69*/ 0, 73541cd0125SJakub Kruzik 0, 73641cd0125SJakub Kruzik 0, 73741cd0125SJakub Kruzik 0, 73841cd0125SJakub Kruzik 0, 73941cd0125SJakub Kruzik /* 74*/ 0, 74041cd0125SJakub Kruzik 0, 74141cd0125SJakub Kruzik 0, 74241cd0125SJakub Kruzik 0, 74341cd0125SJakub Kruzik 0, 74441cd0125SJakub Kruzik /* 79*/ 0, 74541cd0125SJakub Kruzik 0, 74641cd0125SJakub Kruzik 0, 74741cd0125SJakub Kruzik 0, 74841cd0125SJakub Kruzik 0, 74941cd0125SJakub Kruzik /* 84*/ 0, 75041cd0125SJakub Kruzik 0, 75141cd0125SJakub Kruzik 0, 75241cd0125SJakub Kruzik 0, 75341cd0125SJakub Kruzik 0, 75441cd0125SJakub Kruzik /* 89*/ 0, 75541cd0125SJakub Kruzik 0, 75641cd0125SJakub Kruzik 0, 75741cd0125SJakub Kruzik 0, 75841cd0125SJakub Kruzik 0, 75941cd0125SJakub Kruzik /* 94*/ 0, 76041cd0125SJakub Kruzik 0, 76141cd0125SJakub Kruzik 0, 76241cd0125SJakub Kruzik 0, 76341cd0125SJakub Kruzik 0, 76441cd0125SJakub Kruzik /*99*/ 0, 76541cd0125SJakub Kruzik 0, 76641cd0125SJakub Kruzik 0, 76741cd0125SJakub Kruzik 0, 76841cd0125SJakub Kruzik 0, 76941cd0125SJakub Kruzik /*104*/ 0, 77041cd0125SJakub Kruzik 0, 77141cd0125SJakub Kruzik 0, 77241cd0125SJakub Kruzik 0, 77341cd0125SJakub Kruzik 0, 77441cd0125SJakub Kruzik /*109*/ 0, 77541cd0125SJakub Kruzik 0, 77641cd0125SJakub Kruzik 0, 77741cd0125SJakub Kruzik 0, 77841cd0125SJakub Kruzik 0, 77941cd0125SJakub Kruzik /*114*/ 0, 78041cd0125SJakub Kruzik 0, 78141cd0125SJakub Kruzik 0, 78241cd0125SJakub Kruzik 0, 78341cd0125SJakub Kruzik 0, 78441cd0125SJakub Kruzik /*119*/ 0, 78541cd0125SJakub Kruzik 0, 78641cd0125SJakub Kruzik 0, 78741cd0125SJakub Kruzik 0, 78841cd0125SJakub Kruzik 0, 78941cd0125SJakub Kruzik /*124*/ 0, 79041cd0125SJakub Kruzik 0, 79141cd0125SJakub Kruzik 0, 79241cd0125SJakub Kruzik 0, 79341cd0125SJakub Kruzik 0, 79441cd0125SJakub Kruzik /*129*/ 0, 79541cd0125SJakub Kruzik 0, 79641cd0125SJakub Kruzik 0, 79741cd0125SJakub Kruzik 0, 79841cd0125SJakub Kruzik 0, 79941cd0125SJakub Kruzik /*134*/ 0, 80041cd0125SJakub Kruzik 0, 80141cd0125SJakub Kruzik 0, 80241cd0125SJakub Kruzik 0, 80341cd0125SJakub Kruzik 0, 80441cd0125SJakub Kruzik /*139*/ 0, 80541cd0125SJakub Kruzik 0, 80641cd0125SJakub Kruzik 0 80741cd0125SJakub Kruzik }; 80841cd0125SJakub Kruzik 80941cd0125SJakub Kruzik /*MC 81041cd0125SJakub Kruzik MATCOMPOSITE - A matrix defined by the sum (or product) of one or more matrices. 81141cd0125SJakub Kruzik The matrices need to have a correct size and parallel layout for the sum or product to be valid. 81241cd0125SJakub Kruzik 81341cd0125SJakub Kruzik Notes: 81441cd0125SJakub Kruzik to use the product of the matrices call MatCompositeSetType(mat,MAT_COMPOSITE_MULTIPLICATIVE); 81541cd0125SJakub Kruzik 81641cd0125SJakub Kruzik Level: advanced 81741cd0125SJakub Kruzik 818*6d0add67SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeAddMat(), MatSetType(), MatCompositeSetType(), MatCompositeGetType(), MatCompositeMerge(), MatCompositeSetMergeFromRight(), MatCompositeGetNumberMat(), MatCompositeGetMat() 81941cd0125SJakub Kruzik M*/ 82041cd0125SJakub Kruzik 82141cd0125SJakub Kruzik PETSC_EXTERN PetscErrorCode MatCreate_Composite(Mat A) 82241cd0125SJakub Kruzik { 82341cd0125SJakub Kruzik Mat_Composite *b; 82441cd0125SJakub Kruzik PetscErrorCode ierr; 82541cd0125SJakub Kruzik 82641cd0125SJakub Kruzik PetscFunctionBegin; 82741cd0125SJakub Kruzik ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 82841cd0125SJakub Kruzik A->data = (void*)b; 82941cd0125SJakub Kruzik ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 83041cd0125SJakub Kruzik 83141cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 83241cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 83341cd0125SJakub Kruzik 83441cd0125SJakub Kruzik A->assembled = PETSC_TRUE; 83541cd0125SJakub Kruzik A->preallocated = PETSC_TRUE; 83641cd0125SJakub Kruzik b->type = MAT_COMPOSITE_ADDITIVE; 83741cd0125SJakub Kruzik b->scale = 1.0; 83841cd0125SJakub Kruzik b->nmat = 0; 83904d534ceSJakub Kruzik b->mergefromright = PETSC_TRUE; 84041cd0125SJakub Kruzik 84141cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeAddMat_C",MatCompositeAddMat_Composite);CHKERRQ(ierr); 84241cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetType_C",MatCompositeSetType_Composite);CHKERRQ(ierr); 8436dbc55e5SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetType_C",MatCompositeGetType_Composite);CHKERRQ(ierr); 84441cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeMerge_C",MatCompositeMerge_Composite);CHKERRQ(ierr); 845*6d0add67SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetNumberMat_C",MatCompositeGetNumberMat_Composite);CHKERRQ(ierr); 84641cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetMat_C",MatCompositeGetMat_Composite);CHKERRQ(ierr); 84704d534ceSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetMergeFromRight_C",MatCompositeSetMergeFromRight_Composite);CHKERRQ(ierr); 84841cd0125SJakub Kruzik 84941cd0125SJakub Kruzik ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr); 85041cd0125SJakub Kruzik PetscFunctionReturn(0); 85141cd0125SJakub Kruzik } 85241cd0125SJakub Kruzik 853