xref: /petsc/src/mat/impls/composite/mcomposite.c (revision b9147fbb7375951b83d4ce6f264c883d157e3a5b)
1793850ffSBarry Smith #define PETSCMAT_DLL
2793850ffSBarry Smith 
3*b9147fbbSdalcinl #include "include/private/matimpl.h"        /*I "petscmat.h" I*/
4793850ffSBarry Smith 
5793850ffSBarry Smith typedef struct _Mat_CompositeLink *Mat_CompositeLink;
6793850ffSBarry Smith struct _Mat_CompositeLink {
7793850ffSBarry Smith   Mat               mat;
8793850ffSBarry Smith   Mat_CompositeLink next;
9793850ffSBarry Smith };
10793850ffSBarry Smith 
11793850ffSBarry Smith typedef struct {
12793850ffSBarry Smith   Mat_CompositeLink head;
13793850ffSBarry Smith   Vec               work;
14793850ffSBarry Smith } Mat_Composite;
15793850ffSBarry Smith 
16793850ffSBarry Smith #undef __FUNCT__
17793850ffSBarry Smith #define __FUNCT__ "MatDestroy_Composite"
18793850ffSBarry Smith PetscErrorCode MatDestroy_Composite(Mat mat)
19793850ffSBarry Smith {
20793850ffSBarry Smith   PetscErrorCode   ierr;
212c33bbaeSSatish Balay   Mat_Composite    *shell = (Mat_Composite*)mat->data;
22793850ffSBarry Smith   Mat_CompositeLink next = shell->head;
23793850ffSBarry Smith 
24793850ffSBarry Smith   PetscFunctionBegin;
25793850ffSBarry Smith   while (next) {
26793850ffSBarry Smith     ierr = MatDestroy(next->mat);CHKERRQ(ierr);
27793850ffSBarry Smith     next = next->next;
28793850ffSBarry Smith   }
29793850ffSBarry Smith   if (shell->work) {ierr = VecDestroy(shell->work);CHKERRQ(ierr);}
30793850ffSBarry Smith   ierr      = PetscFree(shell);CHKERRQ(ierr);
31793850ffSBarry Smith   mat->data = 0;
32793850ffSBarry Smith   PetscFunctionReturn(0);
33793850ffSBarry Smith }
34793850ffSBarry Smith 
35793850ffSBarry Smith #undef __FUNCT__
36793850ffSBarry Smith #define __FUNCT__ "MatMult_Composite"
37793850ffSBarry Smith PetscErrorCode MatMult_Composite(Mat A,Vec x,Vec y)
38793850ffSBarry Smith {
39793850ffSBarry Smith   Mat_Composite     *shell = (Mat_Composite*)A->data;
40793850ffSBarry Smith   Mat_CompositeLink next = shell->head;
41793850ffSBarry Smith   PetscErrorCode    ierr;
42793850ffSBarry Smith 
43793850ffSBarry Smith   PetscFunctionBegin;
44793850ffSBarry Smith   if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()");
45793850ffSBarry Smith   ierr = MatMult(next->mat,x,y);CHKERRQ(ierr);
46793850ffSBarry Smith   while ((next = next->next)) {
47793850ffSBarry Smith     ierr = MatMultAdd(next->mat,x,y,y);CHKERRQ(ierr);
48793850ffSBarry Smith   }
49793850ffSBarry Smith   PetscFunctionReturn(0);
50793850ffSBarry Smith }
51793850ffSBarry Smith 
52793850ffSBarry Smith #undef __FUNCT__
53793850ffSBarry Smith #define __FUNCT__ "MatMultTranspose_Composite"
54793850ffSBarry Smith PetscErrorCode MatMultTranspose_Composite(Mat A,Vec x,Vec y)
55793850ffSBarry Smith {
56793850ffSBarry Smith   Mat_Composite     *shell = (Mat_Composite*)A->data;
57793850ffSBarry Smith   Mat_CompositeLink next = shell->head;
58793850ffSBarry Smith   PetscErrorCode    ierr;
59793850ffSBarry Smith 
60793850ffSBarry Smith   PetscFunctionBegin;
61793850ffSBarry Smith   if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()");
62793850ffSBarry Smith   ierr = MatMultTranspose(next->mat,x,y);CHKERRQ(ierr);
63793850ffSBarry Smith   while ((next = next->next)) {
64793850ffSBarry Smith     ierr = MatMultTransposeAdd(next->mat,x,y,y);CHKERRQ(ierr);
65793850ffSBarry Smith   }
66793850ffSBarry Smith   PetscFunctionReturn(0);
67793850ffSBarry Smith }
68793850ffSBarry Smith 
69793850ffSBarry Smith #undef __FUNCT__
70793850ffSBarry Smith #define __FUNCT__ "MatGetDiagonal_Composite"
71793850ffSBarry Smith PetscErrorCode MatGetDiagonal_Composite(Mat A,Vec v)
72793850ffSBarry Smith {
73793850ffSBarry Smith   Mat_Composite     *shell = (Mat_Composite*)A->data;
74793850ffSBarry Smith   Mat_CompositeLink next = shell->head;
75793850ffSBarry Smith   PetscErrorCode    ierr;
76793850ffSBarry Smith 
77793850ffSBarry Smith   PetscFunctionBegin;
78793850ffSBarry Smith   if (!next) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()");
79793850ffSBarry Smith   ierr = MatGetDiagonal(next->mat,v);CHKERRQ(ierr);
80793850ffSBarry Smith   if (next->next && !shell->work) {
81793850ffSBarry Smith     ierr = VecDuplicate(v,&shell->work);CHKERRQ(ierr);
82793850ffSBarry Smith   }
83793850ffSBarry Smith   while ((next = next->next)) {
84793850ffSBarry Smith     ierr = MatGetDiagonal(next->mat,shell->work);CHKERRQ(ierr);
85793850ffSBarry Smith     ierr = VecAXPY(v,1.0,shell->work);CHKERRQ(ierr);
86793850ffSBarry Smith   }
87793850ffSBarry Smith   PetscFunctionReturn(0);
88793850ffSBarry Smith }
89793850ffSBarry Smith 
90793850ffSBarry Smith #undef __FUNCT__
91793850ffSBarry Smith #define __FUNCT__ "MatAssemblyEnd_Composite"
92793850ffSBarry Smith PetscErrorCode MatAssemblyEnd_Composite(Mat Y,MatAssemblyType t)
93793850ffSBarry Smith {
94793850ffSBarry Smith   PetscFunctionBegin;
95793850ffSBarry Smith   PetscFunctionReturn(0);
96793850ffSBarry Smith }
97793850ffSBarry Smith 
98793850ffSBarry Smith 
99793850ffSBarry Smith static struct _MatOps MatOps_Values = {0,
100793850ffSBarry Smith        0,
101793850ffSBarry Smith        0,
102793850ffSBarry Smith        MatMult_Composite,
103793850ffSBarry Smith        0,
104793850ffSBarry Smith /* 5*/ MatMultTranspose_Composite,
105793850ffSBarry Smith        0,
106793850ffSBarry Smith        0,
107793850ffSBarry Smith        0,
108793850ffSBarry Smith        0,
109793850ffSBarry Smith /*10*/ 0,
110793850ffSBarry Smith        0,
111793850ffSBarry Smith        0,
112793850ffSBarry Smith        0,
113793850ffSBarry Smith        0,
114793850ffSBarry Smith /*15*/ 0,
115793850ffSBarry Smith        0,
116793850ffSBarry Smith        MatGetDiagonal_Composite,
117793850ffSBarry Smith        0,
118793850ffSBarry Smith        0,
119793850ffSBarry Smith /*20*/ 0,
120793850ffSBarry Smith        MatAssemblyEnd_Composite,
121793850ffSBarry Smith        0,
122793850ffSBarry Smith        0,
123793850ffSBarry Smith        0,
124793850ffSBarry Smith /*25*/ 0,
125793850ffSBarry Smith        0,
126793850ffSBarry Smith        0,
127793850ffSBarry Smith        0,
128793850ffSBarry Smith        0,
129793850ffSBarry Smith /*30*/ 0,
130793850ffSBarry Smith        0,
131793850ffSBarry Smith        0,
132793850ffSBarry Smith        0,
133793850ffSBarry Smith        0,
134793850ffSBarry Smith /*35*/ 0,
135793850ffSBarry Smith        0,
136793850ffSBarry Smith        0,
137793850ffSBarry Smith        0,
138793850ffSBarry Smith        0,
139793850ffSBarry Smith /*40*/ 0,
140793850ffSBarry Smith        0,
141793850ffSBarry Smith        0,
142793850ffSBarry Smith        0,
143793850ffSBarry Smith        0,
144793850ffSBarry Smith /*45*/ 0,
145793850ffSBarry Smith        0,
146793850ffSBarry Smith        0,
147793850ffSBarry Smith        0,
148793850ffSBarry Smith        0,
149793850ffSBarry Smith /*50*/ 0,
150793850ffSBarry Smith        0,
151793850ffSBarry Smith        0,
152793850ffSBarry Smith        0,
153793850ffSBarry Smith        0,
154793850ffSBarry Smith /*55*/ 0,
155793850ffSBarry Smith        0,
156793850ffSBarry Smith        0,
157793850ffSBarry Smith        0,
158793850ffSBarry Smith        0,
159793850ffSBarry Smith /*60*/ 0,
160793850ffSBarry Smith        MatDestroy_Composite,
161793850ffSBarry Smith        0,
162793850ffSBarry Smith        0,
163793850ffSBarry Smith        0,
164793850ffSBarry Smith /*65*/ 0,
165793850ffSBarry Smith        0,
166793850ffSBarry Smith        0,
167793850ffSBarry Smith        0,
168793850ffSBarry Smith        0,
169793850ffSBarry Smith /*70*/ 0,
170793850ffSBarry Smith        0,
171793850ffSBarry Smith        0,
172793850ffSBarry Smith        0,
173793850ffSBarry Smith        0,
174793850ffSBarry Smith /*75*/ 0,
175793850ffSBarry Smith        0,
176793850ffSBarry Smith        0,
177793850ffSBarry Smith        0,
178793850ffSBarry Smith        0,
179793850ffSBarry Smith /*80*/ 0,
180793850ffSBarry Smith        0,
181793850ffSBarry Smith        0,
182793850ffSBarry Smith        0,
183793850ffSBarry Smith        0,
184793850ffSBarry Smith /*85*/ 0,
185793850ffSBarry Smith        0,
186793850ffSBarry Smith        0,
187793850ffSBarry Smith        0,
188793850ffSBarry Smith        0,
189793850ffSBarry Smith /*90*/ 0,
190793850ffSBarry Smith        0,
191793850ffSBarry Smith        0,
192793850ffSBarry Smith        0,
193793850ffSBarry Smith        0,
194793850ffSBarry Smith /*95*/ 0,
195793850ffSBarry Smith        0,
196793850ffSBarry Smith        0,
197793850ffSBarry Smith        0};
198793850ffSBarry Smith 
199793850ffSBarry Smith /*MC
200793850ffSBarry Smith    MATCOMPOSITE - A matrix defined by the sum of one or more matrices (all matrices are of same size and parallel layout)
201793850ffSBarry Smith 
202793850ffSBarry Smith   Level: advanced
203793850ffSBarry Smith 
204793850ffSBarry Smith .seealso: MatCreateComposite
205793850ffSBarry Smith M*/
206793850ffSBarry Smith 
207793850ffSBarry Smith EXTERN_C_BEGIN
208793850ffSBarry Smith #undef __FUNCT__
209793850ffSBarry Smith #define __FUNCT__ "MatCreate_Composite"
210793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Composite(Mat A)
211793850ffSBarry Smith {
212793850ffSBarry Smith   Mat_Composite  *b;
213793850ffSBarry Smith   PetscErrorCode ierr;
214793850ffSBarry Smith 
215793850ffSBarry Smith   PetscFunctionBegin;
216793850ffSBarry Smith   ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
217793850ffSBarry Smith 
218793850ffSBarry Smith   ierr = PetscNew(Mat_Composite,&b);CHKERRQ(ierr);
219793850ffSBarry Smith   A->data = (void*)b;
220793850ffSBarry Smith 
221793850ffSBarry Smith   ierr = PetscMapInitialize(A->comm,&A->rmap);CHKERRQ(ierr);
222793850ffSBarry Smith   ierr = PetscMapInitialize(A->comm,&A->cmap);CHKERRQ(ierr);
223793850ffSBarry Smith 
224793850ffSBarry Smith   A->assembled     = PETSC_TRUE;
225793850ffSBarry Smith   A->preallocated  = PETSC_FALSE;
226793850ffSBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr);
227793850ffSBarry Smith   PetscFunctionReturn(0);
228793850ffSBarry Smith }
229793850ffSBarry Smith EXTERN_C_END
230793850ffSBarry Smith 
231793850ffSBarry Smith #undef __FUNCT__
232793850ffSBarry Smith #define __FUNCT__ "MatCreateComposite"
233793850ffSBarry Smith /*@C
234793850ffSBarry Smith    MatCreateComposite - Creates a matrix as the sum of zero or more matrices
235793850ffSBarry Smith 
236793850ffSBarry Smith   Collective on MPI_Comm
237793850ffSBarry Smith 
238793850ffSBarry Smith    Input Parameters:
239793850ffSBarry Smith +  comm - MPI communicator
240793850ffSBarry Smith .  nmat - number of matrices to put in
241793850ffSBarry Smith -  mats - the matrices
242793850ffSBarry Smith 
243793850ffSBarry Smith    Output Parameter:
244793850ffSBarry Smith .  A - the matrix
245793850ffSBarry Smith 
246793850ffSBarry Smith    Level: advanced
247793850ffSBarry Smith 
248793850ffSBarry Smith    Notes:
249793850ffSBarry Smith      Alternative construction
250793850ffSBarry Smith $       MatCreate(comm,&mat);
251793850ffSBarry Smith $       MatSetSizes(mat,m,n,M,N);
252793850ffSBarry Smith $       MatSetType(mat,MATCOMPOSITE);
253793850ffSBarry Smith $       MatCompositeAddMat(mat,mats[0]);
254793850ffSBarry Smith $       ....
255793850ffSBarry Smith $       MatCompositeAddMat(mat,mats[nmat-1]);
256793850ffSBarry Smith 
257793850ffSBarry Smith .seealso: MatDestroy(), MatMult(), MatCompositeAddMat()
258793850ffSBarry Smith 
259793850ffSBarry Smith @*/
260793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreateComposite(MPI_Comm comm,PetscInt nmat,const Mat *mats,Mat *mat)
261793850ffSBarry Smith {
262793850ffSBarry Smith   PetscErrorCode ierr;
263793850ffSBarry Smith   PetscInt       m,n,M,N,i;
264793850ffSBarry Smith 
265793850ffSBarry Smith   PetscFunctionBegin;
266793850ffSBarry Smith   if (nmat < 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Must pass in at least one matrix");
267f3f84630SBarry Smith   PetscValidPointer(mat,3);
268793850ffSBarry Smith 
269793850ffSBarry Smith   ierr = MatGetLocalSize(mats[0],&m,&n);CHKERRQ(ierr);
270793850ffSBarry Smith   ierr = MatGetSize(mats[0],&M,&N);CHKERRQ(ierr);
271793850ffSBarry Smith   ierr = MatCreate(comm,mat);CHKERRQ(ierr);
272793850ffSBarry Smith   ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr);
273793850ffSBarry Smith   ierr = MatSetType(*mat,MATCOMPOSITE);CHKERRQ(ierr);
274793850ffSBarry Smith   for (i=0; i<nmat; i++) {
275793850ffSBarry Smith     ierr = MatCompositeAddMat(*mat,mats[i]);CHKERRQ(ierr);
276793850ffSBarry Smith   }
277793850ffSBarry Smith   PetscFunctionReturn(0);
278793850ffSBarry Smith }
279793850ffSBarry Smith 
280793850ffSBarry Smith #undef __FUNCT__
281793850ffSBarry Smith #define __FUNCT__ "MatCompositeAddMat"
282793850ffSBarry Smith /*@
283793850ffSBarry Smith     MatCompositeAddMat - add another matrix to a composite matrix
284793850ffSBarry Smith 
285793850ffSBarry Smith    Collective on Mat
286793850ffSBarry Smith 
287793850ffSBarry Smith     Input Parameters:
288793850ffSBarry Smith +   mat - the composite matrix
289793850ffSBarry Smith -   smat - the partial matrix
290793850ffSBarry Smith 
291793850ffSBarry Smith    Level: advanced
292793850ffSBarry Smith 
293793850ffSBarry Smith .seealso: MatCreateComposite()
294793850ffSBarry Smith @*/
295793850ffSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCompositeAddMat(Mat mat,Mat smat)
296793850ffSBarry Smith {
297793850ffSBarry Smith   Mat_Composite     *shell = (Mat_Composite*)mat->data;
298793850ffSBarry Smith   PetscErrorCode    ierr;
299793850ffSBarry Smith   Mat_CompositeLink ilink,next;
300793850ffSBarry Smith 
301793850ffSBarry Smith   PetscFunctionBegin;
302793850ffSBarry Smith   PetscValidHeaderSpecific(mat,MAT_COOKIE,1);
303793850ffSBarry Smith   PetscValidHeaderSpecific(smat,MAT_COOKIE,2);
304793850ffSBarry Smith   ierr       = PetscNew(struct _Mat_CompositeLink,&ilink);CHKERRQ(ierr);
305793850ffSBarry Smith   ilink->next = 0;
306793850ffSBarry Smith   ilink->mat  = smat;
307793850ffSBarry Smith   ierr        = PetscObjectReference((PetscObject)smat);CHKERRQ(ierr);
308793850ffSBarry Smith 
309793850ffSBarry Smith   next = shell->head;
310793850ffSBarry Smith   if (!next) {
311793850ffSBarry Smith     shell->head  = ilink;
312793850ffSBarry Smith   } else {
313793850ffSBarry Smith     while (next->next) {
314793850ffSBarry Smith       next = next->next;
315793850ffSBarry Smith     }
316793850ffSBarry Smith     next->next      = ilink;
317793850ffSBarry Smith   }
318793850ffSBarry Smith   PetscFunctionReturn(0);
319793850ffSBarry Smith }
320793850ffSBarry Smith 
321