1*af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 2*af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 3d433e6cbSMatthew G. Knepley 4d433e6cbSMatthew G. Knepley typedef struct { 5d433e6cbSMatthew G. Knepley PetscErrorCode (*ifunctionlocal)(DM,PetscReal,Vec,Vec,Vec,void*); 6d433e6cbSMatthew G. Knepley PetscErrorCode (*ijacobianlocal)(DM,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*); 7d433e6cbSMatthew G. Knepley PetscErrorCode (*rhsfunctionlocal)(DM,PetscReal,Vec,Vec,void*); 8d433e6cbSMatthew G. Knepley void *ifunctionlocalctx; 9d433e6cbSMatthew G. Knepley void *ijacobianlocalctx; 10d433e6cbSMatthew G. Knepley void *rhsfunctionlocalctx; 11d433e6cbSMatthew G. Knepley } DMTS_Local; 12d433e6cbSMatthew G. Knepley 13d433e6cbSMatthew G. Knepley #undef __FUNCT__ 14d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSDestroy_DMLocal" 15d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDestroy_DMLocal(DMTS tdm) 16d433e6cbSMatthew G. Knepley { 17d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 18d433e6cbSMatthew G. Knepley 19d433e6cbSMatthew G. Knepley PetscFunctionBegin; 20d433e6cbSMatthew G. Knepley ierr = PetscFree(tdm->data);CHKERRQ(ierr); 21d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 22d433e6cbSMatthew G. Knepley } 23d433e6cbSMatthew G. Knepley 24d433e6cbSMatthew G. Knepley #undef __FUNCT__ 25d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSDuplicate_DMLocal" 26d433e6cbSMatthew G. Knepley static PetscErrorCode DMTSDuplicate_DMLocal(DMTS oldtdm, DMTS tdm) 27d433e6cbSMatthew G. Knepley { 28d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 29d433e6cbSMatthew G. Knepley 30d433e6cbSMatthew G. Knepley PetscFunctionBegin; 31d433e6cbSMatthew G. Knepley ierr = PetscNewLog(tdm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr); 32d433e6cbSMatthew G. Knepley if (oldtdm->data) {ierr = PetscMemcpy(tdm->data, oldtdm->data, sizeof(DMTS_Local));CHKERRQ(ierr);} 33d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 34d433e6cbSMatthew G. Knepley } 35d433e6cbSMatthew G. Knepley 36d433e6cbSMatthew G. Knepley #undef __FUNCT__ 37d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMLocalTSGetContext" 38d433e6cbSMatthew G. Knepley static PetscErrorCode DMLocalTSGetContext(DM dm, DMTS tdm, DMTS_Local **dmlocalts) 39d433e6cbSMatthew G. Knepley { 40d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 41d433e6cbSMatthew G. Knepley 42d433e6cbSMatthew G. Knepley PetscFunctionBegin; 43d433e6cbSMatthew G. Knepley *dmlocalts = NULL; 44d433e6cbSMatthew G. Knepley if (!tdm->data) { 45d433e6cbSMatthew G. Knepley ierr = PetscNewLog(dm, (DMTS_Local **) &tdm->data);CHKERRQ(ierr); 46d433e6cbSMatthew G. Knepley 47d433e6cbSMatthew G. Knepley tdm->ops->destroy = DMTSDestroy_DMLocal; 48d433e6cbSMatthew G. Knepley tdm->ops->duplicate = DMTSDuplicate_DMLocal; 49d433e6cbSMatthew G. Knepley } 50d433e6cbSMatthew G. Knepley *dmlocalts = (DMTS_Local *) tdm->data; 51d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 52d433e6cbSMatthew G. Knepley } 53d433e6cbSMatthew G. Knepley 54d433e6cbSMatthew G. Knepley #undef __FUNCT__ 55d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeIFunction_DMLocal" 56d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, Vec F, void *ctx) 57d433e6cbSMatthew G. Knepley { 58d433e6cbSMatthew G. Knepley DM dm; 59d433e6cbSMatthew G. Knepley Vec locX, locX_t, locF; 60d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *) ctx; 61d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 62d433e6cbSMatthew G. Knepley 63d433e6cbSMatthew G. Knepley PetscFunctionBegin; 64d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(ts,TS_CLASSID,1); 65d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X,VEC_CLASSID,3); 66d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X_t,VEC_CLASSID,4); 67d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(F,VEC_CLASSID,5); 68d433e6cbSMatthew G. Knepley ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 69d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr); 70d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr); 71d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locF);CHKERRQ(ierr); 72d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locX);CHKERRQ(ierr); 73d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locX_t);CHKERRQ(ierr); 74d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 75d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 76d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr); 77d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr); 78d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locF);CHKERRQ(ierr); 79d433e6cbSMatthew G. Knepley CHKMEMQ; 80d433e6cbSMatthew G. Knepley ierr = (*dmlocalts->ifunctionlocal)(dm, time, locX, locX_t, locF, dmlocalts->ifunctionlocalctx);CHKERRQ(ierr); 81d433e6cbSMatthew G. Knepley CHKMEMQ; 82d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(F);CHKERRQ(ierr); 83d433e6cbSMatthew G. Knepley ierr = DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F);CHKERRQ(ierr); 84d433e6cbSMatthew G. Knepley ierr = DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F);CHKERRQ(ierr); 85d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr); 86d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr); 87d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locF);CHKERRQ(ierr); 88d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 89d433e6cbSMatthew G. Knepley } 90d433e6cbSMatthew G. Knepley 91d433e6cbSMatthew G. Knepley #undef __FUNCT__ 92d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeRHSFunction_DMLocal" 93d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeRHSFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec F, void *ctx) 94d433e6cbSMatthew G. Knepley { 95d433e6cbSMatthew G. Knepley DM dm; 96d433e6cbSMatthew G. Knepley Vec locX; 97d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *) ctx; 98d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 99d433e6cbSMatthew G. Knepley 100d433e6cbSMatthew G. Knepley PetscFunctionBegin; 101d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(ts,TS_CLASSID,1); 102d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X,VEC_CLASSID,3); 103d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(F,VEC_CLASSID,5); 104d433e6cbSMatthew G. Knepley ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 105d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr); 106d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locX);CHKERRQ(ierr); 107d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 108d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 109d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(F);CHKERRQ(ierr); 110d433e6cbSMatthew G. Knepley CHKMEMQ; 111d433e6cbSMatthew G. Knepley ierr = (*dmlocalts->rhsfunctionlocal)(dm, time, locX, F, dmlocalts->rhsfunctionlocalctx);CHKERRQ(ierr); 112d433e6cbSMatthew G. Knepley CHKMEMQ; 113d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr); 114d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 115d433e6cbSMatthew G. Knepley } 116d433e6cbSMatthew G. Knepley 117d433e6cbSMatthew G. Knepley #undef __FUNCT__ 118d433e6cbSMatthew G. Knepley #define __FUNCT__ "TSComputeIJacobian_DMLocal" 119d433e6cbSMatthew G. Knepley static PetscErrorCode TSComputeIJacobian_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, PetscReal a, Mat A, Mat B, void *ctx) 120d433e6cbSMatthew G. Knepley { 121d433e6cbSMatthew G. Knepley DM dm; 122d433e6cbSMatthew G. Knepley Vec locX, locX_t; 123d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *) ctx; 124d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 125d433e6cbSMatthew G. Knepley 126d433e6cbSMatthew G. Knepley PetscFunctionBegin; 127d433e6cbSMatthew G. Knepley ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 128d433e6cbSMatthew G. Knepley if (dmlocalts->ijacobianlocal) { 129d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locX);CHKERRQ(ierr); 130d433e6cbSMatthew G. Knepley ierr = DMGetLocalVector(dm, &locX_t);CHKERRQ(ierr); 131d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locX);CHKERRQ(ierr); 132d433e6cbSMatthew G. Knepley ierr = VecZeroEntries(locX_t);CHKERRQ(ierr); 133d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 134d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX);CHKERRQ(ierr); 135d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr); 136d433e6cbSMatthew G. Knepley ierr = DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t);CHKERRQ(ierr); 137d433e6cbSMatthew G. Knepley CHKMEMQ; 138d433e6cbSMatthew G. Knepley ierr = (*dmlocalts->ijacobianlocal)(dm, time, locX, locX_t, a, A, B, dmlocalts->ijacobianlocalctx);CHKERRQ(ierr); 139d433e6cbSMatthew G. Knepley CHKMEMQ; 140d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locX);CHKERRQ(ierr); 141d433e6cbSMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locX_t);CHKERRQ(ierr); 142d433e6cbSMatthew G. Knepley } else { 143d433e6cbSMatthew G. Knepley MatFDColoring fdcoloring; 144d433e6cbSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject *) &fdcoloring);CHKERRQ(ierr); 145d433e6cbSMatthew G. Knepley if (!fdcoloring) { 146d433e6cbSMatthew G. Knepley ISColoring coloring; 147d433e6cbSMatthew G. Knepley 148d433e6cbSMatthew G. Knepley ierr = DMCreateColoring(dm, dm->coloringtype, &coloring);CHKERRQ(ierr); 149d433e6cbSMatthew G. Knepley ierr = MatFDColoringCreate(B, coloring, &fdcoloring);CHKERRQ(ierr); 150d433e6cbSMatthew G. Knepley ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); 151d433e6cbSMatthew G. Knepley switch (dm->coloringtype) { 152d433e6cbSMatthew G. Knepley case IS_COLORING_GLOBAL: 153d433e6cbSMatthew G. Knepley ierr = MatFDColoringSetFunction(fdcoloring, (PetscErrorCode (*)(void)) TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr); 154d433e6cbSMatthew G. Knepley break; 155d433e6cbSMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) ts), PETSC_ERR_SUP, "No support for coloring type '%s'", ISColoringTypes[dm->coloringtype]); 156d433e6cbSMatthew G. Knepley } 157d433e6cbSMatthew G. Knepley ierr = PetscObjectSetOptionsPrefix((PetscObject) fdcoloring, ((PetscObject) dm)->prefix);CHKERRQ(ierr); 158d433e6cbSMatthew G. Knepley ierr = MatFDColoringSetFromOptions(fdcoloring);CHKERRQ(ierr); 159d433e6cbSMatthew G. Knepley ierr = MatFDColoringSetUp(B, coloring, fdcoloring);CHKERRQ(ierr); 160d433e6cbSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) dm, "DMDASNES_FDCOLORING", (PetscObject) fdcoloring);CHKERRQ(ierr); 161d433e6cbSMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) fdcoloring);CHKERRQ(ierr); 162d433e6cbSMatthew G. Knepley 163d433e6cbSMatthew G. Knepley /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call 164d433e6cbSMatthew G. Knepley * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the 165d433e6cbSMatthew G. Knepley * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually 166d433e6cbSMatthew G. Knepley * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be 167d433e6cbSMatthew G. Knepley * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed. 168d433e6cbSMatthew G. Knepley */ 169d433e6cbSMatthew G. Knepley ierr = PetscObjectDereference((PetscObject) dm);CHKERRQ(ierr); 170d433e6cbSMatthew G. Knepley } 171d433e6cbSMatthew G. Knepley ierr = MatFDColoringApply(B, fdcoloring, X, ts);CHKERRQ(ierr); 172d433e6cbSMatthew G. Knepley } 173d433e6cbSMatthew G. Knepley /* This will be redundant if the user called both, but it's too common to forget. */ 174d433e6cbSMatthew G. Knepley if (A != B) { 175d433e6cbSMatthew G. Knepley ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 176d433e6cbSMatthew G. Knepley ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 177d433e6cbSMatthew G. Knepley } 178d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 179d433e6cbSMatthew G. Knepley } 180d433e6cbSMatthew G. Knepley 181d433e6cbSMatthew G. Knepley #undef __FUNCT__ 182d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetIFunctionLocal" 183d433e6cbSMatthew G. Knepley /*@C 184d433e6cbSMatthew G. Knepley DMTSSetIFunctionLocal - set a local implicit function evaluation function. This function is called with local vector 185d433e6cbSMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 186d433e6cbSMatthew G. Knepley elements and DMTS will automatically accumulate the overlapping values. 187d433e6cbSMatthew G. Knepley 188d433e6cbSMatthew G. Knepley Logically Collective 189d433e6cbSMatthew G. Knepley 190d433e6cbSMatthew G. Knepley Input Arguments: 191d433e6cbSMatthew G. Knepley + dm - DM to associate callback with 192d433e6cbSMatthew G. Knepley . func - local function evaluation 193d433e6cbSMatthew G. Knepley - ctx - context for function evaluation 194d433e6cbSMatthew G. Knepley 195d433e6cbSMatthew G. Knepley Level: beginner 196d433e6cbSMatthew G. Knepley 197d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunction(), DMTSSetIJacobianLocal() 198d433e6cbSMatthew G. Knepley @*/ 199d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, Vec, void *), void *ctx) 200d433e6cbSMatthew G. Knepley { 201d433e6cbSMatthew G. Knepley DMTS tdm; 202d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 203d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 204d433e6cbSMatthew G. Knepley 205d433e6cbSMatthew G. Knepley PetscFunctionBegin; 206d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 207d433e6cbSMatthew G. Knepley ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr); 208d433e6cbSMatthew G. Knepley ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr); 209d433e6cbSMatthew G. Knepley 210d433e6cbSMatthew G. Knepley dmlocalts->ifunctionlocal = func; 211d433e6cbSMatthew G. Knepley dmlocalts->ifunctionlocalctx = ctx; 212d433e6cbSMatthew G. Knepley 213d433e6cbSMatthew G. Knepley ierr = DMTSSetIFunction(dm, TSComputeIFunction_DMLocal, dmlocalts);CHKERRQ(ierr); 214d433e6cbSMatthew G. Knepley if (!tdm->ops->ijacobian) { /* Call us for the Jacobian too, can be overridden by the user. */ 215d433e6cbSMatthew G. Knepley ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr); 216d433e6cbSMatthew G. Knepley } 217d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 218d433e6cbSMatthew G. Knepley } 219d433e6cbSMatthew G. Knepley 220d433e6cbSMatthew G. Knepley #undef __FUNCT__ 221d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetIJacobianLocal" 222d433e6cbSMatthew G. Knepley /*@C 223d433e6cbSMatthew G. Knepley DMTSSetIJacobianLocal - set a local Jacobian evaluation function 224d433e6cbSMatthew G. Knepley 225d433e6cbSMatthew G. Knepley Logically Collective 226d433e6cbSMatthew G. Knepley 227d433e6cbSMatthew G. Knepley Input Arguments: 228d433e6cbSMatthew G. Knepley + dm - DM to associate callback with 229d433e6cbSMatthew G. Knepley . func - local Jacobian evaluation 230d433e6cbSMatthew G. Knepley - ctx - optional context for local Jacobian evaluation 231d433e6cbSMatthew G. Knepley 232d433e6cbSMatthew G. Knepley Level: beginner 233d433e6cbSMatthew G. Knepley 234d433e6cbSMatthew G. Knepley .seealso: DMTSSetIFunctionLocal(), DMTSSetIJacobian(), DMTSSetIFunction() 235d433e6cbSMatthew G. Knepley @*/ 236d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetIJacobianLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *), void *ctx) 237d433e6cbSMatthew G. Knepley { 238d433e6cbSMatthew G. Knepley DMTS tdm; 239d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 240d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 241d433e6cbSMatthew G. Knepley 242d433e6cbSMatthew G. Knepley PetscFunctionBegin; 243d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 244d433e6cbSMatthew G. Knepley ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr); 245d433e6cbSMatthew G. Knepley ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr); 246d433e6cbSMatthew G. Knepley 247d433e6cbSMatthew G. Knepley dmlocalts->ijacobianlocal = func; 248d433e6cbSMatthew G. Knepley dmlocalts->ijacobianlocalctx = ctx; 249d433e6cbSMatthew G. Knepley 250d433e6cbSMatthew G. Knepley ierr = DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts);CHKERRQ(ierr); 251d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 252d433e6cbSMatthew G. Knepley } 253d433e6cbSMatthew G. Knepley 254d433e6cbSMatthew G. Knepley #undef __FUNCT__ 255d433e6cbSMatthew G. Knepley #define __FUNCT__ "DMTSSetRHSFunctionLocal" 256d433e6cbSMatthew G. Knepley /*@C 257d433e6cbSMatthew G. Knepley DMTSSetRHSFunctionLocal - set a local rhs function evaluation function. This function is called with local vector 258d433e6cbSMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 259d433e6cbSMatthew G. Knepley elements and DMTS will automatically accumulate the overlapping values. 260d433e6cbSMatthew G. Knepley 261d433e6cbSMatthew G. Knepley Logically Collective 262d433e6cbSMatthew G. Knepley 263d433e6cbSMatthew G. Knepley Input Arguments: 264d433e6cbSMatthew G. Knepley + dm - DM to associate callback with 265d433e6cbSMatthew G. Knepley . func - local function evaluation 266d433e6cbSMatthew G. Knepley - ctx - context for function evaluation 267d433e6cbSMatthew G. Knepley 268d433e6cbSMatthew G. Knepley Level: beginner 269d433e6cbSMatthew G. Knepley 270d433e6cbSMatthew G. Knepley .seealso: DMTSSetRHSFunction(), DMTSSetIFunction(), DMTSSetIJacobianLocal() 271d433e6cbSMatthew G. Knepley @*/ 272d433e6cbSMatthew G. Knepley PetscErrorCode DMTSSetRHSFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx) 273d433e6cbSMatthew G. Knepley { 274d433e6cbSMatthew G. Knepley DMTS tdm; 275d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 276d433e6cbSMatthew G. Knepley PetscErrorCode ierr; 277d433e6cbSMatthew G. Knepley 278d433e6cbSMatthew G. Knepley PetscFunctionBegin; 279d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 280d433e6cbSMatthew G. Knepley ierr = DMGetDMTSWrite(dm, &tdm);CHKERRQ(ierr); 281d433e6cbSMatthew G. Knepley ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts);CHKERRQ(ierr); 282d433e6cbSMatthew G. Knepley 283d433e6cbSMatthew G. Knepley dmlocalts->rhsfunctionlocal = func; 284d433e6cbSMatthew G. Knepley dmlocalts->rhsfunctionlocalctx = ctx; 285d433e6cbSMatthew G. Knepley 286d433e6cbSMatthew G. Knepley ierr = DMTSSetRHSFunction(dm, TSComputeRHSFunction_DMLocal, dmlocalts);CHKERRQ(ierr); 287d433e6cbSMatthew G. Knepley PetscFunctionReturn(0); 288d433e6cbSMatthew G. Knepley } 289