Actual source code: adelement.c
1: #ifdef ad_GRAD_MAX
2: #undef ad_GRAD_MAX
3: #endif
4: #define ad_GRAD_MAX 4
6: #include "taodaapplication.h" /* taodaapplication.h */
7: #include "taoapp.h"
9: //#include "ad_deriv.h"
11: /* Function Gradient Evaluation over single element */
12: typedef struct {
13: int (*computeadicfunctiongradient)(int[2],DERIV_TYPE[4],DERIV_TYPE*,void*);
14: void *elementfgctx;
15: int elementfgflops;
16: DERIV_TYPE adX[4];
17: } TaoDA2D1DOFADICFGCtx;
22: static int TaoDA2dLoopADFunctionGradient(TAO_APPLICATION tao, DA da, Vec X, double *f, Vec G, void * ctx) {
24: TaoDA2D1DOFADICFGCtx *myapp = (TaoDA2D1DOFADICFGCtx*) ctx;
25: MPI_Comm comm;
26: Vec localX, localG;
27: int info, i, j, coor[2];
28: int xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye;
29: PetscScalar **x, **g;
30: PetscScalar floc = 0.0;
31: PetscScalar zero = 0.0;
32: DERIV_TYPE adF,*adX=myapp->adX;
34: info = DAGetLocalVector(da, &localX); CHKERRQ(info);
35: info = DAGetLocalVector(da, &localG); CHKERRQ(info);
36: info = VecSet(G, zero); CHKERRQ(info);
37: info = VecSet(localG, zero); CHKERRQ(info);
39: info = DAGlobalToLocalBegin(da, X, INSERT_VALUES, localX); CHKERRQ(info);
40: info = DAGlobalToLocalEnd(da, X, INSERT_VALUES, localX); CHKERRQ(info);
42: info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info);
43: info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info);
45: info = DAGetCorners(da, &xs, &ys, PETSC_NULL, &xm, &ym, PETSC_NULL); CHKERRQ(info);
46: info = DAGetGhostCorners(da, &gxs, &gys, PETSC_NULL, &gxm, &gym, PETSC_NULL); CHKERRQ(info);
48: xe = gxs + gxm - 1;
49: ye = gys + gym - 1;
51: for (j = ys; j < ye; j++) {
52: for (i = xs; i < xe; i++) {
54: DERIV_val(adX[0]) = x[j][i];
55: DERIV_val(adX[1]) = x[j][i+1];
56: DERIV_val(adX[2]) = x[j+1][i];
57: DERIV_val(adX[3]) = x[j+1][i+1];
58: coor[0] = i; coor[1] = j;
60: info = myapp->computeadicfunctiongradient(coor,adX,&adF,myapp->elementfgctx);
61: CHKERRQ(info);
63: floc += DERIV_val(adF);
65: g[j][i] += DERIV_grad(adF)[0];
66: g[j][i+1] += DERIV_grad(adF)[1];
67: g[j+1][i] += DERIV_grad(adF)[2];
68: g[j+1][i+1] += DERIV_grad(adF)[3];
69: }
70: }
72: PetscLogFlops((ye-ys)*(xe-xs)*(myapp->elementfgflops + 5));
74: PetscObjectGetComm((PetscObject)da,&comm); CHKERRQ(info);
75: info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, comm); CHKERRQ(info);
77: info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info);
78: info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info);
80: info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info);
81: info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info);
83: info = DARestoreLocalVector(da, &localX); CHKERRQ(info);
84: info = DARestoreLocalVector(da, &localG); CHKERRQ(info);
86: return(0);
87: } /* TaoDA2dLoopADFunctionGradient */
91: static int TaoShutDownADICQQQQ(void* ctx){
93: ad_AD_Final();
94: return(0);
95: }
99: /*@
100: DAAppSetADElementFunctionGradient - Set routine that evaluates the
101: local part of a function on a 2-dimensional DA with 1 degree of freedom.
103: Collective on TAO_APPLICATION
105: Input Parameters:
106: + daapp - the TAO_DA_APPLICATION solver context
107: . funcgrad - local function gradient routine
108: . flops - the number of flops done performed in the funcgrad routine
109: - fgctx - [optional] user-defined context for private data for the evaluation.
111: Calling sequence of funcgrad:
112: $ int funcgrad(int coordinates[2], PetscScalar x[4], double *f, PetscScalar g[4], void* ctx)
114: + coord - the global coordinates [i j] in each direction of the DA
115: . x - the variables on the DA ( da[j][i], da[j][j+1], da[j+1][i], da[j+1][i+1] ) (bottom left, bottom right, top left, top right)
116: . g - the ADIC differentiated objective function with respect to each variable
117: - ctx - user defined context
118:
119: Note: This function requires ADIC to be installed and the ADIC-specific variables to be set in
120: $TAO_DIR/bmake/packages.$PETSC_ARCH
122: Level: intermediate
124: .keywords: DA, gradient, ADIC
126: .seealso: DAAppSetObjectiveAndGradientRoutine(), DAAppSetElementObjectiveAndGradientRoutine()
127: @*/
128: int DAAppSetADElementFunctionGradient(TAO_APPLICATION daapplication,
129: int (*funcgrad)(int[2],DERIV_TYPE[4],DERIV_TYPE*,void*),
130: int flops, void *ctx){
131: int i,n,info;
132: int dim,dof,s;
133: DAStencilType st;
134: TaoDA2D1DOFADICFGCtx *fgctx;
135: DA da;
138: info=DAAppGetNumberOfDAGrids(daapplication,&n); CHKERRQ(info);
139: for (i=0;i<n;i++){
140: info = DAAppGetDA(daapplication, i, &da); CHKERRQ(info);
141: info = DAGetInfo(da,&dim,0,0,0,0,0,0,&dof,&s,0,&st); CHKERRQ(info);
142: if (dim!=2){
143: SETERRQ(1,"TAO DA ERROR: DA must have dimension of 2");}
144: if (dof!=1){
145: SETERRQ(1,"TAO DA ERROR: DA must have exactly 1 degree of freedom per node");}
146: if (s!=1){
147: SETERRQ(1,"TAO DA ERROR: DA stencil width must equal 1"); }
148: if (st!=DA_STENCIL_BOX){
149: SETERRQ(1,"TAO DA ERROR: DA stencil must be DA_STENCIL_BOX");}
150: }
151: PetscNew(TaoDA2D1DOFADICFGCtx,&fgctx);
152: // ad_AD_Init(4);
153: ad_AD_Init(ad_GRAD_MAX);
154: ad_AD_SetIndepArray(fgctx->adX,4);
155: ad_AD_SetIndepDone();
156: fgctx->computeadicfunctiongradient=funcgrad;
157: fgctx->elementfgctx=ctx;
158: fgctx->elementfgflops=flops;
159: info = DAAppSetObjectiveAndGradientRoutine(daapplication, TaoDA2dLoopADFunctionGradient, (void*)fgctx);
160: CHKERRQ(info);
161: info = TaoAppSetDestroyRoutine(daapplication,TaoApplicationFreeMemory, (void*)fgctx); CHKERRQ(info);
162: info = TaoAppSetDestroyRoutine(daapplication, TaoShutDownADICQQQQ, 0); CHKERRQ(info);
163: info = PetscInfo(daapplication,"Set objective function pointer for TAO_DA_APPLICATION object.\n"); CHKERRQ(info);
164: return(0);
165: }