PetscErrorCode FormFunction(SNES snes,Vec X,Vec F,void *ctx) { PetscErrorCode ierr; DMMG dmmg = (DMMG)ctx; AppCtx *user = (AppCtx*)dmmg->user; DA da2 = (DA)dmmg->dm; DALocalInfo info2; Field2 **x2,**f2; Vec X2; PetscFunctionBegin; ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X */ ierr = DAGetLocalVector(da2,&X2);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); /* Access the array inside of X1 */ ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); /* Access the subvectors in F. These are not ghosted so directly access the memory locations in F */ ierr = DAVecGetArray(da2,F,(void**)&f2);CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormFunctionLocal2(&info2,0,x2,f2,(void**)user);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,F,(void**)&f2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DARestoreLocalVector(da2,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* FormFunctionComp - Unwraps the input vector and passes its local ghosted pieces into the user function */ PetscErrorCode FormFunctionComp(SNES snes,Vec X,Vec F,void *ctx) { PetscErrorCode ierr; DMMG dmmg = (DMMG)ctx; AppCtx *user = (AppCtx*)dmmg->user; DMComposite dm = (DMComposite)dmmg->dm; DALocalInfo info1,info2; DA da1,da2; Field1 **x1,**f1; Field2 **x2,**f2; Vec X1,X2,F1,F2; PetscFunctionBegin; ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1);CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X */ ierr = DMCompositeGetLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DMCompositeScatter(dm,X,X1,X2);CHKERRQ(ierr); /* Access the arrays inside the subvectors of X */ ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); /* Access the subvectors in F. These are not ghosted and directly access the memory locations in F */ ierr = DMCompositeGetAccess(dm,F,&F1,&F2);CHKERRQ(ierr); /* Access the arrays inside the subvectors of F */ ierr = DAVecGetArray(da1,F1,(void**)&f1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,F2,(void**)&f2);CHKERRQ(ierr); /* Evaluate local user provided function */ user->x2 = x2; /* used by FormFunctionLocal1() */ ierr = FormFunctionLocal1(&info1,x1,f1,(void**)user);CHKERRQ(ierr); user->x1 = x1; /* used by FormFunctionLocal2() */ ierr = FormFunctionLocal2(&info2,x2,f2,(void**)user);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,F1,(void**)&f1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,F2,(void**)&f2);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(dm,F,&F1,&F2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }