xref: /petsc/src/tao/matrix/adamat.c (revision 87f595a510d358797c1cc8101e6f6c6930cb072f)
1a7e14dcfSSatish Balay #include "adamat.h"                /*I  "mat.h"  I*/
2a7e14dcfSSatish Balay 
3a7e14dcfSSatish Balay #undef __FUNCT__
4a7e14dcfSSatish Balay #define __FUNCT__ "MatCreateADA"
5a7e14dcfSSatish Balay /*@C
6a7e14dcfSSatish Balay    MatCreateADA - Creates a matrix M=A^T D1 A + D2 where D1, D2 are diagonal
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay    Collective on matrix
9a7e14dcfSSatish Balay 
10a7e14dcfSSatish Balay    Input Parameters:
11a7e14dcfSSatish Balay +  mat - matrix of arbitrary type
12a7e14dcfSSatish Balay .  d1 - A vector with diagonal elements of D1
13a7e14dcfSSatish Balay -  d2 - A vector
14a7e14dcfSSatish Balay 
15a7e14dcfSSatish Balay    Output Parameters:
16a7e14dcfSSatish Balay .  J - New matrix whose operations are defined in terms of mat, D1, and D2.
17a7e14dcfSSatish Balay 
18a7e14dcfSSatish Balay    Notes:
19a7e14dcfSSatish Balay    The user provides the input data and is responsible for destroying
20a7e14dcfSSatish Balay    this data after matrix J has been destroyed.
21a7e14dcfSSatish Balay    The operation MatMult(A,D2,D1) must be well defined.
22a7e14dcfSSatish Balay    Before calling the operation MatGetDiagonal(), the function
23a7e14dcfSSatish Balay    MatADAComputeDiagonal() must be called.  The matrices A and D1 must
24a7e14dcfSSatish Balay    be the same during calls to MatADAComputeDiagonal() and
25a7e14dcfSSatish Balay    MatGetDiagonal().
26a7e14dcfSSatish Balay 
27a7e14dcfSSatish Balay    Level: developer
28a7e14dcfSSatish Balay 
29a7e14dcfSSatish Balay .seealso: MatCreate()
30a7e14dcfSSatish Balay @*/
31a7e14dcfSSatish Balay PetscErrorCode MatCreateADA(Mat mat,Vec d1, Vec d2, Mat *J)
32a7e14dcfSSatish Balay {
33a7e14dcfSSatish Balay   MPI_Comm     comm=((PetscObject)mat)->comm;
34a7e14dcfSSatish Balay   TaoMatADACtx ctx;
35a7e14dcfSSatish Balay   PetscErrorCode          ierr;
36a7e14dcfSSatish Balay   PetscInt nloc,n;
37a7e14dcfSSatish Balay 
38a7e14dcfSSatish Balay   PetscFunctionBegin;
39a7e14dcfSSatish Balay 
403c9e27cfSGeoffrey Irving   ierr = PetscNew(&ctx);CHKERRQ(ierr);
41a7e14dcfSSatish Balay 
42a7e14dcfSSatish Balay   ctx->A=mat;
43a7e14dcfSSatish Balay   ctx->D1=d1;
44a7e14dcfSSatish Balay   ctx->D2=d2;
45a7e14dcfSSatish Balay   if (d1){
46a7e14dcfSSatish Balay     ierr = VecDuplicate(d1,&ctx->W);CHKERRQ(ierr);
47a7e14dcfSSatish Balay     ierr =  PetscObjectReference((PetscObject)d1);CHKERRQ(ierr);
48a7e14dcfSSatish Balay   } else {
49a7e14dcfSSatish Balay     ctx->W=0;
50a7e14dcfSSatish Balay   }
51a7e14dcfSSatish Balay   if (d2){
52a7e14dcfSSatish Balay     ierr = VecDuplicate(d2,&ctx->W2);CHKERRQ(ierr);
53a7e14dcfSSatish Balay     ierr = VecDuplicate(d2,&ctx->ADADiag);CHKERRQ(ierr);
54a7e14dcfSSatish Balay     ierr =  PetscObjectReference((PetscObject)d2);CHKERRQ(ierr);
55a7e14dcfSSatish Balay   } else {
56a7e14dcfSSatish Balay     ctx->W2=0;
57a7e14dcfSSatish Balay     ctx->ADADiag=0;
58a7e14dcfSSatish Balay   }
59a7e14dcfSSatish Balay 
60a7e14dcfSSatish Balay   ctx->GotDiag=0;
61a7e14dcfSSatish Balay   ierr =  PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
62a7e14dcfSSatish Balay 
63a7e14dcfSSatish Balay   ierr=VecGetLocalSize(d2,&nloc);CHKERRQ(ierr);
64a7e14dcfSSatish Balay   ierr=VecGetSize(d2,&n);CHKERRQ(ierr);
65a7e14dcfSSatish Balay 
66a7e14dcfSSatish Balay   ierr = MatCreateShell(comm,nloc,nloc,n,n,ctx,J);CHKERRQ(ierr);
67a7e14dcfSSatish Balay 
68a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_MULT,(void(*)(void))MatMult_ADA);CHKERRQ(ierr);
69a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_DESTROY,(void(*)(void))MatDestroy_ADA);CHKERRQ(ierr);
70a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_VIEW,(void(*)(void))MatView_ADA);CHKERRQ(ierr);
71a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_MULT_TRANSPOSE,(void(*)(void))MatMultTranspose_ADA);CHKERRQ(ierr);
72a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_DIAGONAL_SET,(void(*)(void))MatDiagonalSet_ADA);CHKERRQ(ierr);
73a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_SHIFT,(void(*)(void))MatShift_ADA);CHKERRQ(ierr);
74a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_EQUAL,(void(*)(void))MatEqual_ADA);CHKERRQ(ierr);
75a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_SCALE,(void(*)(void))MatScale_ADA);CHKERRQ(ierr);
76a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_TRANSPOSE,(void(*)(void))MatTranspose_ADA);CHKERRQ(ierr);
77a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_GET_DIAGONAL,(void(*)(void))MatGetDiagonal_ADA);CHKERRQ(ierr);
78a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_GET_SUBMATRICES,(void(*)(void))MatGetSubMatrices_ADA);CHKERRQ(ierr);
79a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_NORM,(void(*)(void))MatNorm_ADA);CHKERRQ(ierr);
80a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_DUPLICATE,(void(*)(void))MatDuplicate_ADA);CHKERRQ(ierr);
81a7e14dcfSSatish Balay   ierr = MatShellSetOperation(*J,MATOP_GET_SUBMATRIX,(void(*)(void))MatGetSubMatrix_ADA);CHKERRQ(ierr);
82a7e14dcfSSatish Balay 
83a7e14dcfSSatish Balay   ierr = PetscLogObjectParent((PetscObject)(*J),(PetscObject)ctx->W); CHKERRQ(ierr);
84a7e14dcfSSatish Balay   ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)(*J)); CHKERRQ(ierr);
85a7e14dcfSSatish Balay 
86a7e14dcfSSatish Balay   ierr = MatSetOption(*J,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
87a7e14dcfSSatish Balay   PetscFunctionReturn(0);
88a7e14dcfSSatish Balay }
89a7e14dcfSSatish Balay 
90a7e14dcfSSatish Balay #undef __FUNCT__
91a7e14dcfSSatish Balay #define __FUNCT__ "MatMult_ADA"
92a7e14dcfSSatish Balay PetscErrorCode MatMult_ADA(Mat mat,Vec a,Vec y)
93a7e14dcfSSatish Balay {
94a7e14dcfSSatish Balay   TaoMatADACtx ctx;
95a7e14dcfSSatish Balay   PetscReal        one = 1.0;
96a7e14dcfSSatish Balay   PetscErrorCode           ierr;
97a7e14dcfSSatish Balay 
98a7e14dcfSSatish Balay   PetscFunctionBegin;
99a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
100a7e14dcfSSatish Balay 
101a7e14dcfSSatish Balay   ierr = MatMult(ctx->A,a,ctx->W);CHKERRQ(ierr);
102a7e14dcfSSatish Balay   if (ctx->D1){
103a7e14dcfSSatish Balay     ierr = VecPointwiseMult(ctx->W,ctx->D1,ctx->W);CHKERRQ(ierr);
104a7e14dcfSSatish Balay   }
105a7e14dcfSSatish Balay   ierr = MatMultTranspose(ctx->A,ctx->W,y);CHKERRQ(ierr);
106a7e14dcfSSatish Balay   if (ctx->D2){
107a7e14dcfSSatish Balay     ierr = VecPointwiseMult(ctx->W2, ctx->D2, a);CHKERRQ(ierr);
108a7e14dcfSSatish Balay     ierr = VecAXPY(y, one, ctx->W2);CHKERRQ(ierr);
109a7e14dcfSSatish Balay   }
110a7e14dcfSSatish Balay   PetscFunctionReturn(0);
111a7e14dcfSSatish Balay }
112a7e14dcfSSatish Balay 
113a7e14dcfSSatish Balay #undef __FUNCT__
114a7e14dcfSSatish Balay #define __FUNCT__ "MatMultTranspose_ADA"
115a7e14dcfSSatish Balay PetscErrorCode MatMultTranspose_ADA(Mat mat,Vec a,Vec y)
116a7e14dcfSSatish Balay {
117a7e14dcfSSatish Balay   PetscErrorCode ierr;
118a7e14dcfSSatish Balay 
119a7e14dcfSSatish Balay   PetscFunctionBegin;
120a7e14dcfSSatish Balay   ierr = MatMult_ADA(mat,a,y);CHKERRQ(ierr);
121a7e14dcfSSatish Balay   PetscFunctionReturn(0);
122a7e14dcfSSatish Balay }
123a7e14dcfSSatish Balay 
124a7e14dcfSSatish Balay #undef __FUNCT__
125a7e14dcfSSatish Balay #define __FUNCT__ "MatDiagonalSet_ADA"
126a7e14dcfSSatish Balay PetscErrorCode MatDiagonalSet_ADA(Vec D, Mat M)
127a7e14dcfSSatish Balay {
128a7e14dcfSSatish Balay   TaoMatADACtx ctx;
129a7e14dcfSSatish Balay   PetscReal        zero=0.0,one = 1.0;
130a7e14dcfSSatish Balay   PetscErrorCode   ierr;
131a7e14dcfSSatish Balay 
132a7e14dcfSSatish Balay   PetscFunctionBegin;
133a7e14dcfSSatish Balay   ierr = MatShellGetContext(M,(void **)&ctx);CHKERRQ(ierr);
134a7e14dcfSSatish Balay 
1356c23d075SBarry Smith   if (ctx->D2==NULL){
136a7e14dcfSSatish Balay     ierr = VecDuplicate(D,&ctx->D2);CHKERRQ(ierr);
137a7e14dcfSSatish Balay     ierr = VecSet(ctx->D2, zero);CHKERRQ(ierr);
138a7e14dcfSSatish Balay   }
139a7e14dcfSSatish Balay   ierr = VecAXPY(ctx->D2, one, D);CHKERRQ(ierr);
140a7e14dcfSSatish Balay 
141a7e14dcfSSatish Balay   PetscFunctionReturn(0);
142a7e14dcfSSatish Balay }
143a7e14dcfSSatish Balay 
144a7e14dcfSSatish Balay #undef __FUNCT__
145a7e14dcfSSatish Balay #define __FUNCT__ "MatDestroy_ADA"
146a7e14dcfSSatish Balay PetscErrorCode MatDestroy_ADA(Mat mat)
147a7e14dcfSSatish Balay {
148a7e14dcfSSatish Balay   PetscErrorCode          ierr;
149a7e14dcfSSatish Balay   TaoMatADACtx ctx;
150a7e14dcfSSatish Balay 
151a7e14dcfSSatish Balay   PetscFunctionBegin;
152a7e14dcfSSatish Balay   ierr=MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
153a7e14dcfSSatish Balay   if (ctx->W) {
154a7e14dcfSSatish Balay     ierr=VecDestroy(&ctx->W);CHKERRQ(ierr);
155a7e14dcfSSatish Balay   }
156a7e14dcfSSatish Balay   if (ctx->W2) {
157a7e14dcfSSatish Balay     ierr=VecDestroy(&ctx->W2);CHKERRQ(ierr);
158a7e14dcfSSatish Balay   }
159a7e14dcfSSatish Balay   if (ctx->ADADiag) {
160a7e14dcfSSatish Balay     ierr=VecDestroy(&ctx->ADADiag);CHKERRQ(ierr);
161a7e14dcfSSatish Balay   }
162a7e14dcfSSatish Balay   if (ctx->A) {
163a7e14dcfSSatish Balay     ierr=MatDestroy(&ctx->A);CHKERRQ(ierr);
164a7e14dcfSSatish Balay   }
165a7e14dcfSSatish Balay   if (ctx->D1) {
166a7e14dcfSSatish Balay     ierr=VecDestroy(&ctx->D1);CHKERRQ(ierr);
167a7e14dcfSSatish Balay   }
168a7e14dcfSSatish Balay   if (ctx->D2) {
169a7e14dcfSSatish Balay     ierr=VecDestroy(&ctx->D2);CHKERRQ(ierr);
170a7e14dcfSSatish Balay   }
171a7e14dcfSSatish Balay   ierr = PetscFree(ctx); CHKERRQ(ierr);
172a7e14dcfSSatish Balay   PetscFunctionReturn(0);
173a7e14dcfSSatish Balay }
174a7e14dcfSSatish Balay 
175a7e14dcfSSatish Balay #undef __FUNCT__
176a7e14dcfSSatish Balay #define __FUNCT__ "MatView_ADA"
177a7e14dcfSSatish Balay PetscErrorCode MatView_ADA(Mat mat,PetscViewer viewer)
178a7e14dcfSSatish Balay {
179a7e14dcfSSatish Balay 
180a7e14dcfSSatish Balay   PetscFunctionBegin;
181a7e14dcfSSatish Balay   PetscFunctionReturn(0);
182a7e14dcfSSatish Balay }
183a7e14dcfSSatish Balay 
184a7e14dcfSSatish Balay #undef __FUNCT__
185a7e14dcfSSatish Balay #define __FUNCT__ "MatShift_ADA"
186a7e14dcfSSatish Balay PetscErrorCode MatShift_ADA(Mat Y, PetscReal a)
187a7e14dcfSSatish Balay {
188a7e14dcfSSatish Balay   PetscErrorCode ierr;
189a7e14dcfSSatish Balay   TaoMatADACtx   ctx;
190a7e14dcfSSatish Balay 
191a7e14dcfSSatish Balay   PetscFunctionBegin;
192a7e14dcfSSatish Balay   ierr = MatShellGetContext(Y,(void **)&ctx);CHKERRQ(ierr);
193a7e14dcfSSatish Balay   ierr = VecShift(ctx->D2,a);CHKERRQ(ierr);
194a7e14dcfSSatish Balay   PetscFunctionReturn(0);
195a7e14dcfSSatish Balay }
196a7e14dcfSSatish Balay 
197a7e14dcfSSatish Balay #undef __FUNCT__
198a7e14dcfSSatish Balay #define __FUNCT__ "MatDuplicate_ADA"
199a7e14dcfSSatish Balay PetscErrorCode MatDuplicate_ADA(Mat mat,MatDuplicateOption op,Mat *M)
200a7e14dcfSSatish Balay {
201a7e14dcfSSatish Balay   PetscErrorCode    ierr;
202a7e14dcfSSatish Balay   TaoMatADACtx      ctx;
203a7e14dcfSSatish Balay   Mat               A2;
204a7e14dcfSSatish Balay   Vec               D1b=NULL,D2b;
205a7e14dcfSSatish Balay 
206a7e14dcfSSatish Balay   PetscFunctionBegin;
207a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
208a7e14dcfSSatish Balay   ierr = MatDuplicate(ctx->A,op,&A2);CHKERRQ(ierr);
209a7e14dcfSSatish Balay   if (ctx->D1){
210a7e14dcfSSatish Balay     ierr = VecDuplicate(ctx->D1,&D1b);CHKERRQ(ierr);
211a7e14dcfSSatish Balay     ierr = VecCopy(ctx->D1,D1b);CHKERRQ(ierr);
212a7e14dcfSSatish Balay   }
213a7e14dcfSSatish Balay   ierr = VecDuplicate(ctx->D2,&D2b);CHKERRQ(ierr);
214a7e14dcfSSatish Balay   ierr = VecCopy(ctx->D2,D2b);CHKERRQ(ierr);
215a7e14dcfSSatish Balay   ierr = MatCreateADA(A2,D1b,D2b,M);CHKERRQ(ierr);
216a7e14dcfSSatish Balay   if (ctx->D1){
217a7e14dcfSSatish Balay     ierr = PetscObjectDereference((PetscObject)D1b);CHKERRQ(ierr);
218a7e14dcfSSatish Balay   }
219a7e14dcfSSatish Balay   ierr = PetscObjectDereference((PetscObject)D2b);CHKERRQ(ierr);
220a7e14dcfSSatish Balay   ierr = PetscObjectDereference((PetscObject)A2);CHKERRQ(ierr);
221a7e14dcfSSatish Balay 
222a7e14dcfSSatish Balay   PetscFunctionReturn(0);
223a7e14dcfSSatish Balay }
224a7e14dcfSSatish Balay 
225a7e14dcfSSatish Balay #undef __FUNCT__
226a7e14dcfSSatish Balay #define __FUNCT__ "MatEqual_ADA"
227a7e14dcfSSatish Balay PetscErrorCode MatEqual_ADA(Mat A,Mat B,PetscBool *flg)
228a7e14dcfSSatish Balay {
229a7e14dcfSSatish Balay   PetscErrorCode    ierr;
230a7e14dcfSSatish Balay   TaoMatADACtx  ctx1,ctx2;
231a7e14dcfSSatish Balay 
232a7e14dcfSSatish Balay   PetscFunctionBegin;
233a7e14dcfSSatish Balay   ierr = MatShellGetContext(A,(void **)&ctx1);CHKERRQ(ierr);
234a7e14dcfSSatish Balay   ierr = MatShellGetContext(B,(void **)&ctx2);CHKERRQ(ierr);
235a7e14dcfSSatish Balay   ierr = VecEqual(ctx1->D2,ctx2->D2,flg);CHKERRQ(ierr);
236a7e14dcfSSatish Balay   if (*flg==PETSC_TRUE){
237a7e14dcfSSatish Balay     ierr = VecEqual(ctx1->D1,ctx2->D1,flg);CHKERRQ(ierr);
238a7e14dcfSSatish Balay   }
239a7e14dcfSSatish Balay   if (*flg==PETSC_TRUE){
240a7e14dcfSSatish Balay     ierr = MatEqual(ctx1->A,ctx2->A,flg);CHKERRQ(ierr);
241a7e14dcfSSatish Balay   }
242a7e14dcfSSatish Balay   PetscFunctionReturn(0);
243a7e14dcfSSatish Balay }
244a7e14dcfSSatish Balay 
245a7e14dcfSSatish Balay #undef __FUNCT__
246a7e14dcfSSatish Balay #define __FUNCT__ "MatScale_ADA"
247a7e14dcfSSatish Balay PetscErrorCode MatScale_ADA(Mat mat, PetscReal a)
248a7e14dcfSSatish Balay {
249a7e14dcfSSatish Balay   PetscErrorCode   ierr;
250a7e14dcfSSatish Balay   TaoMatADACtx ctx;
251a7e14dcfSSatish Balay 
252a7e14dcfSSatish Balay   PetscFunctionBegin;
253a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
254a7e14dcfSSatish Balay   ierr = VecScale(ctx->D1,a);CHKERRQ(ierr);
255a7e14dcfSSatish Balay   if (ctx->D2){
256a7e14dcfSSatish Balay     ierr = VecScale(ctx->D2,a);CHKERRQ(ierr);
257a7e14dcfSSatish Balay   }
258a7e14dcfSSatish Balay   PetscFunctionReturn(0);
259a7e14dcfSSatish Balay }
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay #undef __FUNCT__
262a7e14dcfSSatish Balay #define __FUNCT__ "MatTranspose_ADA"
263a7e14dcfSSatish Balay PetscErrorCode MatTranspose_ADA(Mat mat,Mat *B)
264a7e14dcfSSatish Balay {
265a7e14dcfSSatish Balay   PetscErrorCode ierr;
266a7e14dcfSSatish Balay   TaoMatADACtx ctx;
267a7e14dcfSSatish Balay 
268a7e14dcfSSatish Balay   PetscFunctionBegin;
269a7e14dcfSSatish Balay   if (*B){
270a7e14dcfSSatish Balay     ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
271a7e14dcfSSatish Balay     ierr = MatDuplicate(mat,MAT_COPY_VALUES,B);CHKERRQ(ierr);
272a7e14dcfSSatish Balay   }
273a7e14dcfSSatish Balay   PetscFunctionReturn(0);
274a7e14dcfSSatish Balay }
275a7e14dcfSSatish Balay 
276a7e14dcfSSatish Balay #undef __FUNCT__
277a7e14dcfSSatish Balay #define __FUNCT__ "MatADAComputeDiagonal"
278a7e14dcfSSatish Balay PetscErrorCode MatADAComputeDiagonal(Mat mat)
279a7e14dcfSSatish Balay {
280a7e14dcfSSatish Balay   PetscErrorCode ierr;
281a7e14dcfSSatish Balay   PetscInt          i,m,n,low,high;
282a7e14dcfSSatish Balay   PetscReal       *dtemp,*dptr;
283a7e14dcfSSatish Balay   TaoMatADACtx ctx;
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay   PetscFunctionBegin;
286a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
287a7e14dcfSSatish Balay 
288a7e14dcfSSatish Balay   ierr = MatGetOwnershipRange(mat, &low, &high);CHKERRQ(ierr);
289a7e14dcfSSatish Balay   ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr);
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay   ierr = PetscMalloc( n*sizeof(PetscReal),&dtemp ); CHKERRQ(ierr);
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay   for (i=0; i<n; i++){
294a7e14dcfSSatish Balay     ierr = MatGetColumnVector(ctx->A, ctx->W, i);CHKERRQ(ierr);
295a7e14dcfSSatish Balay     ierr = VecPointwiseMult(ctx->W,ctx->W,ctx->W);CHKERRQ(ierr);
296a7e14dcfSSatish Balay     ierr = VecDotBegin(ctx->D1, ctx->W,dtemp+i);CHKERRQ(ierr);
297a7e14dcfSSatish Balay   }
298a7e14dcfSSatish Balay   for (i=0; i<n; i++){
299a7e14dcfSSatish Balay     ierr = VecDotEnd(ctx->D1, ctx->W,dtemp+i);CHKERRQ(ierr);
300a7e14dcfSSatish Balay   }
301a7e14dcfSSatish Balay 
302a7e14dcfSSatish Balay   ierr = VecGetArray(ctx->ADADiag,&dptr);CHKERRQ(ierr);
303a7e14dcfSSatish Balay   for (i=low; i<high; i++){
304a7e14dcfSSatish Balay     dptr[i-low]= dtemp[i];
305a7e14dcfSSatish Balay   }
306a7e14dcfSSatish Balay   ierr = VecRestoreArray(ctx->ADADiag,&dptr);CHKERRQ(ierr);
307a7e14dcfSSatish Balay   if (dtemp) {
308a7e14dcfSSatish Balay     ierr = PetscFree(dtemp); CHKERRQ(ierr);
309a7e14dcfSSatish Balay   }
310a7e14dcfSSatish Balay   PetscFunctionReturn(0);
311a7e14dcfSSatish Balay }
312a7e14dcfSSatish Balay 
313a7e14dcfSSatish Balay #undef __FUNCT__
314a7e14dcfSSatish Balay #define __FUNCT__ "MatGetDiagonal_ADA"
315a7e14dcfSSatish Balay PetscErrorCode MatGetDiagonal_ADA(Mat mat,Vec v)
316a7e14dcfSSatish Balay {
317a7e14dcfSSatish Balay   PetscErrorCode      ierr;
318a7e14dcfSSatish Balay   PetscReal       one=1.0;
319a7e14dcfSSatish Balay   TaoMatADACtx ctx;
320a7e14dcfSSatish Balay 
321a7e14dcfSSatish Balay   PetscFunctionBegin;
322a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
323a7e14dcfSSatish Balay   ierr = MatADAComputeDiagonal(mat); CHKERRQ(ierr);
324a7e14dcfSSatish Balay   ierr=VecCopy(ctx->ADADiag,v);CHKERRQ(ierr);
325a7e14dcfSSatish Balay   if (ctx->D2){
326a7e14dcfSSatish Balay     ierr=VecAXPY(v, one, ctx->D2);CHKERRQ(ierr);
327a7e14dcfSSatish Balay   }
328a7e14dcfSSatish Balay 
329a7e14dcfSSatish Balay   PetscFunctionReturn(0);
330a7e14dcfSSatish Balay }
331a7e14dcfSSatish Balay 
332a7e14dcfSSatish Balay #undef __FUNCT__
333a7e14dcfSSatish Balay #define __FUNCT__ "MatGetSubMatrices_ADA"
334a7e14dcfSSatish Balay PetscErrorCode MatGetSubMatrices_ADA(Mat A,PetscInt n, IS *irow,IS *icol,MatReuse scall,Mat **B)
335a7e14dcfSSatish Balay {
336a7e14dcfSSatish Balay   PetscErrorCode ierr;
337a7e14dcfSSatish Balay   PetscInt i;
338a7e14dcfSSatish Balay 
339a7e14dcfSSatish Balay   PetscFunctionBegin;
340a7e14dcfSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
341a7e14dcfSSatish Balay     ierr = PetscMalloc( (n+1)*sizeof(Mat),B );CHKERRQ(ierr);
342a7e14dcfSSatish Balay   }
343a7e14dcfSSatish Balay 
344a7e14dcfSSatish Balay   for ( i=0; i<n; i++ ) {
345a7e14dcfSSatish Balay     ierr = MatGetSubMatrix_ADA(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
346a7e14dcfSSatish Balay   }
347a7e14dcfSSatish Balay   PetscFunctionReturn(0);
348a7e14dcfSSatish Balay }
349a7e14dcfSSatish Balay 
350a7e14dcfSSatish Balay #undef __FUNCT__
351a7e14dcfSSatish Balay #define __FUNCT__ "MatGetSubMatrix_ADA"
352a7e14dcfSSatish Balay PetscErrorCode MatGetSubMatrix_ADA(Mat mat,IS isrow,IS iscol,MatReuse cll,
353a7e14dcfSSatish Balay 			Mat *newmat)
354a7e14dcfSSatish Balay {
355a7e14dcfSSatish Balay   PetscErrorCode          ierr;
356a7e14dcfSSatish Balay   PetscInt low,high;
357a7e14dcfSSatish Balay   PetscInt          n,nlocal,i;
358a7e14dcfSSatish Balay   const PetscInt          *iptr;
359a7e14dcfSSatish Balay   PetscReal       *dptr,*ddptr,zero=0.0;
360a7e14dcfSSatish Balay   VecType      type_name;
361a7e14dcfSSatish Balay   IS           ISrow;
362a7e14dcfSSatish Balay   Vec          D1,D2;
363a7e14dcfSSatish Balay   Mat          Atemp;
364a7e14dcfSSatish Balay   TaoMatADACtx ctx;
365a7e14dcfSSatish Balay 
366a7e14dcfSSatish Balay   PetscFunctionBegin;
367a7e14dcfSSatish Balay 
368a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
369a7e14dcfSSatish Balay 
370a7e14dcfSSatish Balay   ierr = MatGetOwnershipRange(ctx->A,&low,&high);CHKERRQ(ierr);
371a7e14dcfSSatish Balay   ierr = ISCreateStride(((PetscObject)mat)->comm,high-low,low,1,&ISrow);CHKERRQ(ierr);
372a7e14dcfSSatish Balay   ierr = MatGetSubMatrix(ctx->A,ISrow,iscol,cll,&Atemp);CHKERRQ(ierr);
373a7e14dcfSSatish Balay   ierr = ISDestroy(&ISrow);CHKERRQ(ierr);
374a7e14dcfSSatish Balay 
375a7e14dcfSSatish Balay   if (ctx->D1){
376a7e14dcfSSatish Balay     ierr=VecDuplicate(ctx->D1,&D1);CHKERRQ(ierr);
377a7e14dcfSSatish Balay     ierr=VecCopy(ctx->D1,D1);CHKERRQ(ierr);
378a7e14dcfSSatish Balay   } else {
3796c23d075SBarry Smith     D1=NULL;
380a7e14dcfSSatish Balay   }
381a7e14dcfSSatish Balay 
382a7e14dcfSSatish Balay   if (ctx->D2){
383a7e14dcfSSatish Balay     ierr=ISGetSize(isrow,&n);CHKERRQ(ierr);
384a7e14dcfSSatish Balay     ierr=ISGetLocalSize(isrow,&nlocal);CHKERRQ(ierr);
385a7e14dcfSSatish Balay     ierr=VecCreate(((PetscObject)(ctx->D2))->comm,&D2);CHKERRQ(ierr);
386a7e14dcfSSatish Balay     ierr=VecGetType(ctx->D2,&type_name);CHKERRQ(ierr);
387a7e14dcfSSatish Balay     ierr=VecSetSizes(D2,nlocal,n);CHKERRQ(ierr);
388a7e14dcfSSatish Balay     ierr=VecSetType(D2,type_name);CHKERRQ(ierr);
389a7e14dcfSSatish Balay     ierr=VecSet(D2, zero);CHKERRQ(ierr);
390a7e14dcfSSatish Balay     ierr=VecGetArray(ctx->D2, &dptr); CHKERRQ(ierr);
391a7e14dcfSSatish Balay     ierr=VecGetArray(D2, &ddptr); CHKERRQ(ierr);
392a7e14dcfSSatish Balay     ierr=ISGetIndices(isrow,&iptr); CHKERRQ(ierr);
393a7e14dcfSSatish Balay     for (i=0;i<nlocal;i++){
394a7e14dcfSSatish Balay       ddptr[i] = dptr[iptr[i]-low];
395a7e14dcfSSatish Balay     }
396a7e14dcfSSatish Balay     ierr=ISRestoreIndices(isrow,&iptr); CHKERRQ(ierr);
397a7e14dcfSSatish Balay     ierr=VecRestoreArray(D2, &ddptr); CHKERRQ(ierr);
398a7e14dcfSSatish Balay     ierr=VecRestoreArray(ctx->D2, &dptr); CHKERRQ(ierr);
399a7e14dcfSSatish Balay 
400a7e14dcfSSatish Balay   } else {
4016c23d075SBarry Smith     D2=NULL;
402a7e14dcfSSatish Balay   }
403a7e14dcfSSatish Balay 
404a7e14dcfSSatish Balay   ierr = MatCreateADA(Atemp,D1,D2,newmat);CHKERRQ(ierr);
405a7e14dcfSSatish Balay   ierr = MatShellGetContext(*newmat,(void **)&ctx);CHKERRQ(ierr);
406a7e14dcfSSatish Balay   ierr = PetscObjectDereference((PetscObject)Atemp);CHKERRQ(ierr);
407a7e14dcfSSatish Balay   if (ctx->D1){
408a7e14dcfSSatish Balay     ierr = PetscObjectDereference((PetscObject)D1);CHKERRQ(ierr);
409a7e14dcfSSatish Balay   }
410a7e14dcfSSatish Balay   if (ctx->D2){
411a7e14dcfSSatish Balay     ierr = PetscObjectDereference((PetscObject)D2);CHKERRQ(ierr);
412a7e14dcfSSatish Balay   }
413a7e14dcfSSatish Balay   PetscFunctionReturn(0);
414a7e14dcfSSatish Balay }
415a7e14dcfSSatish Balay 
416a7e14dcfSSatish Balay #undef __FUNCT__
417a7e14dcfSSatish Balay #define __FUNCT__ "MatGetRowADA"
418a7e14dcfSSatish Balay PetscErrorCode MatGetRowADA(Mat mat,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscReal **vals)
419a7e14dcfSSatish Balay {
420a7e14dcfSSatish Balay   PetscErrorCode ierr;
421a7e14dcfSSatish Balay   PetscInt m,n;
422a7e14dcfSSatish Balay 
423a7e14dcfSSatish Balay   PetscFunctionBegin;
424a7e14dcfSSatish Balay   ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr);
425a7e14dcfSSatish Balay 
426a7e14dcfSSatish Balay   if (*ncols>0){
427a7e14dcfSSatish Balay     ierr = PetscMalloc( (*ncols)*sizeof(PetscInt),cols );CHKERRQ(ierr);
428a7e14dcfSSatish Balay     ierr = PetscMalloc( (*ncols)*sizeof(PetscReal),vals );CHKERRQ(ierr);
429a7e14dcfSSatish Balay   } else {
4306c23d075SBarry Smith     *cols=NULL;
4316c23d075SBarry Smith     *vals=NULL;
432a7e14dcfSSatish Balay   }
433a7e14dcfSSatish Balay 
434a7e14dcfSSatish Balay   PetscFunctionReturn(0);
435a7e14dcfSSatish Balay }
436a7e14dcfSSatish Balay 
437a7e14dcfSSatish Balay #undef __FUNCT__
438a7e14dcfSSatish Balay #define __FUNCT__ "MatRestoreRowADA"
439a7e14dcfSSatish Balay PetscErrorCode MatRestoreRowADA(Mat mat,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscReal **vals)
440a7e14dcfSSatish Balay {
441a7e14dcfSSatish Balay   PetscErrorCode ierr;
442a7e14dcfSSatish Balay   PetscFunctionBegin;
443a7e14dcfSSatish Balay   if (*ncols>0){
444a7e14dcfSSatish Balay     ierr = PetscFree(*cols);  CHKERRQ(ierr);
445a7e14dcfSSatish Balay     ierr = PetscFree(*vals);  CHKERRQ(ierr);
446a7e14dcfSSatish Balay   }
4476c23d075SBarry Smith   *cols=NULL;
4486c23d075SBarry Smith   *vals=NULL;
449a7e14dcfSSatish Balay   PetscFunctionReturn(0);
450a7e14dcfSSatish Balay }
451a7e14dcfSSatish Balay 
452a7e14dcfSSatish Balay #undef __FUNCT__
453a7e14dcfSSatish Balay #define __FUNCT__ "MatGetColumnVectorADA"
454a7e14dcfSSatish Balay PetscErrorCode MatGetColumnVector_ADA(Mat mat,Vec Y, PetscInt col)
455a7e14dcfSSatish Balay {
456a7e14dcfSSatish Balay   PetscErrorCode    ierr;
457a7e14dcfSSatish Balay   PetscInt low,high;
458a7e14dcfSSatish Balay   PetscReal zero=0.0,one=1.0;
459a7e14dcfSSatish Balay 
460a7e14dcfSSatish Balay   PetscFunctionBegin;
461a7e14dcfSSatish Balay   ierr=VecSet(Y, zero);CHKERRQ(ierr);
462a7e14dcfSSatish Balay   ierr=VecGetOwnershipRange(Y,&low,&high);CHKERRQ(ierr);
463a7e14dcfSSatish Balay   if (col>=low && col<high){
464a7e14dcfSSatish Balay     ierr=VecSetValue(Y,col,one,INSERT_VALUES);CHKERRQ(ierr);
465a7e14dcfSSatish Balay   }
466a7e14dcfSSatish Balay   ierr=VecAssemblyBegin(Y);CHKERRQ(ierr);
467a7e14dcfSSatish Balay   ierr=VecAssemblyEnd(Y);CHKERRQ(ierr);
468a7e14dcfSSatish Balay   ierr=MatMult_ADA(mat,Y,Y);CHKERRQ(ierr);
469a7e14dcfSSatish Balay 
470a7e14dcfSSatish Balay   PetscFunctionReturn(0);
471a7e14dcfSSatish Balay }
472a7e14dcfSSatish Balay 
473a7e14dcfSSatish Balay PetscErrorCode MatConvert_ADA(Mat mat,MatType newtype,Mat *NewMat)
474a7e14dcfSSatish Balay {
475a7e14dcfSSatish Balay   PetscErrorCode ierr;
476a7e14dcfSSatish Balay   PetscMPIInt    size;
477a7e14dcfSSatish Balay   PetscBool      sametype, issame, isdense, isseqdense;
478a7e14dcfSSatish Balay   TaoMatADACtx   ctx;
479a7e14dcfSSatish Balay 
480a7e14dcfSSatish Balay   PetscFunctionBegin;
481a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
482*87f595a5SBarry Smith   ierr = MPI_Comm_size(((PetscObject)mat)->comm,&size);CHKERRQ(ierr);
483a7e14dcfSSatish Balay 
484a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr);
485a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)mat,MATSAME,&issame); CHKERRQ(ierr);
486a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIDENSE,&isdense); CHKERRQ(ierr);
487a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQDENSE,&isseqdense); CHKERRQ(ierr);
488a7e14dcfSSatish Balay 
489a7e14dcfSSatish Balay   if (sametype || issame) {
490a7e14dcfSSatish Balay     ierr=MatDuplicate(mat,MAT_COPY_VALUES,NewMat);CHKERRQ(ierr);
491a7e14dcfSSatish Balay   } else if (isdense) {
492a7e14dcfSSatish Balay     PetscInt  i,j,low,high,m,n,M,N;
493a7e14dcfSSatish Balay     PetscReal *dptr;
494a7e14dcfSSatish Balay     Vec       X;
495a7e14dcfSSatish Balay 
496a7e14dcfSSatish Balay     ierr = VecDuplicate(ctx->D2,&X);CHKERRQ(ierr);
497a7e14dcfSSatish Balay     ierr=MatGetSize(mat,&M,&N);CHKERRQ(ierr);
498a7e14dcfSSatish Balay     ierr=MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr);
499*87f595a5SBarry Smith     ierr = MatCreateDense(((PetscObject)mat)->comm,m,m,N,N,NULL,NewMat);CHKERRQ(ierr);
500a7e14dcfSSatish Balay     ierr = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(ierr);
501a7e14dcfSSatish Balay     for (i=0;i<M;i++){
502a7e14dcfSSatish Balay       ierr = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(ierr);
503a7e14dcfSSatish Balay       ierr = VecGetArray(X,&dptr);CHKERRQ(ierr);
504a7e14dcfSSatish Balay       for (j=0; j<high-low; j++){
505a7e14dcfSSatish Balay         ierr = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(ierr);
506a7e14dcfSSatish Balay       }
507a7e14dcfSSatish Balay       ierr=VecRestoreArray(X,&dptr);CHKERRQ(ierr);
508a7e14dcfSSatish Balay     }
509a7e14dcfSSatish Balay     ierr=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
510a7e14dcfSSatish Balay     ierr=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
511a7e14dcfSSatish Balay     ierr = VecDestroy(&X);CHKERRQ(ierr);
512a7e14dcfSSatish Balay   } else if (isseqdense && size==1){
513a7e14dcfSSatish Balay     PetscInt   i,j,low,high,m,n,M,N;
514a7e14dcfSSatish Balay     PetscReal *dptr;
515a7e14dcfSSatish Balay     Vec       X;
516a7e14dcfSSatish Balay 
517a7e14dcfSSatish Balay     ierr = VecDuplicate(ctx->D2,&X);CHKERRQ(ierr);
518a7e14dcfSSatish Balay     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
519a7e14dcfSSatish Balay     ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr);
520*87f595a5SBarry Smith     ierr = MatCreateSeqDense(((PetscObject)mat)->comm,N,N,NULL,NewMat); CHKERRQ(ierr);
521a7e14dcfSSatish Balay     ierr = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(ierr);
522a7e14dcfSSatish Balay     for (i=0;i<M;i++){
523a7e14dcfSSatish Balay       ierr = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(ierr);
524a7e14dcfSSatish Balay       ierr = VecGetArray(X,&dptr);CHKERRQ(ierr);
525a7e14dcfSSatish Balay       for (j=0; j<high-low; j++){
526a7e14dcfSSatish Balay         ierr = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(ierr);
527a7e14dcfSSatish Balay       }
528a7e14dcfSSatish Balay       ierr=VecRestoreArray(X,&dptr);CHKERRQ(ierr);
529a7e14dcfSSatish Balay     }
530a7e14dcfSSatish Balay     ierr=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
531a7e14dcfSSatish Balay     ierr=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
532a7e14dcfSSatish Balay     ierr=VecDestroy(&X);CHKERRQ(ierr);
533*87f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,1,"No support to convert objects to that type");
534a7e14dcfSSatish Balay   PetscFunctionReturn(0);
535a7e14dcfSSatish Balay }
536a7e14dcfSSatish Balay 
537a7e14dcfSSatish Balay #undef __FUNCT__
538a7e14dcfSSatish Balay #define __FUNCT__ "MatNorm_ADA"
539a7e14dcfSSatish Balay PetscErrorCode MatNorm_ADA(Mat mat,NormType type,PetscReal *norm)
540a7e14dcfSSatish Balay {
541a7e14dcfSSatish Balay   PetscErrorCode ierr;
542a7e14dcfSSatish Balay   TaoMatADACtx   ctx;
543a7e14dcfSSatish Balay 
544a7e14dcfSSatish Balay   PetscFunctionBegin;
545a7e14dcfSSatish Balay   ierr = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(ierr);
546a7e14dcfSSatish Balay   if (type == NORM_FROBENIUS) {
547a7e14dcfSSatish Balay     *norm = 1.0;
548a7e14dcfSSatish Balay   } else if (type == NORM_1 || type == NORM_INFINITY) {
549a7e14dcfSSatish Balay     *norm = 1.0;
550*87f595a5SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
551a7e14dcfSSatish Balay   PetscFunctionReturn(0);
552a7e14dcfSSatish Balay }
553