Actual source code: matadic.c
1: #define PETSCMAT_DLL
3: /*
4: ADIC matrix-free matrix implementation
5: */
7: #include private/matimpl.h
8: #include petscda.h
9: #include petscsnes.h
11: #include "adic/ad_utils.h"
14: typedef struct {
15: DA da;
16: Vec localu; /* point at which Jacobian is evaluated */
17: void *ctx;
18: SNES snes;
19: Vec diagonal; /* current matrix diagonal */
20: PetscTruth diagonalvalid; /* indicates if diagonal matches current base vector */
21: } Mat_DAAD;
25: PetscErrorCode MatAssemblyEnd_DAAD(Mat A,MatAssemblyType atype)
26: {
27: Mat_DAAD *a = (Mat_DAAD*)A->data;
29: Vec u;
32: a->diagonalvalid = PETSC_FALSE;
33: if (a->snes) {
34: SNESGetSolution(a->snes,&u);
35: DAGlobalToLocalBegin(a->da,u,INSERT_VALUES,a->localu);
36: DAGlobalToLocalEnd(a->da,u,INSERT_VALUES,a->localu);
37: }
38: return(0);
39: }
43: PetscErrorCode MatMult_DAAD(Mat A,Vec xx,Vec yy)
44: {
45: Mat_DAAD *a = (Mat_DAAD*)A->data;
46: Vec localxx;
50: DAGetLocalVector(a->da,&localxx);
51: DAGlobalToLocalBegin(a->da,xx,INSERT_VALUES,localxx);
52: DAGlobalToLocalEnd(a->da,xx,INSERT_VALUES,localxx);
53: DAMultiplyByJacobian1WithAD(a->da,a->localu,localxx,yy,a->ctx);
54: DARestoreLocalVector(a->da,&localxx);
55: return(0);
56: }
58: #include "../src/dm/da/daimpl.h"
62: PetscErrorCode MatGetDiagonal_DAAD(Mat A,Vec dd)
63: {
64: Mat_DAAD *a = (Mat_DAAD*)A->data;
66: int j,nI,gI,gtdof;
67: PetscScalar *avu,*ad_vustart,ad_f[2],*d;
68: DALocalInfo info;
69: MatStencil stencil;
70: void* *ad_vu;
74: /* get space for derivative object. */
75: DAGetAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
77: /* copy input vector into derivative object */
78: VecGetArray(a->localu,&avu);
79: for (j=0; j<gtdof; j++) {
80: ad_vustart[2*j] = avu[j];
81: ad_vustart[2*j+1] = 0.0;
82: }
83: VecRestoreArray(a->localu,&avu);
85: PetscADResetIndep();
86: PetscADIncrementTotalGradSize(1);
87: PetscADSetIndepDone();
89: VecGetArray(dd,&d);
91: DAGetLocalInfo(a->da,&info);
92: nI = 0;
93: for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
94: for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
95: for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
96: for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
97: gI = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
98: ad_vustart[1+2*gI] = 1.0;
99: (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
100: d[nI] = ad_f[1];
101: ad_vustart[1+2*gI] = 0.0;
102: nI++;
103: }
104: }
105: }
106: }
108: VecRestoreArray(dd,&d);
109: DARestoreAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
110: return(0);
111: }
116: PetscErrorCode MatSOR_DAAD(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx)
117: {
118: Mat_DAAD *a = (Mat_DAAD*)A->data;
120: int j,gtdof,nI,gI;
121: PetscScalar *avu,*av,*ad_vustart,ad_f[2],*d,*b;
122: Vec localxx,dd;
123: DALocalInfo info;
124: MatStencil stencil;
125: void* *ad_vu;
128: if (omega != 1.0) SETERRQ(PETSC_ERR_ARG_WRONG,"Currently only support omega of 1.0");
129: if (fshift) SETERRQ(PETSC_ERR_ARG_WRONG,"Currently do not support fshift");
130: if (its <= 0 || lits <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
132: if (!a->diagonal) {
133: DACreateGlobalVector(a->da,&a->diagonal);
134: }
135: if (!a->diagonalvalid) {
136: MatGetDiagonal(A,a->diagonal);
137: a->diagonalvalid = PETSC_TRUE;
138: }
139: dd = a->diagonal;
142: DAGetLocalVector(a->da,&localxx);
143: if (flag & SOR_ZERO_INITIAL_GUESS) {
144: VecSet(localxx,0.0);
145: } else {
146: DAGlobalToLocalBegin(a->da,xx,INSERT_VALUES,localxx);
147: DAGlobalToLocalEnd(a->da,xx,INSERT_VALUES,localxx);
148: }
150: /* get space for derivative object. */
151: DAGetAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
153: /* copy input vector into derivative object */
154: VecGetArray(a->localu,&avu);
155: VecGetArray(localxx,&av);
156: for (j=0; j<gtdof; j++) {
157: ad_vustart[2*j] = avu[j];
158: ad_vustart[2*j+1] = av[j];
159: }
160: VecRestoreArray(a->localu,&avu);
161: VecRestoreArray(localxx,&av);
163: PetscADResetIndep();
164: PetscADIncrementTotalGradSize(1);
165: PetscADSetIndepDone();
167: VecGetArray(dd,&d);
168: VecGetArray(bb,&b);
170: DAGetLocalInfo(a->da,&info);
171: while (its--) {
172: if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){
173: nI = 0;
174: for (stencil.k = info.zs; stencil.k<info.zs+info.zm; stencil.k++) {
175: for (stencil.j = info.ys; stencil.j<info.ys+info.ym; stencil.j++) {
176: for (stencil.i = info.xs; stencil.i<info.xs+info.xm; stencil.i++) {
177: for (stencil.c = 0; stencil.c<info.dof; stencil.c++) {
178: (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
179: gI = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
180: ad_vustart[1+2*gI] += (b[nI] - ad_f[1])/d[nI];
181: nI++;
182: }
183: }
184: }
185: }
186: }
187: if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){
188: nI = info.dof*info.xm*info.ym*info.zm - 1;
189: for (stencil.k = info.zs+info.zm-1; stencil.k>=info.zs; stencil.k--) {
190: for (stencil.j = info.ys+info.ym-1; stencil.j>=info.ys; stencil.j--) {
191: for (stencil.i = info.xs+info.xm-1; stencil.i>=info.xs; stencil.i--) {
192: for (stencil.c = info.dof-1; stencil.c>=0; stencil.c--) {
193: (*a->da->adicmf_lfi)(&info,&stencil,ad_vu,ad_f,a->ctx);
194: gI = stencil.c + (stencil.i - info.gxs)*info.dof + (stencil.j - info.gys)*info.dof*info.gxm + (stencil.k - info.gzs)*info.dof*info.gxm*info.gym;
195: ad_vustart[1+2*gI] += (b[nI] - ad_f[1])/d[nI];
196: nI--;
197: }
198: }
199: }
200: }
201: }
202: }
204: VecRestoreArray(dd,&d);
205: VecRestoreArray(bb,&b);
207: VecGetArray(localxx,&av);
208: for (j=0; j<gtdof; j++) {
209: av[j] = ad_vustart[2*j+1];
210: }
211: VecRestoreArray(localxx,&av);
212: DALocalToGlobal(a->da,localxx,INSERT_VALUES,xx);
214: DARestoreLocalVector(a->da,&localxx);
215: DARestoreAdicMFArray(a->da,PETSC_TRUE,(void **)&ad_vu,(void**)&ad_vustart,>dof);
216: return(0);
217: }
223: PetscErrorCode MatDestroy_DAAD(Mat A)
224: {
225: Mat_DAAD *a = (Mat_DAAD*)A->data;
229: DADestroy(a->da);
230: VecDestroy(a->localu);
231: if (a->diagonal) {VecDestroy(a->diagonal);}
232: PetscFree(a);
233: PetscObjectChangeTypeName((PetscObject)A,0);
234: PetscObjectComposeFunction((PetscObject)A,"MatMFFDSetBase_C","",PETSC_NULL);
235: PetscObjectComposeFunction((PetscObject)A,"MatDAADSetDA_C","",PETSC_NULL);
236: PetscObjectComposeFunction((PetscObject)A,"MatDAADSetSNES_C","",PETSC_NULL);
237: PetscObjectComposeFunction((PetscObject)A,"MatDAADSetCtx_C","",PETSC_NULL);
238: return(0);
239: }
241: /* -------------------------------------------------------------------*/
242: static struct _MatOps MatOps_Values = {0,
243: 0,
244: 0,
245: MatMult_DAAD,
246: /* 4*/ 0,
247: 0,
248: 0,
249: 0,
250: 0,
251: 0,
252: /*10*/ 0,
253: 0,
254: 0,
255: MatSOR_DAAD,
256: 0,
257: /*15*/ 0,
258: 0,
259: MatGetDiagonal_DAAD,
260: 0,
261: 0,
262: /*20*/ 0,
263: MatAssemblyEnd_DAAD,
264: 0,
265: 0,
266: /*24*/ 0,
267: 0,
268: 0,
269: 0,
270: 0,
271: /*29*/ 0,
272: 0,
273: 0,
274: 0,
275: 0,
276: /*34*/ 0,
277: 0,
278: 0,
279: 0,
280: 0,
281: /*39*/ 0,
282: 0,
283: 0,
284: 0,
285: 0,
286: /*44*/ 0,
287: 0,
288: 0,
289: 0,
290: 0,
291: /*49*/ 0,
292: 0,
293: 0,
294: 0,
295: 0,
296: /*54*/ 0,
297: 0,
298: 0,
299: 0,
300: 0,
301: /*59*/ 0,
302: MatDestroy_DAAD,
303: 0,
304: 0,
305: 0,
306: /*64*/ 0,
307: 0,
308: 0,
309: 0,
310: 0,
311: /*69*/ 0,
312: 0,
313: 0,
314: 0,
315: 0,
316: /*74*/ 0,
317: 0,
318: 0,
319: 0,
320: 0,
321: /*79*/ 0,
322: 0,
323: 0,
324: 0,
325: 0,
326: /*84*/ 0,
327: 0,
328: 0,
329: 0,
330: 0,
331: /*89*/ 0,
332: 0,
333: 0,
334: 0,
335: 0,
336: /*94*/ 0,
337: 0,
338: 0,
339: 0};
341: /* --------------------------------------------------------------------------------*/
346: PetscErrorCode MatMFFDSetBase_AD(Mat J,Vec U,Vec F)
347: {
349: Mat_DAAD *a = (Mat_DAAD*)J->data;
352: a->diagonalvalid = PETSC_FALSE;
353: DAGlobalToLocalBegin(a->da,U,INSERT_VALUES,a->localu);
354: DAGlobalToLocalEnd(a->da,U,INSERT_VALUES,a->localu);
355: return(0);
356: }
362: PetscErrorCode MatDAADSetDA_AD(Mat A,DA da)
363: {
364: Mat_DAAD *a = (Mat_DAAD*)A->data;
366: PetscInt nc,nx,ny,nz,Nx,Ny,Nz;
369: PetscObjectReference((PetscObject)da);
370: if (a->da) { DADestroy(a->da); }
371: a->da = da;
372: DAGetInfo(da,0,&Nx,&Ny,&Nz,0,0,0,&nc,0,0,0);
373: DAGetCorners(da,0,0,0,&nx,&ny,&nz);
374: A->rmap->n = A->cmap->n = nc*nx*ny*nz;
375: A->rmap->N = A->cmap->N = nc*Nx*Ny*Nz;
376: DACreateLocalVector(da,&a->localu);
377: return(0);
378: }
384: PetscErrorCode MatDAADSetSNES_AD(Mat A,SNES snes)
385: {
386: Mat_DAAD *a = (Mat_DAAD*)A->data;
389: a->snes = snes;
390: return(0);
391: }
397: PetscErrorCode MatDAADSetCtx_AD(Mat A,void *ctx)
398: {
399: Mat_DAAD *a = (Mat_DAAD*)A->data;
402: a->ctx = ctx;
403: return(0);
404: }
407: /*MC
408: MATDAAD - MATDAAD = "daad" - A matrix type that can do matrix-vector products using a local function that
409: is differentiated with ADIFOR or ADIC.
411: Level: intermediate
413: .seealso: MatCreateDAAD
414: M*/
419: PetscErrorCode MatCreate_DAAD(Mat B)
420: {
421: Mat_DAAD *b;
425: PetscNewLog(B,Mat_DAAD,&b);
426: B->data = (void*)b;
427: PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));
428:
429: PetscLayoutSetBlockSize(B->rmap,1);
430: PetscLayoutSetBlockSize(B->cmap,1);
431: PetscLayoutSetUp(B->rmap);
432: PetscLayoutSetUp(B->cmap);
434: PetscObjectChangeTypeName((PetscObject)B,MATDAAD);
435: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMFFDSetBase_C","MatMFFDSetBase_AD",MatMFFDSetBase_AD);
436: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetDA_C","MatDAADSetDA_AD",MatDAADSetDA_AD);
437: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetSNES_C","MatDAADSetSNES_AD",MatDAADSetSNES_AD);
438: PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetCtx_C","MatDAADSetCtx_AD",MatDAADSetCtx_AD);
439: PetscObjectChangeTypeName((PetscObject)B,MATDAAD);
440: return(0);
441: }
447: /*@C
448: MatDAADSetDA - Tells the matrix what DA it is using for layout and Jacobian.
450: Collective on Mat and DA
452: Input Parameters:
453: + mat - the matrix
454: - da - the DA
456: Level: intermediate
458: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD()
460: @*/
461: PetscErrorCode MatDAADSetDA(Mat A,DA da)
462: {
463: PetscErrorCode ierr,(*f)(Mat,void*);
468: PetscObjectQueryFunction((PetscObject)A,"MatDAADSetDA_C",(void (**)(void))&f);
469: if (f) {
470: (*f)(A,da);
471: }
472: return(0);
473: }
477: /*@C
478: MatDAADSetSNES - Tells the matrix what SNES it is using for the base U.
480: Collective on Mat and SNES
482: Input Parameters:
483: + mat - the matrix
484: - snes - the SNES
486: Level: intermediate
488: Notes: this is currently turned off for Fortran usage
490: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD(), MatDAADSetDA()
492: @*/
493: PetscErrorCode MatDAADSetSNES(Mat A,SNES snes)
494: {
495: PetscErrorCode ierr,(*f)(Mat,void*);
500: PetscObjectQueryFunction((PetscObject)A,"MatDAADSetSNES_C",(void (**)(void))&f);
501: if (f) {
502: (*f)(A,snes);
503: }
504: return(0);
505: }
509: /*@C
510: MatDAADSetCtx - Sets the user context for a DAAD (ADIC matrix-free) matrix.
512: Collective on Mat
514: Input Parameters:
515: + mat - the matrix
516: - ctx - the context
518: Level: intermediate
520: .seealso: MatCreate(), DASetLocalAdicMFFunction(), MatCreateDAAD(), MatDAADSetDA()
522: @*/
523: PetscErrorCode MatDAADSetCtx(Mat A,void *ctx)
524: {
525: PetscErrorCode ierr,(*f)(Mat,void*);
529: PetscObjectQueryFunction((PetscObject)A,"MatDAADSetCtx_C",(void (**)(void))&f);
530: if (f) {
531: (*f)(A,ctx);
532: }
533: return(0);
534: }
538: /*@C
539: MatCreateDAAD - Creates a matrix that can do matrix-vector products using a local
540: function that is differentiated with ADIFOR or ADIC.
542: Collective on DA
544: Input Parameters:
545: . da - the DA that defines the distribution of the vectors
547: Output Parameter:
548: . A - the matrix
550: Level: intermediate
552: Notes: this is currently turned off for Fortran
554: .seealso: MatCreate(), DASetLocalAdicMFFunction()
556: @*/
557: PetscErrorCode MatCreateDAAD(DA da,Mat *A)
558: {
560: MPI_Comm comm;
563: PetscObjectGetComm((PetscObject)da,&comm);
564: MatCreate(comm,A);
565: MatSetType(*A,MATDAAD);
566: MatDAADSetDA(*A,da);
567: return(0);
568: }
573: /*@
574: MatRegisterDAAD - Registers DAAD matrix type
576: Level: advanced
578: .seealso: MatCreateDAAD(), DASetLocalAdicMFFunction()
580: @*/
581: PetscErrorCode MatRegisterDAAD(void)
582: {
585: MatRegisterDynamic(MATDAAD,PETSC_NULL,"MatCreate_DAAD",MatCreate_DAAD);
586: return(0);
587: }