/*@ DAAppSetADElementFunctionGradient - Set routine that evaluates the local part of a function on a 2-dimensional DA with 1 degree of freedom. Collective on TAO_APPLICATION Input Parameters: + daapp - the TAO_DA_APPLICATION solver context . funcgrad - local function gradient routine . flops - the number of flops done performed in the funcgrad routine - fgctx - [optional] user-defined context for private data for the evaluation. Calling sequence of funcgrad: $ int funcgrad(int coordinates[2], PetscScalar x[4], double *f, PetscScalar g[4], void* ctx) + coord - the global coordinates [i j] in each direction of the DA . 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) . g - the ADIC differentiated objective function with respect to each variable - ctx - user defined context Note: This function requires ADIC to be installed and the ADIC-specific variables to be set in $TAO_DIR/bmake/packages.$PETSC_ARCH Level: intermediate .keywords: DA, gradient, ADIC .seealso: DAAppSetObjectiveAndGradientRoutine(), DAAppSetElementObjectiveAndGradientRoutine() @*/ int DAAppSetADElementFunctionGradient(TAO_APPLICATION daapplication, int (*funcgrad)(int[2],DERIV_TYPE[4],DERIV_TYPE*,void*), int flops, void *ctx){ int i,n,info; int dim,dof,s; DAStencilType st; TaoDA2D1DOFADICFGCtx *fgctx; DA da; PetscFunctionBegin; info=DAAppGetNumberOfDAGrids(daapplication,&n); CHKERRQ(info); for (i=0;i<n;i++){ info = DAAppGetDA(daapplication, i, &da); CHKERRQ(info); info = DAGetInfo(da,&dim,0,0,0,0,0,0,&dof,&s,0,&st); CHKERRQ(info); if (dim!=2){ SETERRQ(1,"TAO DA ERROR: DA must have dimension of 2");} if (dof!=1){ SETERRQ(1,"TAO DA ERROR: DA must have exactly 1 degree of freedom per node");} if (s!=1){ SETERRQ(1,"TAO DA ERROR: DA stencil width must equal 1"); } if (st!=DA_STENCIL_BOX){ SETERRQ(1,"TAO DA ERROR: DA stencil must be DA_STENCIL_BOX");} } PetscNew(TaoDA2D1DOFADICFGCtx,&fgctx); // ad_AD_Init(4); ad_AD_Init(ad_GRAD_MAX); ad_AD_SetIndepArray(fgctx->adX,4); ad_AD_SetIndepDone(); fgctx->computeadicfunctiongradient=funcgrad; fgctx->elementfgctx=ctx; fgctx->elementfgflops=flops; info = DAAppSetObjectiveAndGradientRoutine(daapplication, TaoDA2dLoopADFunctionGradient, (void*)fgctx); CHKERRQ(info); info = TaoAppSetDestroyRoutine(daapplication,TaoApplicationFreeMemory, (void*)fgctx); CHKERRQ(info); info = TaoAppSetDestroyRoutine(daapplication, TaoShutDownADICQQQQ, 0); CHKERRQ(info); info = PetscInfo(daapplication,"Set objective function pointer for TAO_DA_APPLICATION object.\n"); CHKERRQ(info); PetscFunctionReturn(0); }
void PetscADSetIndepDone(void) { ad_AD_SetIndepDone(); }