1793850ffSBarry Smith 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3793850ffSBarry Smith 48c8613bfSJakub Kruzik const char *const MatCompositeMergeTypes[] = {"left","right","MatCompositeMergeType","MAT_COMPOSITE_",0}; 58c8613bfSJakub Kruzik 6793850ffSBarry Smith typedef struct _Mat_CompositeLink *Mat_CompositeLink; 7793850ffSBarry Smith struct _Mat_CompositeLink { 8793850ffSBarry Smith Mat mat; 96d7c1e57SBarry Smith Vec work; 106d7c1e57SBarry Smith Mat_CompositeLink next,prev; 11793850ffSBarry Smith }; 12793850ffSBarry Smith 13793850ffSBarry Smith typedef struct { 146d7c1e57SBarry Smith MatCompositeType type; 156d7c1e57SBarry Smith Mat_CompositeLink head,tail; 16793850ffSBarry Smith Vec work; 17e4fc5df0SBarry Smith PetscScalar scale; /* scale factor supplied with MatScale() */ 18e4fc5df0SBarry Smith Vec left,right; /* left and right diagonal scaling provided with MatDiagonalScale() */ 19e4fc5df0SBarry Smith Vec leftwork,rightwork; 206a7ede75SJakub Kruzik PetscInt nmat; 214b2558d6SJakub Kruzik PetscBool merge; 228c8613bfSJakub Kruzik MatCompositeMergeType mergetype; 233b35acafSJakub Kruzik MatStructure structure; 24793850ffSBarry Smith } Mat_Composite; 25793850ffSBarry Smith 26793850ffSBarry Smith PetscErrorCode MatDestroy_Composite(Mat mat) 27793850ffSBarry Smith { 28793850ffSBarry Smith PetscErrorCode ierr; 292c33bbaeSSatish Balay Mat_Composite *shell = (Mat_Composite*)mat->data; 306d7c1e57SBarry Smith Mat_CompositeLink next = shell->head,oldnext; 31793850ffSBarry Smith 32793850ffSBarry Smith PetscFunctionBegin; 33793850ffSBarry Smith while (next) { 346bf464f9SBarry Smith ierr = MatDestroy(&next->mat);CHKERRQ(ierr); 356d7c1e57SBarry Smith if (next->work && (!next->next || next->work != next->next->work)) { 366bf464f9SBarry Smith ierr = VecDestroy(&next->work);CHKERRQ(ierr); 376d7c1e57SBarry Smith } 386d7c1e57SBarry Smith oldnext = next; 39793850ffSBarry Smith next = next->next; 406d7c1e57SBarry Smith ierr = PetscFree(oldnext);CHKERRQ(ierr); 41793850ffSBarry Smith } 426bf464f9SBarry Smith ierr = VecDestroy(&shell->work);CHKERRQ(ierr); 436bf464f9SBarry Smith ierr = VecDestroy(&shell->left);CHKERRQ(ierr); 446bf464f9SBarry Smith ierr = VecDestroy(&shell->right);CHKERRQ(ierr); 456bf464f9SBarry Smith ierr = VecDestroy(&shell->leftwork);CHKERRQ(ierr); 466bf464f9SBarry Smith ierr = VecDestroy(&shell->rightwork);CHKERRQ(ierr); 476bf464f9SBarry Smith ierr = PetscFree(mat->data);CHKERRQ(ierr); 48793850ffSBarry Smith PetscFunctionReturn(0); 49793850ffSBarry Smith } 50793850ffSBarry Smith 516d7c1e57SBarry Smith PetscErrorCode MatMult_Composite_Multiplicative(Mat A,Vec x,Vec y) 526d7c1e57SBarry Smith { 536d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 546d7c1e57SBarry Smith Mat_CompositeLink next = shell->head; 556d7c1e57SBarry Smith PetscErrorCode ierr; 566d7c1e57SBarry Smith Vec in,out; 576d7c1e57SBarry Smith 586d7c1e57SBarry Smith PetscFunctionBegin; 59e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 606d7c1e57SBarry Smith in = x; 61e4fc5df0SBarry Smith if (shell->right) { 62e4fc5df0SBarry Smith if (!shell->rightwork) { 63e4fc5df0SBarry Smith ierr = VecDuplicate(shell->right,&shell->rightwork);CHKERRQ(ierr); 64e4fc5df0SBarry Smith } 65e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->rightwork,shell->right,in);CHKERRQ(ierr); 66e4fc5df0SBarry Smith in = shell->rightwork; 67e4fc5df0SBarry Smith } 686d7c1e57SBarry Smith while (next->next) { 696d7c1e57SBarry Smith if (!next->work) { /* should reuse previous work if the same size */ 702a7a6963SBarry Smith ierr = MatCreateVecs(next->mat,NULL,&next->work);CHKERRQ(ierr); 716d7c1e57SBarry Smith } 726d7c1e57SBarry Smith out = next->work; 736d7c1e57SBarry Smith ierr = MatMult(next->mat,in,out);CHKERRQ(ierr); 746d7c1e57SBarry Smith in = out; 756d7c1e57SBarry Smith next = next->next; 766d7c1e57SBarry Smith } 776d7c1e57SBarry Smith ierr = MatMult(next->mat,in,y);CHKERRQ(ierr); 78e4fc5df0SBarry Smith if (shell->left) { 79e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->left,y);CHKERRQ(ierr); 80e4fc5df0SBarry Smith } 81e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 826d7c1e57SBarry Smith PetscFunctionReturn(0); 836d7c1e57SBarry Smith } 846d7c1e57SBarry Smith 856d7c1e57SBarry Smith PetscErrorCode MatMultTranspose_Composite_Multiplicative(Mat A,Vec x,Vec y) 866d7c1e57SBarry Smith { 876d7c1e57SBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 886d7c1e57SBarry Smith Mat_CompositeLink tail = shell->tail; 896d7c1e57SBarry Smith PetscErrorCode ierr; 906d7c1e57SBarry Smith Vec in,out; 916d7c1e57SBarry Smith 926d7c1e57SBarry Smith PetscFunctionBegin; 93e32f2f54SBarry Smith if (!tail) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 946d7c1e57SBarry Smith in = x; 95e4fc5df0SBarry Smith if (shell->left) { 96e4fc5df0SBarry Smith if (!shell->leftwork) { 97e4fc5df0SBarry Smith ierr = VecDuplicate(shell->left,&shell->leftwork);CHKERRQ(ierr); 98e4fc5df0SBarry Smith } 99e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->leftwork,shell->left,in);CHKERRQ(ierr); 100e4fc5df0SBarry Smith in = shell->leftwork; 101e4fc5df0SBarry Smith } 1026d7c1e57SBarry Smith while (tail->prev) { 1036d7c1e57SBarry Smith if (!tail->prev->work) { /* should reuse previous work if the same size */ 1042a7a6963SBarry Smith ierr = MatCreateVecs(tail->mat,NULL,&tail->prev->work);CHKERRQ(ierr); 1056d7c1e57SBarry Smith } 1066d7c1e57SBarry Smith out = tail->prev->work; 1076d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,out);CHKERRQ(ierr); 1086d7c1e57SBarry Smith in = out; 1096d7c1e57SBarry Smith tail = tail->prev; 1106d7c1e57SBarry Smith } 1116d7c1e57SBarry Smith ierr = MatMultTranspose(tail->mat,in,y);CHKERRQ(ierr); 112e4fc5df0SBarry Smith if (shell->right) { 113e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->right,y);CHKERRQ(ierr); 114e4fc5df0SBarry Smith } 115e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 1166d7c1e57SBarry Smith PetscFunctionReturn(0); 1176d7c1e57SBarry Smith } 1186d7c1e57SBarry Smith 119793850ffSBarry Smith PetscErrorCode MatMult_Composite(Mat A,Vec x,Vec y) 120793850ffSBarry Smith { 121793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 122793850ffSBarry Smith Mat_CompositeLink next = shell->head; 123793850ffSBarry Smith PetscErrorCode ierr; 124e4fc5df0SBarry Smith Vec in; 125793850ffSBarry Smith 126793850ffSBarry Smith PetscFunctionBegin; 127e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 128e4fc5df0SBarry Smith in = x; 129e4fc5df0SBarry Smith if (shell->right) { 130e4fc5df0SBarry Smith if (!shell->rightwork) { 131e4fc5df0SBarry Smith ierr = VecDuplicate(shell->right,&shell->rightwork);CHKERRQ(ierr); 132793850ffSBarry Smith } 133e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->rightwork,shell->right,in);CHKERRQ(ierr); 134e4fc5df0SBarry Smith in = shell->rightwork; 135e4fc5df0SBarry Smith } 136e4fc5df0SBarry Smith ierr = MatMult(next->mat,in,y);CHKERRQ(ierr); 137e4fc5df0SBarry Smith while ((next = next->next)) { 138e4fc5df0SBarry Smith ierr = MatMultAdd(next->mat,in,y,y);CHKERRQ(ierr); 139e4fc5df0SBarry Smith } 140e4fc5df0SBarry Smith if (shell->left) { 141e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->left,y);CHKERRQ(ierr); 142e4fc5df0SBarry Smith } 143e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 144793850ffSBarry Smith PetscFunctionReturn(0); 145793850ffSBarry Smith } 146793850ffSBarry Smith 147793850ffSBarry Smith PetscErrorCode MatMultTranspose_Composite(Mat A,Vec x,Vec y) 148793850ffSBarry Smith { 149793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 150793850ffSBarry Smith Mat_CompositeLink next = shell->head; 151793850ffSBarry Smith PetscErrorCode ierr; 152e4fc5df0SBarry Smith Vec in; 153793850ffSBarry Smith 154793850ffSBarry Smith PetscFunctionBegin; 155e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 156e4fc5df0SBarry Smith in = x; 157e4fc5df0SBarry Smith if (shell->left) { 158e4fc5df0SBarry Smith if (!shell->leftwork) { 159e4fc5df0SBarry Smith ierr = VecDuplicate(shell->left,&shell->leftwork);CHKERRQ(ierr); 160793850ffSBarry Smith } 161e4fc5df0SBarry Smith ierr = VecPointwiseMult(shell->leftwork,shell->left,in);CHKERRQ(ierr); 162e4fc5df0SBarry Smith in = shell->leftwork; 163e4fc5df0SBarry Smith } 164e4fc5df0SBarry Smith ierr = MatMultTranspose(next->mat,in,y);CHKERRQ(ierr); 165e4fc5df0SBarry Smith while ((next = next->next)) { 166e4fc5df0SBarry Smith ierr = MatMultTransposeAdd(next->mat,in,y,y);CHKERRQ(ierr); 167e4fc5df0SBarry Smith } 168e4fc5df0SBarry Smith if (shell->right) { 169e4fc5df0SBarry Smith ierr = VecPointwiseMult(y,shell->right,y);CHKERRQ(ierr); 170e4fc5df0SBarry Smith } 171e4fc5df0SBarry Smith ierr = VecScale(y,shell->scale);CHKERRQ(ierr); 172793850ffSBarry Smith PetscFunctionReturn(0); 173793850ffSBarry Smith } 174793850ffSBarry Smith 1757bf3a71bSJakub Kruzik PetscErrorCode MatMultAdd_Composite(Mat A,Vec x,Vec y,Vec z) 1767bf3a71bSJakub Kruzik { 1777bf3a71bSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)A->data; 1787bf3a71bSJakub Kruzik PetscErrorCode ierr; 1797bf3a71bSJakub Kruzik 1807bf3a71bSJakub Kruzik PetscFunctionBegin; 1817bf3a71bSJakub Kruzik if (y != z) { 1827bf3a71bSJakub Kruzik ierr = MatMult(A,x,z);CHKERRQ(ierr); 1837bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,y);CHKERRQ(ierr); 1847bf3a71bSJakub Kruzik } else { 1857bf3a71bSJakub Kruzik if (!shell->leftwork) { 1867bf3a71bSJakub Kruzik ierr = VecDuplicate(z,&shell->leftwork);CHKERRQ(ierr); 1877bf3a71bSJakub Kruzik } 1887bf3a71bSJakub Kruzik ierr = MatMult(A,x,shell->leftwork);CHKERRQ(ierr); 1897bf3a71bSJakub Kruzik ierr = VecCopy(y,z);CHKERRQ(ierr); 1907bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,shell->leftwork);CHKERRQ(ierr); 1917bf3a71bSJakub Kruzik } 1927bf3a71bSJakub Kruzik PetscFunctionReturn(0); 1937bf3a71bSJakub Kruzik } 1947bf3a71bSJakub Kruzik 1957bf3a71bSJakub Kruzik PetscErrorCode MatMultTransposeAdd_Composite(Mat A,Vec x,Vec y, Vec z) 1967bf3a71bSJakub Kruzik { 1977bf3a71bSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)A->data; 1987bf3a71bSJakub Kruzik PetscErrorCode ierr; 1997bf3a71bSJakub Kruzik 2007bf3a71bSJakub Kruzik PetscFunctionBegin; 2017bf3a71bSJakub Kruzik if (y != z) { 2027bf3a71bSJakub Kruzik ierr = MatMultTranspose(A,x,z);CHKERRQ(ierr); 2037bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,y);CHKERRQ(ierr); 2047bf3a71bSJakub Kruzik } else { 2057bf3a71bSJakub Kruzik if (!shell->rightwork) { 2067bf3a71bSJakub Kruzik ierr = VecDuplicate(z,&shell->rightwork);CHKERRQ(ierr); 2077bf3a71bSJakub Kruzik } 2087bf3a71bSJakub Kruzik ierr = MatMultTranspose(A,x,shell->rightwork);CHKERRQ(ierr); 2097bf3a71bSJakub Kruzik ierr = VecCopy(y,z);CHKERRQ(ierr); 2107bf3a71bSJakub Kruzik ierr = VecAXPY(z,1.0,shell->rightwork);CHKERRQ(ierr); 2117bf3a71bSJakub Kruzik } 2127bf3a71bSJakub Kruzik PetscFunctionReturn(0); 2137bf3a71bSJakub Kruzik } 2147bf3a71bSJakub Kruzik 215793850ffSBarry Smith PetscErrorCode MatGetDiagonal_Composite(Mat A,Vec v) 216793850ffSBarry Smith { 217793850ffSBarry Smith Mat_Composite *shell = (Mat_Composite*)A->data; 218793850ffSBarry Smith Mat_CompositeLink next = shell->head; 219793850ffSBarry Smith PetscErrorCode ierr; 220793850ffSBarry Smith 221793850ffSBarry Smith PetscFunctionBegin; 222e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 223e32f2f54SBarry Smith if (shell->right || shell->left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get diagonal if left or right scaling"); 224e4fc5df0SBarry Smith 225793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,v);CHKERRQ(ierr); 226793850ffSBarry Smith if (next->next && !shell->work) { 227793850ffSBarry Smith ierr = VecDuplicate(v,&shell->work);CHKERRQ(ierr); 228793850ffSBarry Smith } 229793850ffSBarry Smith while ((next = next->next)) { 230793850ffSBarry Smith ierr = MatGetDiagonal(next->mat,shell->work);CHKERRQ(ierr); 231793850ffSBarry Smith ierr = VecAXPY(v,1.0,shell->work);CHKERRQ(ierr); 232793850ffSBarry Smith } 233e4fc5df0SBarry Smith ierr = VecScale(v,shell->scale);CHKERRQ(ierr); 234793850ffSBarry Smith PetscFunctionReturn(0); 235793850ffSBarry Smith } 236793850ffSBarry Smith 237793850ffSBarry Smith PetscErrorCode MatAssemblyEnd_Composite(Mat Y,MatAssemblyType t) 238793850ffSBarry Smith { 2394b2558d6SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)Y->data; 240b52f573bSBarry Smith PetscErrorCode ierr; 241b52f573bSBarry Smith 242793850ffSBarry Smith PetscFunctionBegin; 2434b2558d6SJakub Kruzik if (shell->merge) { 244b52f573bSBarry Smith ierr = MatCompositeMerge(Y);CHKERRQ(ierr); 245b52f573bSBarry Smith } 246793850ffSBarry Smith PetscFunctionReturn(0); 247793850ffSBarry Smith } 248793850ffSBarry Smith 249e4fc5df0SBarry Smith PetscErrorCode MatScale_Composite(Mat inA,PetscScalar alpha) 250e4fc5df0SBarry Smith { 251e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 252e4fc5df0SBarry Smith 253e4fc5df0SBarry Smith PetscFunctionBegin; 254321429dbSBarry Smith a->scale *= alpha; 255e4fc5df0SBarry Smith PetscFunctionReturn(0); 256e4fc5df0SBarry Smith } 257e4fc5df0SBarry Smith 258e4fc5df0SBarry Smith PetscErrorCode MatDiagonalScale_Composite(Mat inA,Vec left,Vec right) 259e4fc5df0SBarry Smith { 260e4fc5df0SBarry Smith Mat_Composite *a = (Mat_Composite*)inA->data; 261e4fc5df0SBarry Smith PetscErrorCode ierr; 262e4fc5df0SBarry Smith 263e4fc5df0SBarry Smith PetscFunctionBegin; 264e4fc5df0SBarry Smith if (left) { 265321429dbSBarry Smith if (!a->left) { 266e4fc5df0SBarry Smith ierr = VecDuplicate(left,&a->left);CHKERRQ(ierr); 267e4fc5df0SBarry Smith ierr = VecCopy(left,a->left);CHKERRQ(ierr); 268321429dbSBarry Smith } else { 269321429dbSBarry Smith ierr = VecPointwiseMult(a->left,left,a->left);CHKERRQ(ierr); 270321429dbSBarry Smith } 271e4fc5df0SBarry Smith } 272e4fc5df0SBarry Smith if (right) { 273321429dbSBarry Smith if (!a->right) { 274e4fc5df0SBarry Smith ierr = VecDuplicate(right,&a->right);CHKERRQ(ierr); 275e4fc5df0SBarry Smith ierr = VecCopy(right,a->right);CHKERRQ(ierr); 276321429dbSBarry Smith } else { 277321429dbSBarry Smith ierr = VecPointwiseMult(a->right,right,a->right);CHKERRQ(ierr); 278321429dbSBarry Smith } 279e4fc5df0SBarry Smith } 280e4fc5df0SBarry Smith PetscFunctionReturn(0); 281e4fc5df0SBarry Smith } 282793850ffSBarry Smith 2834b2558d6SJakub Kruzik PetscErrorCode MatSetFromOptions_Composite(PetscOptionItems *PetscOptionsObject,Mat A) 2844b2558d6SJakub Kruzik { 2854b2558d6SJakub Kruzik Mat_Composite *a = (Mat_Composite*)A->data; 2864b2558d6SJakub Kruzik PetscErrorCode ierr; 2874b2558d6SJakub Kruzik 2884b2558d6SJakub Kruzik PetscFunctionBegin; 2894b2558d6SJakub Kruzik ierr = PetscOptionsHead(PetscOptionsObject,"MATCOMPOSITE options");CHKERRQ(ierr); 2904b2558d6SJakub Kruzik ierr = PetscOptionsBool("-mat_composite_merge","Merge at MatAssemblyEnd","MatCompositeMerge",a->merge,&a->merge,NULL);CHKERRQ(ierr); 2918c8613bfSJakub Kruzik ierr = PetscOptionsEnum("-mat_composite_merge_type","Set composite merge direction","MatCompositeSetMergeType",MatCompositeMergeTypes,(PetscEnum)a->mergetype,(PetscEnum*)&a->mergetype,NULL);CHKERRQ(ierr); 2924b2558d6SJakub Kruzik ierr = PetscOptionsTail();CHKERRQ(ierr); 2934b2558d6SJakub Kruzik PetscFunctionReturn(0); 2944b2558d6SJakub Kruzik } 2954b2558d6SJakub Kruzik 2962c0821f3SBarry Smith /*@ 2978bd739bdSJakub Kruzik MatCreateComposite - Creates a matrix as the sum or product of one or more matrices 298793850ffSBarry Smith 299*d083f849SBarry Smith Collective 300793850ffSBarry Smith 301793850ffSBarry Smith Input Parameters: 302793850ffSBarry Smith + comm - MPI communicator 303793850ffSBarry Smith . nmat - number of matrices to put in 304793850ffSBarry Smith - mats - the matrices 305793850ffSBarry Smith 306793850ffSBarry Smith Output Parameter: 307db36af27SMatthew G. Knepley . mat - the matrix 308793850ffSBarry Smith 3094b2558d6SJakub Kruzik Options Database Keys: 3104b2558d6SJakub Kruzik + -mat_composite_merge - merge in MatAssemblyEnd() 311b28d0daaSJakub Kruzik - -mat_composite_merge_type - set merge direction 3124b2558d6SJakub Kruzik 313793850ffSBarry Smith Level: advanced 314793850ffSBarry Smith 315793850ffSBarry Smith Notes: 316793850ffSBarry Smith Alternative construction 317793850ffSBarry Smith $ MatCreate(comm,&mat); 318793850ffSBarry Smith $ MatSetSizes(mat,m,n,M,N); 319793850ffSBarry Smith $ MatSetType(mat,MATCOMPOSITE); 320793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[0]); 321793850ffSBarry Smith $ .... 322793850ffSBarry Smith $ MatCompositeAddMat(mat,mats[nmat-1]); 323b52f573bSBarry Smith $ MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); 324b52f573bSBarry Smith $ MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); 325793850ffSBarry Smith 3266d7c1e57SBarry Smith For the multiplicative form the product is mat[nmat-1]*mat[nmat-2]*....*mat[0] 3276d7c1e57SBarry Smith 3286dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCompositeGetMat(), MatCompositeMerge(), MatCompositeSetType(), MATCOMPOSITE 329793850ffSBarry Smith 330793850ffSBarry Smith @*/ 3317087cfbeSBarry Smith PetscErrorCode MatCreateComposite(MPI_Comm comm,PetscInt nmat,const Mat *mats,Mat *mat) 332793850ffSBarry Smith { 333793850ffSBarry Smith PetscErrorCode ierr; 334793850ffSBarry Smith PetscInt m,n,M,N,i; 335793850ffSBarry Smith 336793850ffSBarry Smith PetscFunctionBegin; 337e32f2f54SBarry Smith if (nmat < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in at least one matrix"); 338f3f84630SBarry Smith PetscValidPointer(mat,3); 339793850ffSBarry Smith 340c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[0],PETSC_IGNORE,&n);CHKERRQ(ierr); 341c4f13f43SJakub Kruzik ierr = MatGetLocalSize(mats[nmat-1],&m,PETSC_IGNORE);CHKERRQ(ierr); 342c4f13f43SJakub Kruzik ierr = MatGetSize(mats[0],PETSC_IGNORE,&N);CHKERRQ(ierr); 343c4f13f43SJakub Kruzik ierr = MatGetSize(mats[nmat-1],&M,PETSC_IGNORE);CHKERRQ(ierr); 344793850ffSBarry Smith ierr = MatCreate(comm,mat);CHKERRQ(ierr); 345793850ffSBarry Smith ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); 346793850ffSBarry Smith ierr = MatSetType(*mat,MATCOMPOSITE);CHKERRQ(ierr); 347793850ffSBarry Smith for (i=0; i<nmat; i++) { 348793850ffSBarry Smith ierr = MatCompositeAddMat(*mat,mats[i]);CHKERRQ(ierr); 349793850ffSBarry Smith } 350b52f573bSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 351b52f573bSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 352793850ffSBarry Smith PetscFunctionReturn(0); 353793850ffSBarry Smith } 354793850ffSBarry Smith 355d7f81bf2SJakub Kruzik 356d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeAddMat_Composite(Mat mat,Mat smat) 357d7f81bf2SJakub Kruzik { 358d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 359d7f81bf2SJakub Kruzik Mat_CompositeLink ilink,next = shell->head; 360d7f81bf2SJakub Kruzik PetscErrorCode ierr; 361d7f81bf2SJakub Kruzik 362d7f81bf2SJakub Kruzik PetscFunctionBegin; 363d7f81bf2SJakub Kruzik ierr = PetscNewLog(mat,&ilink);CHKERRQ(ierr); 364d7f81bf2SJakub Kruzik ilink->next = 0; 365d7f81bf2SJakub Kruzik ierr = PetscObjectReference((PetscObject)smat);CHKERRQ(ierr); 366d7f81bf2SJakub Kruzik ilink->mat = smat; 367d7f81bf2SJakub Kruzik 368d7f81bf2SJakub Kruzik if (!next) shell->head = ilink; 369d7f81bf2SJakub Kruzik else { 370d7f81bf2SJakub Kruzik while (next->next) { 371d7f81bf2SJakub Kruzik next = next->next; 372d7f81bf2SJakub Kruzik } 373d7f81bf2SJakub Kruzik next->next = ilink; 374d7f81bf2SJakub Kruzik ilink->prev = next; 375d7f81bf2SJakub Kruzik } 376d7f81bf2SJakub Kruzik shell->tail = ilink; 377d7f81bf2SJakub Kruzik shell->nmat += 1; 378d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 379d7f81bf2SJakub Kruzik } 380d7f81bf2SJakub Kruzik 381793850ffSBarry Smith /*@ 3828bd739bdSJakub Kruzik MatCompositeAddMat - Add another matrix to a composite matrix. 383793850ffSBarry Smith 384793850ffSBarry Smith Collective on Mat 385793850ffSBarry Smith 386793850ffSBarry Smith Input Parameters: 387793850ffSBarry Smith + mat - the composite matrix 388793850ffSBarry Smith - smat - the partial matrix 389793850ffSBarry Smith 390793850ffSBarry Smith Level: advanced 391793850ffSBarry Smith 3928bd739bdSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat(), MATCOMPOSITE 393793850ffSBarry Smith @*/ 3947087cfbeSBarry Smith PetscErrorCode MatCompositeAddMat(Mat mat,Mat smat) 395793850ffSBarry Smith { 396793850ffSBarry Smith PetscErrorCode ierr; 397793850ffSBarry Smith 398793850ffSBarry Smith PetscFunctionBegin; 3990700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4000700a824SBarry Smith PetscValidHeaderSpecific(smat,MAT_CLASSID,2); 401d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeAddMat_C",(Mat,Mat),(mat,smat));CHKERRQ(ierr); 402d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 403d7f81bf2SJakub Kruzik } 404793850ffSBarry Smith 405d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeSetType_Composite(Mat mat,MatCompositeType type) 406d7f81bf2SJakub Kruzik { 407d7f81bf2SJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 408d7f81bf2SJakub Kruzik 409d7f81bf2SJakub Kruzik PetscFunctionBegin; 410ced1ac25SJakub Kruzik b->type = type; 411d7f81bf2SJakub Kruzik if (type == MAT_COMPOSITE_MULTIPLICATIVE) { 412d7f81bf2SJakub Kruzik mat->ops->getdiagonal = 0; 413d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite_Multiplicative; 414d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite_Multiplicative; 415d7f81bf2SJakub Kruzik } else { 416d7f81bf2SJakub Kruzik mat->ops->getdiagonal = MatGetDiagonal_Composite; 417d7f81bf2SJakub Kruzik mat->ops->mult = MatMult_Composite; 418d7f81bf2SJakub Kruzik mat->ops->multtranspose = MatMultTranspose_Composite; 419793850ffSBarry Smith } 4206d7c1e57SBarry Smith PetscFunctionReturn(0); 4216d7c1e57SBarry Smith } 4226d7c1e57SBarry Smith 4232c0821f3SBarry Smith /*@ 4248bd739bdSJakub Kruzik MatCompositeSetType - Indicates if the matrix is defined as the sum of a set of matrices or the product. 4256d7c1e57SBarry Smith 426b2b245abSJakub Kruzik Logically Collective on Mat 4276d7c1e57SBarry Smith 4286d7c1e57SBarry Smith Input Parameters: 4296d7c1e57SBarry Smith . mat - the composite matrix 4306d7c1e57SBarry Smith 4316d7c1e57SBarry Smith Level: advanced 4326d7c1e57SBarry Smith 4336dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeGetType(), MATCOMPOSITE 4346d7c1e57SBarry Smith 4356d7c1e57SBarry Smith @*/ 4367087cfbeSBarry Smith PetscErrorCode MatCompositeSetType(Mat mat,MatCompositeType type) 4376d7c1e57SBarry Smith { 4386d7c1e57SBarry Smith PetscErrorCode ierr; 4396d7c1e57SBarry Smith 4406d7c1e57SBarry Smith PetscFunctionBegin; 441d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 442b2b245abSJakub Kruzik PetscValidLogicalCollectiveEnum(mat,type,2); 443d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetType_C",(Mat,MatCompositeType),(mat,type));CHKERRQ(ierr); 444793850ffSBarry Smith PetscFunctionReturn(0); 445793850ffSBarry Smith } 446793850ffSBarry Smith 4476dbc55e5SJakub Kruzik static PetscErrorCode MatCompositeGetType_Composite(Mat mat,MatCompositeType *type) 4486dbc55e5SJakub Kruzik { 4496dbc55e5SJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 4506dbc55e5SJakub Kruzik 4516dbc55e5SJakub Kruzik PetscFunctionBegin; 4526dbc55e5SJakub Kruzik *type = b->type; 4536dbc55e5SJakub Kruzik PetscFunctionReturn(0); 4546dbc55e5SJakub Kruzik } 4556dbc55e5SJakub Kruzik 4566dbc55e5SJakub Kruzik /*@ 4576dbc55e5SJakub Kruzik MatCompositeGetType - Returns type of composite. 4586dbc55e5SJakub Kruzik 4596dbc55e5SJakub Kruzik Not Collective 4606dbc55e5SJakub Kruzik 4616dbc55e5SJakub Kruzik Input Parameter: 4626dbc55e5SJakub Kruzik . mat - the composite matrix 4636dbc55e5SJakub Kruzik 4646dbc55e5SJakub Kruzik Output Parameter: 4656dbc55e5SJakub Kruzik . type - type of composite 4666dbc55e5SJakub Kruzik 4676dbc55e5SJakub Kruzik Level: advanced 4686dbc55e5SJakub Kruzik 4696dbc55e5SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeSetType(), MATCOMPOSITE 4706dbc55e5SJakub Kruzik 4716dbc55e5SJakub Kruzik @*/ 4726dbc55e5SJakub Kruzik PetscErrorCode MatCompositeGetType(Mat mat,MatCompositeType *type) 4736dbc55e5SJakub Kruzik { 4746dbc55e5SJakub Kruzik PetscErrorCode ierr; 4756dbc55e5SJakub Kruzik 4766dbc55e5SJakub Kruzik PetscFunctionBegin; 4776dbc55e5SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4786dbc55e5SJakub Kruzik PetscValidPointer(type,2); 4796dbc55e5SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetType_C",(Mat,MatCompositeType*),(mat,type));CHKERRQ(ierr); 4806dbc55e5SJakub Kruzik PetscFunctionReturn(0); 4816dbc55e5SJakub Kruzik } 4826dbc55e5SJakub Kruzik 4833b35acafSJakub Kruzik static PetscErrorCode MatCompositeSetMatStructure_Composite(Mat mat,MatStructure str) 4843b35acafSJakub Kruzik { 4853b35acafSJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 4863b35acafSJakub Kruzik 4873b35acafSJakub Kruzik PetscFunctionBegin; 4883b35acafSJakub Kruzik b->structure = str; 4893b35acafSJakub Kruzik PetscFunctionReturn(0); 4903b35acafSJakub Kruzik } 4913b35acafSJakub Kruzik 4923b35acafSJakub Kruzik /*@ 4933b35acafSJakub Kruzik MatCompositeSetMatStructure - Indicates structure of matrices in the composite matrix. 4943b35acafSJakub Kruzik 4953b35acafSJakub Kruzik Not Collective 4963b35acafSJakub Kruzik 4973b35acafSJakub Kruzik Input Parameters: 4983b35acafSJakub Kruzik + mat - the composite matrix 4993b35acafSJakub Kruzik - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN (default) or SUBSET_NONZERO_PATTERN 5003b35acafSJakub Kruzik 5013b35acafSJakub Kruzik Level: advanced 5023b35acafSJakub Kruzik 5033b35acafSJakub Kruzik Notes: 5043b35acafSJakub Kruzik Information about the matrices structure is used in MatCompositeMerge() for additive composite matrix. 5053b35acafSJakub Kruzik 5063b35acafSJakub Kruzik .seealso: MatAXPY(), MatCreateComposite(), MatCompositeMerge() MatCompositeGetMatStructure(), MATCOMPOSITE 5073b35acafSJakub Kruzik 5083b35acafSJakub Kruzik @*/ 5093b35acafSJakub Kruzik PetscErrorCode MatCompositeSetMatStructure(Mat mat,MatStructure str) 5103b35acafSJakub Kruzik { 5113b35acafSJakub Kruzik PetscErrorCode ierr; 5123b35acafSJakub Kruzik 5133b35acafSJakub Kruzik PetscFunctionBegin; 5143b35acafSJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5153b35acafSJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetMatStructure_C",(Mat,MatStructure),(mat,str));CHKERRQ(ierr); 5163b35acafSJakub Kruzik PetscFunctionReturn(0); 5173b35acafSJakub Kruzik } 5183b35acafSJakub Kruzik 5193b35acafSJakub Kruzik static PetscErrorCode MatCompositeGetMatStructure_Composite(Mat mat,MatStructure *str) 5203b35acafSJakub Kruzik { 5213b35acafSJakub Kruzik Mat_Composite *b = (Mat_Composite*)mat->data; 5223b35acafSJakub Kruzik 5233b35acafSJakub Kruzik PetscFunctionBegin; 5243b35acafSJakub Kruzik *str = b->structure; 5253b35acafSJakub Kruzik PetscFunctionReturn(0); 5263b35acafSJakub Kruzik } 5273b35acafSJakub Kruzik 5283b35acafSJakub Kruzik /*@ 5293b35acafSJakub Kruzik MatCompositeGetMatStructure - Returns the structure of matrices in the composite matrix. 5303b35acafSJakub Kruzik 5313b35acafSJakub Kruzik Not Collective 5323b35acafSJakub Kruzik 5333b35acafSJakub Kruzik Input Parameter: 5343b35acafSJakub Kruzik . mat - the composite matrix 5353b35acafSJakub Kruzik 5363b35acafSJakub Kruzik Output Parameter: 5373b35acafSJakub Kruzik . str - structure of the matrices 5383b35acafSJakub Kruzik 5393b35acafSJakub Kruzik Level: advanced 5403b35acafSJakub Kruzik 5413b35acafSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeSetMatStructure(), MATCOMPOSITE 5423b35acafSJakub Kruzik 5433b35acafSJakub Kruzik @*/ 5443b35acafSJakub Kruzik PetscErrorCode MatCompositeGetMatStructure(Mat mat,MatStructure *str) 5453b35acafSJakub Kruzik { 5463b35acafSJakub Kruzik PetscErrorCode ierr; 5473b35acafSJakub Kruzik 5483b35acafSJakub Kruzik PetscFunctionBegin; 5493b35acafSJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5503b35acafSJakub Kruzik PetscValidPointer(str,2); 5513b35acafSJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetMatStructure_C",(Mat,MatStructure*),(mat,str));CHKERRQ(ierr); 5523b35acafSJakub Kruzik PetscFunctionReturn(0); 5533b35acafSJakub Kruzik } 5543b35acafSJakub Kruzik 5558c8613bfSJakub Kruzik static PetscErrorCode MatCompositeSetMergeType_Composite(Mat mat,MatCompositeMergeType type) 5568c8613bfSJakub Kruzik { 5578c8613bfSJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 5588c8613bfSJakub Kruzik 5598c8613bfSJakub Kruzik PetscFunctionBegin; 5608c8613bfSJakub Kruzik shell->mergetype = type; 5618c8613bfSJakub Kruzik PetscFunctionReturn(0); 5628c8613bfSJakub Kruzik } 5638c8613bfSJakub Kruzik 5648c8613bfSJakub Kruzik /*@ 5658c8613bfSJakub Kruzik MatCompositeSetMergeType - Sets order of MatCompositeMerge(). 5668c8613bfSJakub Kruzik 5678c8613bfSJakub Kruzik Logically Collective on Mat 5688c8613bfSJakub Kruzik 5698c8613bfSJakub Kruzik Input Parameter: 5708c8613bfSJakub Kruzik + mat - the composite matrix 5718c8613bfSJakub Kruzik - type - MAT_COMPOSITE_MERGE RIGHT (default) to start merge from right with the first added matrix (mat[0]), 5728c8613bfSJakub Kruzik MAT_COMPOSITE_MERGE_LEFT to start merge from left with the last added matrix (mat[nmat-1]) 5738c8613bfSJakub Kruzik 5748c8613bfSJakub Kruzik Level: advanced 5758c8613bfSJakub Kruzik 5768c8613bfSJakub Kruzik Notes: 5778c8613bfSJakub Kruzik The resulting matrix is the same regardles of the MergeType. Only the order of operation is changed. 5788c8613bfSJakub Kruzik If set to MAT_COMPOSITE_MERGE_RIGHT the order of the merge is mat[nmat-1]*(mat[nmat-2]*(...*(mat[1]*mat[0]))) 5798c8613bfSJakub Kruzik otherwise the order is (((mat[nmat-1]*mat[nmat-2])*mat[nmat-3])*...)*mat[0]. 5808c8613bfSJakub Kruzik 5818c8613bfSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeMerge(), MATCOMPOSITE 5828c8613bfSJakub Kruzik 5838c8613bfSJakub Kruzik @*/ 5848c8613bfSJakub Kruzik PetscErrorCode MatCompositeSetMergeType(Mat mat,MatCompositeMergeType type) 5858c8613bfSJakub Kruzik { 5868c8613bfSJakub Kruzik PetscErrorCode ierr; 5878c8613bfSJakub Kruzik 5888c8613bfSJakub Kruzik PetscFunctionBegin; 5898c8613bfSJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5908c8613bfSJakub Kruzik PetscValidLogicalCollectiveEnum(mat,type,2); 5918c8613bfSJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeSetMergeType_C",(Mat,MatCompositeMergeType),(mat,type));CHKERRQ(ierr); 5928c8613bfSJakub Kruzik PetscFunctionReturn(0); 5938c8613bfSJakub Kruzik } 5948c8613bfSJakub Kruzik 595d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeMerge_Composite(Mat mat) 596b52f573bSBarry Smith { 597b52f573bSBarry Smith Mat_Composite *shell = (Mat_Composite*)mat->data; 5986d7c1e57SBarry Smith Mat_CompositeLink next = shell->head, prev = shell->tail; 599b52f573bSBarry Smith PetscErrorCode ierr; 6006d7c1e57SBarry Smith Mat tmat,newmat; 6011ba60692SJed Brown Vec left,right; 6021ba60692SJed Brown PetscScalar scale; 603b52f573bSBarry Smith 604b52f573bSBarry Smith PetscFunctionBegin; 605e32f2f54SBarry Smith if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); 606b52f573bSBarry Smith 607b52f573bSBarry Smith PetscFunctionBegin; 6086d7c1e57SBarry Smith if (shell->type == MAT_COMPOSITE_ADDITIVE) { 6098c8613bfSJakub Kruzik if (shell->mergetype == MAT_COMPOSITE_MERGE_RIGHT) { 610b52f573bSBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 611b52f573bSBarry Smith while ((next = next->next)) { 6123b35acafSJakub Kruzik ierr = MatAXPY(tmat,1.0,next->mat,shell->structure);CHKERRQ(ierr); 613b52f573bSBarry Smith } 6146d7c1e57SBarry Smith } else { 6158c8613bfSJakub Kruzik ierr = MatDuplicate(prev->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6168c8613bfSJakub Kruzik while ((prev = prev->prev)) { 6173b35acafSJakub Kruzik ierr = MatAXPY(tmat,1.0,prev->mat,shell->structure);CHKERRQ(ierr); 6188c8613bfSJakub Kruzik } 6198c8613bfSJakub Kruzik } 6208c8613bfSJakub Kruzik } else { 6218c8613bfSJakub Kruzik if (shell->mergetype == MAT_COMPOSITE_MERGE_RIGHT) { 6226d7c1e57SBarry Smith ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 623b6cfcaf5SJakub Kruzik while ((next = next->next)) { 624b6cfcaf5SJakub Kruzik ierr = MatMatMult(next->mat,tmat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 6256bf464f9SBarry Smith ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6266d7c1e57SBarry Smith tmat = newmat; 6276d7c1e57SBarry Smith } 62804d534ceSJakub Kruzik } else { 62904d534ceSJakub Kruzik ierr = MatDuplicate(prev->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); 63004d534ceSJakub Kruzik while ((prev = prev->prev)) { 63104d534ceSJakub Kruzik ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); 63204d534ceSJakub Kruzik ierr = MatDestroy(&tmat);CHKERRQ(ierr); 63304d534ceSJakub Kruzik tmat = newmat; 63404d534ceSJakub Kruzik } 63504d534ceSJakub Kruzik } 6366d7c1e57SBarry Smith } 6371ba60692SJed Brown 6381ba60692SJed Brown scale = shell->scale; 6391ba60692SJed Brown if ((left = shell->left)) {ierr = PetscObjectReference((PetscObject)left);CHKERRQ(ierr);} 6401ba60692SJed Brown if ((right = shell->right)) {ierr = PetscObjectReference((PetscObject)right);CHKERRQ(ierr);} 6411ba60692SJed Brown 64228be2f97SBarry Smith ierr = MatHeaderReplace(mat,&tmat);CHKERRQ(ierr); 6431ba60692SJed Brown 6441ba60692SJed Brown ierr = MatDiagonalScale(mat,left,right);CHKERRQ(ierr); 6451ba60692SJed Brown ierr = MatScale(mat,scale);CHKERRQ(ierr); 6461ba60692SJed Brown ierr = VecDestroy(&left);CHKERRQ(ierr); 6471ba60692SJed Brown ierr = VecDestroy(&right);CHKERRQ(ierr); 648b52f573bSBarry Smith PetscFunctionReturn(0); 649b52f573bSBarry Smith } 6506a7ede75SJakub Kruzik 6516a7ede75SJakub Kruzik /*@ 652d7f81bf2SJakub Kruzik MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix 6538bd739bdSJakub Kruzik by summing or computing the product of all the matrices inside the composite matrix. 654d7f81bf2SJakub Kruzik 655b2b245abSJakub Kruzik Collective 656d7f81bf2SJakub Kruzik 657d7f81bf2SJakub Kruzik Input Parameters: 658d7f81bf2SJakub Kruzik . mat - the composite matrix 659d7f81bf2SJakub Kruzik 660d7f81bf2SJakub Kruzik 6614b2558d6SJakub Kruzik Options Database Keys: 662b28d0daaSJakub Kruzik + -mat_composite_merge - merge in MatAssemblyEnd() 663b28d0daaSJakub Kruzik - -mat_composite_merge_type - set merge direction 664d7f81bf2SJakub Kruzik 665d7f81bf2SJakub Kruzik Level: advanced 666d7f81bf2SJakub Kruzik 667d7f81bf2SJakub Kruzik Notes: 668d7f81bf2SJakub Kruzik The MatType of the resulting matrix will be the same as the MatType of the FIRST 669d7f81bf2SJakub Kruzik matrix in the composite matrix. 670d7f81bf2SJakub Kruzik 6713b35acafSJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeSetMatStructure(), MatCompositeSetMergeType(), MATCOMPOSITE 672d7f81bf2SJakub Kruzik 673d7f81bf2SJakub Kruzik @*/ 674d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeMerge(Mat mat) 675d7f81bf2SJakub Kruzik { 676d7f81bf2SJakub Kruzik PetscErrorCode ierr; 677d7f81bf2SJakub Kruzik 678d7f81bf2SJakub Kruzik PetscFunctionBegin; 679d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 680d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeMerge_C",(Mat),(mat));CHKERRQ(ierr); 681d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 682d7f81bf2SJakub Kruzik } 683d7f81bf2SJakub Kruzik 6846d0add67SJakub Kruzik static PetscErrorCode MatCompositeGetNumberMat_Composite(Mat mat,PetscInt *nmat) 685d7f81bf2SJakub Kruzik { 686d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 687d7f81bf2SJakub Kruzik 688d7f81bf2SJakub Kruzik PetscFunctionBegin; 689d7f81bf2SJakub Kruzik *nmat = shell->nmat; 690d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 691d7f81bf2SJakub Kruzik } 692d7f81bf2SJakub Kruzik 693d7f81bf2SJakub Kruzik /*@ 6946d0add67SJakub Kruzik MatCompositeGetNumberMat - Returns the number of matrices in the composite matrix. 6956a7ede75SJakub Kruzik 6966a7ede75SJakub Kruzik Not Collective 6976a7ede75SJakub Kruzik 6986a7ede75SJakub Kruzik Input Parameter: 699d7f81bf2SJakub Kruzik . mat - the composite matrix 7006a7ede75SJakub Kruzik 7016a7ede75SJakub Kruzik Output Parameter: 7026d0add67SJakub Kruzik . nmat - number of matrices in the composite matrix 7036a7ede75SJakub Kruzik 7048b5c3584SJakub Kruzik Level: advanced 7056a7ede75SJakub Kruzik 7068bd739bdSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat(), MATCOMPOSITE 7076a7ede75SJakub Kruzik 7086a7ede75SJakub Kruzik @*/ 7096d0add67SJakub Kruzik PetscErrorCode MatCompositeGetNumberMat(Mat mat,PetscInt *nmat) 7106a7ede75SJakub Kruzik { 711d7f81bf2SJakub Kruzik PetscErrorCode ierr; 7126a7ede75SJakub Kruzik 7136a7ede75SJakub Kruzik PetscFunctionBegin; 714d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7156a7ede75SJakub Kruzik PetscValidPointer(nmat,2); 7166d0add67SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetNumberMat_C",(Mat,PetscInt*),(mat,nmat));CHKERRQ(ierr); 717d7f81bf2SJakub Kruzik PetscFunctionReturn(0); 718d7f81bf2SJakub Kruzik } 719d7f81bf2SJakub Kruzik 720d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetMat_Composite(Mat mat,PetscInt i,Mat *Ai) 721d7f81bf2SJakub Kruzik { 722d7f81bf2SJakub Kruzik Mat_Composite *shell = (Mat_Composite*)mat->data; 723d7f81bf2SJakub Kruzik Mat_CompositeLink ilink; 724d7f81bf2SJakub Kruzik PetscInt k; 725d7f81bf2SJakub Kruzik 726d7f81bf2SJakub Kruzik PetscFunctionBegin; 727d7f81bf2SJakub Kruzik if (i >= shell->nmat) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"index out of range: %d >= %d",i,shell->nmat); 728d7f81bf2SJakub Kruzik ilink = shell->head; 729d7f81bf2SJakub Kruzik for (k=0; k<i; k++) { 730d7f81bf2SJakub Kruzik ilink = ilink->next; 731d7f81bf2SJakub Kruzik } 732d7f81bf2SJakub Kruzik *Ai = ilink->mat; 7336a7ede75SJakub Kruzik PetscFunctionReturn(0); 7346a7ede75SJakub Kruzik } 7356a7ede75SJakub Kruzik 7368b5c3584SJakub Kruzik /*@ 7378bd739bdSJakub Kruzik MatCompositeGetMat - Returns the ith matrix from the composite matrix. 7388b5c3584SJakub Kruzik 7398b5c3584SJakub Kruzik Logically Collective on Mat 7408b5c3584SJakub Kruzik 7418b5c3584SJakub Kruzik Input Parameter: 742d7f81bf2SJakub Kruzik + mat - the composite matrix 7438b5c3584SJakub Kruzik - i - the number of requested matrix 7448b5c3584SJakub Kruzik 7458b5c3584SJakub Kruzik Output Parameter: 7468b5c3584SJakub Kruzik . Ai - ith matrix in composite 7478b5c3584SJakub Kruzik 7488b5c3584SJakub Kruzik Level: advanced 7498b5c3584SJakub Kruzik 7506d0add67SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetNumberMat(), MatCompositeAddMat(), MATCOMPOSITE 7518b5c3584SJakub Kruzik 7528b5c3584SJakub Kruzik @*/ 753d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetMat(Mat mat,PetscInt i,Mat *Ai) 7548b5c3584SJakub Kruzik { 755d7f81bf2SJakub Kruzik PetscErrorCode ierr; 7568b5c3584SJakub Kruzik 7578b5c3584SJakub Kruzik PetscFunctionBegin; 758d7f81bf2SJakub Kruzik PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 759d7f81bf2SJakub Kruzik PetscValidLogicalCollectiveInt(mat,i,2); 7608b5c3584SJakub Kruzik PetscValidPointer(Ai,3); 761d7f81bf2SJakub Kruzik ierr = PetscUseMethod(mat,"MatCompositeGetMat_C",(Mat,PetscInt,Mat*),(mat,i,Ai));CHKERRQ(ierr); 7628b5c3584SJakub Kruzik PetscFunctionReturn(0); 7638b5c3584SJakub Kruzik } 7648b5c3584SJakub Kruzik 76541cd0125SJakub Kruzik static struct _MatOps MatOps_Values = {0, 76641cd0125SJakub Kruzik 0, 76741cd0125SJakub Kruzik 0, 76841cd0125SJakub Kruzik MatMult_Composite, 7697bf3a71bSJakub Kruzik MatMultAdd_Composite, 77041cd0125SJakub Kruzik /* 5*/ MatMultTranspose_Composite, 7717bf3a71bSJakub Kruzik MatMultTransposeAdd_Composite, 77241cd0125SJakub Kruzik 0, 77341cd0125SJakub Kruzik 0, 77441cd0125SJakub Kruzik 0, 77541cd0125SJakub Kruzik /* 10*/ 0, 77641cd0125SJakub Kruzik 0, 77741cd0125SJakub Kruzik 0, 77841cd0125SJakub Kruzik 0, 77941cd0125SJakub Kruzik 0, 78041cd0125SJakub Kruzik /* 15*/ 0, 78141cd0125SJakub Kruzik 0, 78241cd0125SJakub Kruzik MatGetDiagonal_Composite, 78341cd0125SJakub Kruzik MatDiagonalScale_Composite, 78441cd0125SJakub Kruzik 0, 78541cd0125SJakub Kruzik /* 20*/ 0, 78641cd0125SJakub Kruzik MatAssemblyEnd_Composite, 78741cd0125SJakub Kruzik 0, 78841cd0125SJakub Kruzik 0, 78941cd0125SJakub Kruzik /* 24*/ 0, 79041cd0125SJakub Kruzik 0, 79141cd0125SJakub Kruzik 0, 79241cd0125SJakub Kruzik 0, 79341cd0125SJakub Kruzik 0, 79441cd0125SJakub Kruzik /* 29*/ 0, 79541cd0125SJakub Kruzik 0, 79641cd0125SJakub Kruzik 0, 79741cd0125SJakub Kruzik 0, 79841cd0125SJakub Kruzik 0, 79941cd0125SJakub Kruzik /* 34*/ 0, 80041cd0125SJakub Kruzik 0, 80141cd0125SJakub Kruzik 0, 80241cd0125SJakub Kruzik 0, 80341cd0125SJakub Kruzik 0, 80441cd0125SJakub Kruzik /* 39*/ 0, 80541cd0125SJakub Kruzik 0, 80641cd0125SJakub Kruzik 0, 80741cd0125SJakub Kruzik 0, 80841cd0125SJakub Kruzik 0, 80941cd0125SJakub Kruzik /* 44*/ 0, 81041cd0125SJakub Kruzik MatScale_Composite, 81141cd0125SJakub Kruzik MatShift_Basic, 81241cd0125SJakub Kruzik 0, 81341cd0125SJakub Kruzik 0, 81441cd0125SJakub Kruzik /* 49*/ 0, 81541cd0125SJakub Kruzik 0, 81641cd0125SJakub Kruzik 0, 81741cd0125SJakub Kruzik 0, 81841cd0125SJakub Kruzik 0, 81941cd0125SJakub Kruzik /* 54*/ 0, 82041cd0125SJakub Kruzik 0, 82141cd0125SJakub Kruzik 0, 82241cd0125SJakub Kruzik 0, 82341cd0125SJakub Kruzik 0, 82441cd0125SJakub Kruzik /* 59*/ 0, 82541cd0125SJakub Kruzik MatDestroy_Composite, 82641cd0125SJakub Kruzik 0, 82741cd0125SJakub Kruzik 0, 82841cd0125SJakub Kruzik 0, 82941cd0125SJakub Kruzik /* 64*/ 0, 83041cd0125SJakub Kruzik 0, 83141cd0125SJakub Kruzik 0, 83241cd0125SJakub Kruzik 0, 83341cd0125SJakub Kruzik 0, 83441cd0125SJakub Kruzik /* 69*/ 0, 83541cd0125SJakub Kruzik 0, 83641cd0125SJakub Kruzik 0, 83741cd0125SJakub Kruzik 0, 83841cd0125SJakub Kruzik 0, 83941cd0125SJakub Kruzik /* 74*/ 0, 84041cd0125SJakub Kruzik 0, 8414b2558d6SJakub Kruzik MatSetFromOptions_Composite, 84241cd0125SJakub Kruzik 0, 84341cd0125SJakub Kruzik 0, 84441cd0125SJakub Kruzik /* 79*/ 0, 84541cd0125SJakub Kruzik 0, 84641cd0125SJakub Kruzik 0, 84741cd0125SJakub Kruzik 0, 84841cd0125SJakub Kruzik 0, 84941cd0125SJakub Kruzik /* 84*/ 0, 85041cd0125SJakub Kruzik 0, 85141cd0125SJakub Kruzik 0, 85241cd0125SJakub Kruzik 0, 85341cd0125SJakub Kruzik 0, 85441cd0125SJakub Kruzik /* 89*/ 0, 85541cd0125SJakub Kruzik 0, 85641cd0125SJakub Kruzik 0, 85741cd0125SJakub Kruzik 0, 85841cd0125SJakub Kruzik 0, 85941cd0125SJakub Kruzik /* 94*/ 0, 86041cd0125SJakub Kruzik 0, 86141cd0125SJakub Kruzik 0, 86241cd0125SJakub Kruzik 0, 86341cd0125SJakub Kruzik 0, 86441cd0125SJakub Kruzik /*99*/ 0, 86541cd0125SJakub Kruzik 0, 86641cd0125SJakub Kruzik 0, 86741cd0125SJakub Kruzik 0, 86841cd0125SJakub Kruzik 0, 86941cd0125SJakub Kruzik /*104*/ 0, 87041cd0125SJakub Kruzik 0, 87141cd0125SJakub Kruzik 0, 87241cd0125SJakub Kruzik 0, 87341cd0125SJakub Kruzik 0, 87441cd0125SJakub Kruzik /*109*/ 0, 87541cd0125SJakub Kruzik 0, 87641cd0125SJakub Kruzik 0, 87741cd0125SJakub Kruzik 0, 87841cd0125SJakub Kruzik 0, 87941cd0125SJakub Kruzik /*114*/ 0, 88041cd0125SJakub Kruzik 0, 88141cd0125SJakub Kruzik 0, 88241cd0125SJakub Kruzik 0, 88341cd0125SJakub Kruzik 0, 88441cd0125SJakub Kruzik /*119*/ 0, 88541cd0125SJakub Kruzik 0, 88641cd0125SJakub Kruzik 0, 88741cd0125SJakub Kruzik 0, 88841cd0125SJakub Kruzik 0, 88941cd0125SJakub Kruzik /*124*/ 0, 89041cd0125SJakub Kruzik 0, 89141cd0125SJakub Kruzik 0, 89241cd0125SJakub Kruzik 0, 89341cd0125SJakub Kruzik 0, 89441cd0125SJakub Kruzik /*129*/ 0, 89541cd0125SJakub Kruzik 0, 89641cd0125SJakub Kruzik 0, 89741cd0125SJakub Kruzik 0, 89841cd0125SJakub Kruzik 0, 89941cd0125SJakub Kruzik /*134*/ 0, 90041cd0125SJakub Kruzik 0, 90141cd0125SJakub Kruzik 0, 90241cd0125SJakub Kruzik 0, 90341cd0125SJakub Kruzik 0, 90441cd0125SJakub Kruzik /*139*/ 0, 90541cd0125SJakub Kruzik 0, 90641cd0125SJakub Kruzik 0 90741cd0125SJakub Kruzik }; 90841cd0125SJakub Kruzik 90941cd0125SJakub Kruzik /*MC 91041cd0125SJakub Kruzik MATCOMPOSITE - A matrix defined by the sum (or product) of one or more matrices. 91141cd0125SJakub Kruzik The matrices need to have a correct size and parallel layout for the sum or product to be valid. 91241cd0125SJakub Kruzik 91341cd0125SJakub Kruzik Notes: 91441cd0125SJakub Kruzik to use the product of the matrices call MatCompositeSetType(mat,MAT_COMPOSITE_MULTIPLICATIVE); 91541cd0125SJakub Kruzik 91641cd0125SJakub Kruzik Level: advanced 91741cd0125SJakub Kruzik 918de0460efSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeAddMat(), MatSetType(), MatCompositeSetType(), MatCompositeGetType(), MatCompositeSetMatStructure(), MatCompositeGetMatStructure(), MatCompositeMerge(), MatCompositeSetMergeType(), MatCompositeGetNumberMat(), MatCompositeGetMat() 91941cd0125SJakub Kruzik M*/ 92041cd0125SJakub Kruzik 92141cd0125SJakub Kruzik PETSC_EXTERN PetscErrorCode MatCreate_Composite(Mat A) 92241cd0125SJakub Kruzik { 92341cd0125SJakub Kruzik Mat_Composite *b; 92441cd0125SJakub Kruzik PetscErrorCode ierr; 92541cd0125SJakub Kruzik 92641cd0125SJakub Kruzik PetscFunctionBegin; 92741cd0125SJakub Kruzik ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 92841cd0125SJakub Kruzik A->data = (void*)b; 92941cd0125SJakub Kruzik ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 93041cd0125SJakub Kruzik 93141cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 93241cd0125SJakub Kruzik ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 93341cd0125SJakub Kruzik 93441cd0125SJakub Kruzik A->assembled = PETSC_TRUE; 93541cd0125SJakub Kruzik A->preallocated = PETSC_TRUE; 93641cd0125SJakub Kruzik b->type = MAT_COMPOSITE_ADDITIVE; 93741cd0125SJakub Kruzik b->scale = 1.0; 93841cd0125SJakub Kruzik b->nmat = 0; 9394b2558d6SJakub Kruzik b->merge = PETSC_FALSE; 9408c8613bfSJakub Kruzik b->mergetype = MAT_COMPOSITE_MERGE_RIGHT; 9413b35acafSJakub Kruzik b->structure = DIFFERENT_NONZERO_PATTERN; 94241cd0125SJakub Kruzik 94341cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeAddMat_C",MatCompositeAddMat_Composite);CHKERRQ(ierr); 94441cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetType_C",MatCompositeSetType_Composite);CHKERRQ(ierr); 9456dbc55e5SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetType_C",MatCompositeGetType_Composite);CHKERRQ(ierr); 9468c8613bfSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetMergeType_C",MatCompositeSetMergeType_Composite);CHKERRQ(ierr); 9473b35acafSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetMatStructure_C",MatCompositeSetMatStructure_Composite);CHKERRQ(ierr); 9483b35acafSJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetMatStructure_C",MatCompositeGetMatStructure_Composite);CHKERRQ(ierr); 94941cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeMerge_C",MatCompositeMerge_Composite);CHKERRQ(ierr); 9506d0add67SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetNumberMat_C",MatCompositeGetNumberMat_Composite);CHKERRQ(ierr); 95141cd0125SJakub Kruzik ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetMat_C",MatCompositeGetMat_Composite);CHKERRQ(ierr); 95241cd0125SJakub Kruzik 95341cd0125SJakub Kruzik ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr); 95441cd0125SJakub Kruzik PetscFunctionReturn(0); 95541cd0125SJakub Kruzik } 95641cd0125SJakub Kruzik 957