xref: /petsc/src/mat/impls/composite/mcomposite.c (revision 6dbc55e5e566658570d0255ca26a064ceaf98720)
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 
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 
268*6dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCompositeGetMat(), MatCompositeMerge(), MatCompositeSetType(), MATCOMPOSITE
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 
379*6dbc55e5SJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeGetType(), 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 
392*6dbc55e5SJakub Kruzik static PetscErrorCode MatCompositeGetType_Composite(Mat mat,MatCompositeType *type)
393*6dbc55e5SJakub Kruzik {
394*6dbc55e5SJakub Kruzik   Mat_Composite  *b = (Mat_Composite*)mat->data;
395*6dbc55e5SJakub Kruzik 
396*6dbc55e5SJakub Kruzik   PetscFunctionBegin;
397*6dbc55e5SJakub Kruzik   *type = b->type;
398*6dbc55e5SJakub Kruzik   PetscFunctionReturn(0);
399*6dbc55e5SJakub Kruzik }
400*6dbc55e5SJakub Kruzik 
401*6dbc55e5SJakub Kruzik /*@
402*6dbc55e5SJakub Kruzik    MatCompositeGetType - Returns type of composite.
403*6dbc55e5SJakub Kruzik 
404*6dbc55e5SJakub Kruzik    Not Collective
405*6dbc55e5SJakub Kruzik 
406*6dbc55e5SJakub Kruzik    Input Parameter:
407*6dbc55e5SJakub Kruzik .  mat - the composite matrix
408*6dbc55e5SJakub Kruzik 
409*6dbc55e5SJakub Kruzik    Output Parameter:
410*6dbc55e5SJakub Kruzik .  type - type of composite
411*6dbc55e5SJakub Kruzik 
412*6dbc55e5SJakub Kruzik    Level: advanced
413*6dbc55e5SJakub Kruzik 
414*6dbc55e5SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeSetType(), MATCOMPOSITE
415*6dbc55e5SJakub Kruzik 
416*6dbc55e5SJakub Kruzik @*/
417*6dbc55e5SJakub Kruzik PetscErrorCode MatCompositeGetType(Mat mat,MatCompositeType *type)
418*6dbc55e5SJakub Kruzik {
419*6dbc55e5SJakub Kruzik   PetscErrorCode ierr;
420*6dbc55e5SJakub Kruzik 
421*6dbc55e5SJakub Kruzik   PetscFunctionBegin;
422*6dbc55e5SJakub Kruzik   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
423*6dbc55e5SJakub Kruzik   PetscValidPointer(type,2);
424*6dbc55e5SJakub Kruzik   ierr = PetscUseMethod(mat,"MatCompositeGetType_C",(Mat,MatCompositeType*),(mat,type));CHKERRQ(ierr);
425*6dbc55e5SJakub Kruzik   PetscFunctionReturn(0);
426*6dbc55e5SJakub Kruzik }
427*6dbc55e5SJakub Kruzik 
428d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeMerge_Composite(Mat mat)
429b52f573bSBarry Smith {
430b52f573bSBarry Smith   Mat_Composite     *shell = (Mat_Composite*)mat->data;
4316d7c1e57SBarry Smith   Mat_CompositeLink next   = shell->head, prev = shell->tail;
432b52f573bSBarry Smith   PetscErrorCode    ierr;
4336d7c1e57SBarry Smith   Mat               tmat,newmat;
4341ba60692SJed Brown   Vec               left,right;
4351ba60692SJed Brown   PetscScalar       scale;
436b52f573bSBarry Smith 
437b52f573bSBarry Smith   PetscFunctionBegin;
438e32f2f54SBarry Smith   if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()");
439b52f573bSBarry Smith 
440b52f573bSBarry Smith   PetscFunctionBegin;
4416d7c1e57SBarry Smith   if (shell->type == MAT_COMPOSITE_ADDITIVE) {
442b52f573bSBarry Smith     ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr);
443b52f573bSBarry Smith     while ((next = next->next)) {
444b52f573bSBarry Smith       ierr = MatAXPY(tmat,1.0,next->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
445b52f573bSBarry Smith     }
4466d7c1e57SBarry Smith   } else {
44704d534ceSJakub Kruzik     if (shell->mergefromright) {
4486d7c1e57SBarry Smith       ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr);
449b6cfcaf5SJakub Kruzik       while ((next = next->next)) {
450b6cfcaf5SJakub Kruzik         ierr = MatMatMult(next->mat,tmat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr);
4516bf464f9SBarry Smith         ierr = MatDestroy(&tmat);CHKERRQ(ierr);
4526d7c1e57SBarry Smith         tmat = newmat;
4536d7c1e57SBarry Smith       }
45404d534ceSJakub Kruzik     } else {
45504d534ceSJakub Kruzik       ierr = MatDuplicate(prev->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr);
45604d534ceSJakub Kruzik       while ((prev = prev->prev)) {
45704d534ceSJakub Kruzik         ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr);
45804d534ceSJakub Kruzik         ierr = MatDestroy(&tmat);CHKERRQ(ierr);
45904d534ceSJakub Kruzik         tmat = newmat;
46004d534ceSJakub Kruzik       }
46104d534ceSJakub Kruzik     }
4626d7c1e57SBarry Smith   }
4631ba60692SJed Brown 
4641ba60692SJed Brown   scale = shell->scale;
4651ba60692SJed Brown   if ((left = shell->left)) {ierr = PetscObjectReference((PetscObject)left);CHKERRQ(ierr);}
4661ba60692SJed Brown   if ((right = shell->right)) {ierr = PetscObjectReference((PetscObject)right);CHKERRQ(ierr);}
4671ba60692SJed Brown 
46828be2f97SBarry Smith   ierr = MatHeaderReplace(mat,&tmat);CHKERRQ(ierr);
4691ba60692SJed Brown 
4701ba60692SJed Brown   ierr = MatDiagonalScale(mat,left,right);CHKERRQ(ierr);
4711ba60692SJed Brown   ierr = MatScale(mat,scale);CHKERRQ(ierr);
4721ba60692SJed Brown   ierr = VecDestroy(&left);CHKERRQ(ierr);
4731ba60692SJed Brown   ierr = VecDestroy(&right);CHKERRQ(ierr);
474b52f573bSBarry Smith   PetscFunctionReturn(0);
475b52f573bSBarry Smith }
4766a7ede75SJakub Kruzik 
4776a7ede75SJakub Kruzik /*@
478d7f81bf2SJakub Kruzik    MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix
479d7f81bf2SJakub Kruzik      by summing all the matrices inside the composite matrix.
480d7f81bf2SJakub Kruzik 
481d7f81bf2SJakub Kruzik   Collective on MPI_Comm
482d7f81bf2SJakub Kruzik 
483d7f81bf2SJakub Kruzik    Input Parameters:
484d7f81bf2SJakub Kruzik .  mat - the composite matrix
485d7f81bf2SJakub Kruzik 
486d7f81bf2SJakub Kruzik 
487d7f81bf2SJakub Kruzik    Options Database:
488d7f81bf2SJakub Kruzik .  -mat_composite_merge  (you must call MatAssemblyBegin()/MatAssemblyEnd() to have this checked)
489d7f81bf2SJakub Kruzik 
490d7f81bf2SJakub Kruzik    Level: advanced
491d7f81bf2SJakub Kruzik 
492d7f81bf2SJakub Kruzik    Notes:
493d7f81bf2SJakub Kruzik       The MatType of the resulting matrix will be the same as the MatType of the FIRST
494d7f81bf2SJakub Kruzik     matrix in the composite matrix.
495d7f81bf2SJakub Kruzik 
49604d534ceSJakub Kruzik .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MatCompositeSetMergeFromRight(), MATCOMPOSITE
497d7f81bf2SJakub Kruzik 
498d7f81bf2SJakub Kruzik @*/
499d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeMerge(Mat mat)
500d7f81bf2SJakub Kruzik {
501d7f81bf2SJakub Kruzik   PetscErrorCode ierr;
502d7f81bf2SJakub Kruzik 
503d7f81bf2SJakub Kruzik   PetscFunctionBegin;
504d7f81bf2SJakub Kruzik   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
505d7f81bf2SJakub Kruzik   ierr = PetscUseMethod(mat,"MatCompositeMerge_C",(Mat),(mat));CHKERRQ(ierr);
506d7f81bf2SJakub Kruzik   PetscFunctionReturn(0);
507d7f81bf2SJakub Kruzik }
508d7f81bf2SJakub Kruzik 
509d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetNMat_Composite(Mat mat,PetscInt *nmat)
510d7f81bf2SJakub Kruzik {
511d7f81bf2SJakub Kruzik   Mat_Composite     *shell = (Mat_Composite*)mat->data;
512d7f81bf2SJakub Kruzik 
513d7f81bf2SJakub Kruzik   PetscFunctionBegin;
514d7f81bf2SJakub Kruzik   *nmat = shell->nmat;
515d7f81bf2SJakub Kruzik   PetscFunctionReturn(0);
516d7f81bf2SJakub Kruzik }
517d7f81bf2SJakub Kruzik 
518d7f81bf2SJakub Kruzik /*@
5196a7ede75SJakub Kruzik    MatCompositeGetNMat - Returns the number of matrices in composite.
5206a7ede75SJakub Kruzik 
5216a7ede75SJakub Kruzik    Not Collective
5226a7ede75SJakub Kruzik 
5236a7ede75SJakub Kruzik    Input Parameter:
524d7f81bf2SJakub Kruzik .  mat - the composite matrix
5256a7ede75SJakub Kruzik 
5266a7ede75SJakub Kruzik    Output Parameter:
527*6dbc55e5SJakub Kruzik +  size - the local size
528*6dbc55e5SJakub Kruzik -  nmat - number of matrices in composite
5296a7ede75SJakub Kruzik 
5308b5c3584SJakub Kruzik    Level: advanced
5316a7ede75SJakub Kruzik 
5328b5c3584SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetMat()
5336a7ede75SJakub Kruzik 
5346a7ede75SJakub Kruzik @*/
535d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetNMat(Mat mat,PetscInt *nmat)
5366a7ede75SJakub Kruzik {
537d7f81bf2SJakub Kruzik   PetscErrorCode ierr;
5386a7ede75SJakub Kruzik 
5396a7ede75SJakub Kruzik   PetscFunctionBegin;
540d7f81bf2SJakub Kruzik   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
5416a7ede75SJakub Kruzik   PetscValidPointer(nmat,2);
542d7f81bf2SJakub Kruzik   ierr = PetscUseMethod(mat,"MatCompositeGetNMat_C",(Mat,PetscInt*),(mat,nmat));CHKERRQ(ierr);
543d7f81bf2SJakub Kruzik   PetscFunctionReturn(0);
544d7f81bf2SJakub Kruzik }
545d7f81bf2SJakub Kruzik 
546d7f81bf2SJakub Kruzik static PetscErrorCode MatCompositeGetMat_Composite(Mat mat,PetscInt i,Mat *Ai)
547d7f81bf2SJakub Kruzik {
548d7f81bf2SJakub Kruzik   Mat_Composite     *shell = (Mat_Composite*)mat->data;
549d7f81bf2SJakub Kruzik   Mat_CompositeLink ilink;
550d7f81bf2SJakub Kruzik   PetscInt          k;
551d7f81bf2SJakub Kruzik 
552d7f81bf2SJakub Kruzik   PetscFunctionBegin;
553d7f81bf2SJakub Kruzik   if (i >= shell->nmat) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"index out of range: %d >= %d",i,shell->nmat);
554d7f81bf2SJakub Kruzik   ilink = shell->head;
555d7f81bf2SJakub Kruzik   for (k=0; k<i; k++) {
556d7f81bf2SJakub Kruzik     ilink = ilink->next;
557d7f81bf2SJakub Kruzik   }
558d7f81bf2SJakub Kruzik   *Ai = ilink->mat;
5596a7ede75SJakub Kruzik   PetscFunctionReturn(0);
5606a7ede75SJakub Kruzik }
5616a7ede75SJakub Kruzik 
5628b5c3584SJakub Kruzik /*@
5638b5c3584SJakub Kruzik    MatCompositeGetMat - Returns the ith matrix from composite.
5648b5c3584SJakub Kruzik 
5658b5c3584SJakub Kruzik    Logically Collective on Mat
5668b5c3584SJakub Kruzik 
5678b5c3584SJakub Kruzik    Input Parameter:
568d7f81bf2SJakub Kruzik +  mat - the composite matrix
5698b5c3584SJakub Kruzik -  i - the number of requested matrix
5708b5c3584SJakub Kruzik 
5718b5c3584SJakub Kruzik    Output Parameter:
5728b5c3584SJakub Kruzik .  Ai - ith matrix in composite
5738b5c3584SJakub Kruzik 
5748b5c3584SJakub Kruzik    Level: advanced
5758b5c3584SJakub Kruzik 
5768b5c3584SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeGetNMat()
5778b5c3584SJakub Kruzik 
5788b5c3584SJakub Kruzik @*/
579d7f81bf2SJakub Kruzik PetscErrorCode MatCompositeGetMat(Mat mat,PetscInt i,Mat *Ai)
5808b5c3584SJakub Kruzik {
581d7f81bf2SJakub Kruzik   PetscErrorCode ierr;
5828b5c3584SJakub Kruzik 
5838b5c3584SJakub Kruzik   PetscFunctionBegin;
584d7f81bf2SJakub Kruzik   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
585d7f81bf2SJakub Kruzik   PetscValidLogicalCollectiveInt(mat,i,2);
5868b5c3584SJakub Kruzik   PetscValidPointer(Ai,3);
587d7f81bf2SJakub Kruzik   ierr = PetscUseMethod(mat,"MatCompositeGetMat_C",(Mat,PetscInt,Mat*),(mat,i,Ai));CHKERRQ(ierr);
5888b5c3584SJakub Kruzik   PetscFunctionReturn(0);
5898b5c3584SJakub Kruzik }
5908b5c3584SJakub Kruzik 
59104d534ceSJakub Kruzik static PetscErrorCode MatCompositeSetMergeFromRight_Composite(Mat mat,PetscBool flg)
59204d534ceSJakub Kruzik {
59304d534ceSJakub Kruzik   Mat_Composite     *shell = (Mat_Composite*)mat->data;
59404d534ceSJakub Kruzik 
59504d534ceSJakub Kruzik   PetscFunctionBegin;
59604d534ceSJakub Kruzik   shell->mergefromright = flg;
59704d534ceSJakub Kruzik   PetscFunctionReturn(0);
59804d534ceSJakub Kruzik }
59904d534ceSJakub Kruzik 
60004d534ceSJakub Kruzik /*@
60104d534ceSJakub Kruzik    MatCompositeSetMergeFromRight - Sets MatCompositeMerge() to start from right.
60204d534ceSJakub Kruzik 
60304d534ceSJakub Kruzik    Logically Collective on Mat
60404d534ceSJakub Kruzik 
60504d534ceSJakub Kruzik    Input Parameter:
60604d534ceSJakub Kruzik +  mat - the composite matrix
60704d534ceSJakub Kruzik -  flg - if true (default) the merge starts with the first added matrix (mat[0])
60804d534ceSJakub Kruzik 
60904d534ceSJakub Kruzik    Level: advanced
61004d534ceSJakub Kruzik 
61104d534ceSJakub Kruzik .seealso: MatCreateComposite(), MatCompositeMerge()
61204d534ceSJakub Kruzik 
61304d534ceSJakub Kruzik @*/
61404d534ceSJakub Kruzik PetscErrorCode MatCompositeSetMergeFromRight(Mat mat,PetscBool flg)
61504d534ceSJakub Kruzik {
61604d534ceSJakub Kruzik   PetscErrorCode ierr;
61704d534ceSJakub Kruzik 
61804d534ceSJakub Kruzik   PetscFunctionBegin;
61904d534ceSJakub Kruzik   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
62004d534ceSJakub Kruzik   PetscValidLogicalCollectiveBool(mat,flg,2);
62104d534ceSJakub Kruzik   ierr = PetscUseMethod(mat,"MatCompositeSetMergeFromRight_C",(Mat,PetscBool),(mat,flg));CHKERRQ(ierr);
62204d534ceSJakub Kruzik   PetscFunctionReturn(0);
62304d534ceSJakub Kruzik }
62404d534ceSJakub Kruzik 
62541cd0125SJakub Kruzik static struct _MatOps MatOps_Values = {0,
62641cd0125SJakub Kruzik                                        0,
62741cd0125SJakub Kruzik                                        0,
62841cd0125SJakub Kruzik                                        MatMult_Composite,
62941cd0125SJakub Kruzik                                        0,
63041cd0125SJakub Kruzik                                 /*  5*/ MatMultTranspose_Composite,
63141cd0125SJakub Kruzik                                        0,
63241cd0125SJakub Kruzik                                        0,
63341cd0125SJakub Kruzik                                        0,
63441cd0125SJakub Kruzik                                        0,
63541cd0125SJakub Kruzik                                 /* 10*/ 0,
63641cd0125SJakub Kruzik                                        0,
63741cd0125SJakub Kruzik                                        0,
63841cd0125SJakub Kruzik                                        0,
63941cd0125SJakub Kruzik                                        0,
64041cd0125SJakub Kruzik                                 /* 15*/ 0,
64141cd0125SJakub Kruzik                                        0,
64241cd0125SJakub Kruzik                                        MatGetDiagonal_Composite,
64341cd0125SJakub Kruzik                                        MatDiagonalScale_Composite,
64441cd0125SJakub Kruzik                                        0,
64541cd0125SJakub Kruzik                                 /* 20*/ 0,
64641cd0125SJakub Kruzik                                        MatAssemblyEnd_Composite,
64741cd0125SJakub Kruzik                                        0,
64841cd0125SJakub Kruzik                                        0,
64941cd0125SJakub Kruzik                                /* 24*/ 0,
65041cd0125SJakub Kruzik                                        0,
65141cd0125SJakub Kruzik                                        0,
65241cd0125SJakub Kruzik                                        0,
65341cd0125SJakub Kruzik                                        0,
65441cd0125SJakub Kruzik                                /* 29*/ 0,
65541cd0125SJakub Kruzik                                        0,
65641cd0125SJakub Kruzik                                        0,
65741cd0125SJakub Kruzik                                        0,
65841cd0125SJakub Kruzik                                        0,
65941cd0125SJakub Kruzik                                /* 34*/ 0,
66041cd0125SJakub Kruzik                                        0,
66141cd0125SJakub Kruzik                                        0,
66241cd0125SJakub Kruzik                                        0,
66341cd0125SJakub Kruzik                                        0,
66441cd0125SJakub Kruzik                                /* 39*/ 0,
66541cd0125SJakub Kruzik                                        0,
66641cd0125SJakub Kruzik                                        0,
66741cd0125SJakub Kruzik                                        0,
66841cd0125SJakub Kruzik                                        0,
66941cd0125SJakub Kruzik                                /* 44*/ 0,
67041cd0125SJakub Kruzik                                        MatScale_Composite,
67141cd0125SJakub Kruzik                                        MatShift_Basic,
67241cd0125SJakub Kruzik                                        0,
67341cd0125SJakub Kruzik                                        0,
67441cd0125SJakub Kruzik                                /* 49*/ 0,
67541cd0125SJakub Kruzik                                        0,
67641cd0125SJakub Kruzik                                        0,
67741cd0125SJakub Kruzik                                        0,
67841cd0125SJakub Kruzik                                        0,
67941cd0125SJakub Kruzik                                /* 54*/ 0,
68041cd0125SJakub Kruzik                                        0,
68141cd0125SJakub Kruzik                                        0,
68241cd0125SJakub Kruzik                                        0,
68341cd0125SJakub Kruzik                                        0,
68441cd0125SJakub Kruzik                                /* 59*/ 0,
68541cd0125SJakub Kruzik                                        MatDestroy_Composite,
68641cd0125SJakub Kruzik                                        0,
68741cd0125SJakub Kruzik                                        0,
68841cd0125SJakub Kruzik                                        0,
68941cd0125SJakub Kruzik                                /* 64*/ 0,
69041cd0125SJakub Kruzik                                        0,
69141cd0125SJakub Kruzik                                        0,
69241cd0125SJakub Kruzik                                        0,
69341cd0125SJakub Kruzik                                        0,
69441cd0125SJakub Kruzik                                /* 69*/ 0,
69541cd0125SJakub Kruzik                                        0,
69641cd0125SJakub Kruzik                                        0,
69741cd0125SJakub Kruzik                                        0,
69841cd0125SJakub Kruzik                                        0,
69941cd0125SJakub Kruzik                                /* 74*/ 0,
70041cd0125SJakub Kruzik                                        0,
70141cd0125SJakub Kruzik                                        0,
70241cd0125SJakub Kruzik                                        0,
70341cd0125SJakub Kruzik                                        0,
70441cd0125SJakub Kruzik                                /* 79*/ 0,
70541cd0125SJakub Kruzik                                        0,
70641cd0125SJakub Kruzik                                        0,
70741cd0125SJakub Kruzik                                        0,
70841cd0125SJakub Kruzik                                        0,
70941cd0125SJakub Kruzik                                /* 84*/ 0,
71041cd0125SJakub Kruzik                                        0,
71141cd0125SJakub Kruzik                                        0,
71241cd0125SJakub Kruzik                                        0,
71341cd0125SJakub Kruzik                                        0,
71441cd0125SJakub Kruzik                                /* 89*/ 0,
71541cd0125SJakub Kruzik                                        0,
71641cd0125SJakub Kruzik                                        0,
71741cd0125SJakub Kruzik                                        0,
71841cd0125SJakub Kruzik                                        0,
71941cd0125SJakub Kruzik                                /* 94*/ 0,
72041cd0125SJakub Kruzik                                        0,
72141cd0125SJakub Kruzik                                        0,
72241cd0125SJakub Kruzik                                        0,
72341cd0125SJakub Kruzik                                        0,
72441cd0125SJakub Kruzik                                 /*99*/ 0,
72541cd0125SJakub Kruzik                                        0,
72641cd0125SJakub Kruzik                                        0,
72741cd0125SJakub Kruzik                                        0,
72841cd0125SJakub Kruzik                                        0,
72941cd0125SJakub Kruzik                                /*104*/ 0,
73041cd0125SJakub Kruzik                                        0,
73141cd0125SJakub Kruzik                                        0,
73241cd0125SJakub Kruzik                                        0,
73341cd0125SJakub Kruzik                                        0,
73441cd0125SJakub Kruzik                                /*109*/ 0,
73541cd0125SJakub Kruzik                                        0,
73641cd0125SJakub Kruzik                                        0,
73741cd0125SJakub Kruzik                                        0,
73841cd0125SJakub Kruzik                                        0,
73941cd0125SJakub Kruzik                                /*114*/ 0,
74041cd0125SJakub Kruzik                                        0,
74141cd0125SJakub Kruzik                                        0,
74241cd0125SJakub Kruzik                                        0,
74341cd0125SJakub Kruzik                                        0,
74441cd0125SJakub Kruzik                                /*119*/ 0,
74541cd0125SJakub Kruzik                                        0,
74641cd0125SJakub Kruzik                                        0,
74741cd0125SJakub Kruzik                                        0,
74841cd0125SJakub Kruzik                                        0,
74941cd0125SJakub Kruzik                                /*124*/ 0,
75041cd0125SJakub Kruzik                                        0,
75141cd0125SJakub Kruzik                                        0,
75241cd0125SJakub Kruzik                                        0,
75341cd0125SJakub Kruzik                                        0,
75441cd0125SJakub Kruzik                                /*129*/ 0,
75541cd0125SJakub Kruzik                                        0,
75641cd0125SJakub Kruzik                                        0,
75741cd0125SJakub Kruzik                                        0,
75841cd0125SJakub Kruzik                                        0,
75941cd0125SJakub Kruzik                                /*134*/ 0,
76041cd0125SJakub Kruzik                                        0,
76141cd0125SJakub Kruzik                                        0,
76241cd0125SJakub Kruzik                                        0,
76341cd0125SJakub Kruzik                                        0,
76441cd0125SJakub Kruzik                                /*139*/ 0,
76541cd0125SJakub Kruzik                                        0,
76641cd0125SJakub Kruzik                                        0
76741cd0125SJakub Kruzik };
76841cd0125SJakub Kruzik 
76941cd0125SJakub Kruzik /*MC
77041cd0125SJakub Kruzik    MATCOMPOSITE - A matrix defined by the sum (or product) of one or more matrices.
77141cd0125SJakub Kruzik     The matrices need to have a correct size and parallel layout for the sum or product to be valid.
77241cd0125SJakub Kruzik 
77341cd0125SJakub Kruzik    Notes:
77441cd0125SJakub Kruzik     to use the product of the matrices call MatCompositeSetType(mat,MAT_COMPOSITE_MULTIPLICATIVE);
77541cd0125SJakub Kruzik 
77641cd0125SJakub Kruzik   Level: advanced
77741cd0125SJakub Kruzik 
778*6dbc55e5SJakub Kruzik .seealso: MatCreateComposite(), MatCompositeAddMat(), MatSetType(), MatCompositeSetType(), MatCompositeGetType(), MatCompositeMerge(), MatCompositeSetMergeFromRight(), MatCompositeGetNmat(), MatCompositeGetMat()
77941cd0125SJakub Kruzik M*/
78041cd0125SJakub Kruzik 
78141cd0125SJakub Kruzik PETSC_EXTERN PetscErrorCode MatCreate_Composite(Mat A)
78241cd0125SJakub Kruzik {
78341cd0125SJakub Kruzik   Mat_Composite  *b;
78441cd0125SJakub Kruzik   PetscErrorCode ierr;
78541cd0125SJakub Kruzik 
78641cd0125SJakub Kruzik   PetscFunctionBegin;
78741cd0125SJakub Kruzik   ierr    = PetscNewLog(A,&b);CHKERRQ(ierr);
78841cd0125SJakub Kruzik   A->data = (void*)b;
78941cd0125SJakub Kruzik   ierr    = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
79041cd0125SJakub Kruzik 
79141cd0125SJakub Kruzik   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
79241cd0125SJakub Kruzik   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
79341cd0125SJakub Kruzik 
79441cd0125SJakub Kruzik   A->assembled      = PETSC_TRUE;
79541cd0125SJakub Kruzik   A->preallocated   = PETSC_TRUE;
79641cd0125SJakub Kruzik   b->type           = MAT_COMPOSITE_ADDITIVE;
79741cd0125SJakub Kruzik   b->scale          = 1.0;
79841cd0125SJakub Kruzik   b->nmat           = 0;
79904d534ceSJakub Kruzik   b->mergefromright = PETSC_TRUE;
80041cd0125SJakub Kruzik 
80141cd0125SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeAddMat_C",MatCompositeAddMat_Composite);CHKERRQ(ierr);
80241cd0125SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetType_C",MatCompositeSetType_Composite);CHKERRQ(ierr);
803*6dbc55e5SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetType_C",MatCompositeGetType_Composite);CHKERRQ(ierr);
80441cd0125SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeMerge_C",MatCompositeMerge_Composite);CHKERRQ(ierr);
80541cd0125SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetNMat_C",MatCompositeGetNMat_Composite);CHKERRQ(ierr);
80641cd0125SJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeGetMat_C",MatCompositeGetMat_Composite);CHKERRQ(ierr);
80704d534ceSJakub Kruzik   ierr = PetscObjectComposeFunction((PetscObject)A,"MatCompositeSetMergeFromRight_C",MatCompositeSetMergeFromRight_Composite);CHKERRQ(ierr);
80841cd0125SJakub Kruzik 
80941cd0125SJakub Kruzik   ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr);
81041cd0125SJakub Kruzik   PetscFunctionReturn(0);
81141cd0125SJakub Kruzik }
81241cd0125SJakub Kruzik 
813