1af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 2af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/ 3d433e6cbSMatthew G. Knepley 4d433e6cbSMatthew G. Knepley typedef struct { 5f2b97b97SMatthew G. Knepley PetscErrorCode (*boundarylocal)(DM, PetscReal, Vec, Vec, void *); 6d433e6cbSMatthew G. Knepley PetscErrorCode (*ifunctionlocal)(DM, PetscReal, Vec, Vec, Vec, void *); 7d433e6cbSMatthew G. Knepley PetscErrorCode (*ijacobianlocal)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *); 8d433e6cbSMatthew G. Knepley PetscErrorCode (*rhsfunctionlocal)(DM, PetscReal, Vec, Vec, void *); 9f2b97b97SMatthew G. Knepley void *boundarylocalctx; 10d433e6cbSMatthew G. Knepley void *ifunctionlocalctx; 11d433e6cbSMatthew G. Knepley void *ijacobianlocalctx; 12d433e6cbSMatthew G. Knepley void *rhsfunctionlocalctx; 13b4937a87SMatthew G. Knepley Vec lumpedmassinv; 14b4937a87SMatthew G. Knepley Mat mass; 15b4937a87SMatthew G. Knepley KSP kspmass; 16d433e6cbSMatthew G. Knepley } DMTS_Local; 17d433e6cbSMatthew G. Knepley 18d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSDestroy_DMLocal(DMTS tdm) 19d71ae5a4SJacob Faibussowitsch { 20d433e6cbSMatthew G. Knepley PetscFunctionBegin; 219566063dSJacob Faibussowitsch PetscCall(PetscFree(tdm->data)); 223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23d433e6cbSMatthew G. Knepley } 24d433e6cbSMatthew G. Knepley 25d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMTSDuplicate_DMLocal(DMTS oldtdm, DMTS tdm) 26d71ae5a4SJacob Faibussowitsch { 27d433e6cbSMatthew G. Knepley PetscFunctionBegin; 284dfa11a4SJacob Faibussowitsch PetscCall(PetscNew((DMTS_Local **)&tdm->data)); 299566063dSJacob Faibussowitsch if (oldtdm->data) PetscCall(PetscMemcpy(tdm->data, oldtdm->data, sizeof(DMTS_Local))); 303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31d433e6cbSMatthew G. Knepley } 32d433e6cbSMatthew G. Knepley 33d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalTSGetContext(DM dm, DMTS tdm, DMTS_Local **dmlocalts) 34d71ae5a4SJacob Faibussowitsch { 35d433e6cbSMatthew G. Knepley PetscFunctionBegin; 36d433e6cbSMatthew G. Knepley *dmlocalts = NULL; 37d433e6cbSMatthew G. Knepley if (!tdm->data) { 384dfa11a4SJacob Faibussowitsch PetscCall(PetscNew((DMTS_Local **)&tdm->data)); 39d433e6cbSMatthew G. Knepley 40d433e6cbSMatthew G. Knepley tdm->ops->destroy = DMTSDestroy_DMLocal; 41d433e6cbSMatthew G. Knepley tdm->ops->duplicate = DMTSDuplicate_DMLocal; 42d433e6cbSMatthew G. Knepley } 43d433e6cbSMatthew G. Knepley *dmlocalts = (DMTS_Local *)tdm->data; 443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45d433e6cbSMatthew G. Knepley } 46d433e6cbSMatthew G. Knepley 47d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSComputeIFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, Vec F, void *ctx) 48d71ae5a4SJacob Faibussowitsch { 49d433e6cbSMatthew G. Knepley DM dm; 50d433e6cbSMatthew G. Knepley Vec locX, locX_t, locF; 51d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *)ctx; 52d433e6cbSMatthew G. Knepley 53d433e6cbSMatthew G. Knepley PetscFunctionBegin; 54d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 55d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X, VEC_CLASSID, 3); 56d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X_t, VEC_CLASSID, 4); 57d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(F, VEC_CLASSID, 5); 589566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 599566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locX)); 609566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locX_t)); 619566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locF)); 629566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locX)); 639566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locX_t)); 649566063dSJacob Faibussowitsch if (dmlocalts->boundarylocal) PetscCall((*dmlocalts->boundarylocal)(dm, time, locX, locX_t, dmlocalts->boundarylocalctx)); 659566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX)); 669566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX)); 679566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t)); 689566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t)); 699566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locF)); 70d433e6cbSMatthew G. Knepley CHKMEMQ; 719566063dSJacob Faibussowitsch PetscCall((*dmlocalts->ifunctionlocal)(dm, time, locX, locX_t, locF, dmlocalts->ifunctionlocalctx)); 72d433e6cbSMatthew G. Knepley CHKMEMQ; 739566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(F)); 749566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F)); 759566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F)); 769566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locX)); 779566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locX_t)); 789566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locF)); 793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80d433e6cbSMatthew G. Knepley } 81d433e6cbSMatthew G. Knepley 82d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSComputeRHSFunction_DMLocal(TS ts, PetscReal time, Vec X, Vec F, void *ctx) 83d71ae5a4SJacob Faibussowitsch { 84d433e6cbSMatthew G. Knepley DM dm; 85b4937a87SMatthew G. Knepley Vec locX, locF; 86d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *)ctx; 87d433e6cbSMatthew G. Knepley 88d433e6cbSMatthew G. Knepley PetscFunctionBegin; 89d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(ts, TS_CLASSID, 1); 90d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(X, VEC_CLASSID, 3); 91064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(F, VEC_CLASSID, 4); 929566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 939566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locX)); 949566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locF)); 959566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locX)); 969566063dSJacob Faibussowitsch if (dmlocalts->boundarylocal) PetscCall((*dmlocalts->boundarylocal)(dm, time, locX, NULL, dmlocalts->boundarylocalctx)); 979566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX)); 989566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX)); 999566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locF)); 100b4937a87SMatthew G. Knepley CHKMEMQ; 1019566063dSJacob Faibussowitsch PetscCall((*dmlocalts->rhsfunctionlocal)(dm, time, locX, locF, dmlocalts->rhsfunctionlocalctx)); 102b4937a87SMatthew G. Knepley CHKMEMQ; 1039566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(F)); 1049566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, locF, ADD_VALUES, F)); 1059566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, locF, ADD_VALUES, F)); 106b4937a87SMatthew G. Knepley if (dmlocalts->lumpedmassinv) { 1079566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(F, dmlocalts->lumpedmassinv, F)); 108b4937a87SMatthew G. Knepley } else if (dmlocalts->kspmass) { 109b4937a87SMatthew G. Knepley Vec tmp; 110b4937a87SMatthew G. Knepley 1119566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &tmp)); 1129566063dSJacob Faibussowitsch PetscCall(KSPSolve(dmlocalts->kspmass, F, tmp)); 1139566063dSJacob Faibussowitsch PetscCall(VecCopy(tmp, F)); 1149566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &tmp)); 115b4937a87SMatthew G. Knepley } 1169566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locX)); 1179566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locF)); 1183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 119d433e6cbSMatthew G. Knepley } 120d433e6cbSMatthew G. Knepley 121d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSComputeIJacobian_DMLocal(TS ts, PetscReal time, Vec X, Vec X_t, PetscReal a, Mat A, Mat B, void *ctx) 122d71ae5a4SJacob Faibussowitsch { 123d433e6cbSMatthew G. Knepley DM dm; 124d433e6cbSMatthew G. Knepley Vec locX, locX_t; 125d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts = (DMTS_Local *)ctx; 126d433e6cbSMatthew G. Knepley 127d433e6cbSMatthew G. Knepley PetscFunctionBegin; 1289566063dSJacob Faibussowitsch PetscCall(TSGetDM(ts, &dm)); 129d433e6cbSMatthew G. Knepley if (dmlocalts->ijacobianlocal) { 1309566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locX)); 1319566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &locX_t)); 1329566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locX)); 1339566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(locX_t)); 1349566063dSJacob Faibussowitsch if (dmlocalts->boundarylocal) PetscCall((*dmlocalts->boundarylocal)(dm, time, locX, locX_t, dmlocalts->boundarylocalctx)); 1359566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, locX)); 1369566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, locX)); 1379566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X_t, INSERT_VALUES, locX_t)); 1389566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X_t, INSERT_VALUES, locX_t)); 139d433e6cbSMatthew G. Knepley CHKMEMQ; 1409566063dSJacob Faibussowitsch PetscCall((*dmlocalts->ijacobianlocal)(dm, time, locX, locX_t, a, A, B, dmlocalts->ijacobianlocalctx)); 141d433e6cbSMatthew G. Knepley CHKMEMQ; 1429566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locX)); 1439566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &locX_t)); 144d433e6cbSMatthew G. Knepley } else { 145d433e6cbSMatthew G. Knepley MatFDColoring fdcoloring; 1469566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 147d433e6cbSMatthew G. Knepley if (!fdcoloring) { 148d433e6cbSMatthew G. Knepley ISColoring coloring; 149d433e6cbSMatthew G. Knepley 1509566063dSJacob Faibussowitsch PetscCall(DMCreateColoring(dm, dm->coloringtype, &coloring)); 1519566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(B, coloring, &fdcoloring)); 1529566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&coloring)); 153d433e6cbSMatthew G. Knepley switch (dm->coloringtype) { 154d71ae5a4SJacob Faibussowitsch case IS_COLORING_GLOBAL: 155d71ae5a4SJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(fdcoloring, (PetscErrorCode(*)(void))TSComputeIFunction_DMLocal, dmlocalts)); 156d71ae5a4SJacob Faibussowitsch break; 157d71ae5a4SJacob Faibussowitsch default: 158d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No support for coloring type '%s'", ISColoringTypes[dm->coloringtype]); 159d433e6cbSMatthew G. Knepley } 1609566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fdcoloring, ((PetscObject)dm)->prefix)); 1619566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(fdcoloring)); 1629566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(B, coloring, fdcoloring)); 1639566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject)fdcoloring)); 1649566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)fdcoloring)); 165d433e6cbSMatthew G. Knepley 166d433e6cbSMatthew G. Knepley /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call 167d433e6cbSMatthew G. Knepley * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the 168d433e6cbSMatthew G. Knepley * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually 169d433e6cbSMatthew G. Knepley * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be 170d433e6cbSMatthew G. Knepley * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed. 171d433e6cbSMatthew G. Knepley */ 1729566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)dm)); 173d433e6cbSMatthew G. Knepley } 1749566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(B, fdcoloring, X, ts)); 175d433e6cbSMatthew G. Knepley } 176d433e6cbSMatthew G. Knepley /* This will be redundant if the user called both, but it's too common to forget. */ 177d433e6cbSMatthew G. Knepley if (A != B) { 1789566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1799566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 180d433e6cbSMatthew G. Knepley } 1813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 182d433e6cbSMatthew G. Knepley } 183d433e6cbSMatthew G. Knepley 1847eb36faeSMatthew G. Knepley /*@C 185f2b97b97SMatthew G. Knepley DMTSSetBoundaryLocal - set the function for essential boundary data for a local implicit function evaluation. 186a40652d4SToby Isaac 1877eb36faeSMatthew G. Knepley Logically Collective 1887eb36faeSMatthew G. Knepley 1894165533cSJose E. Roman Input Parameters: 190bcf0153eSBarry Smith + dm - `DM` to associate callback with 191a40652d4SToby Isaac . func - local function evaluation 192a40652d4SToby Isaac - ctx - context for function evaluation 1937eb36faeSMatthew G. Knepley 1947eb36faeSMatthew G. Knepley Level: intermediate 1957eb36faeSMatthew G. Knepley 196*14d0ab18SJacob Faibussowitsch Notes: 197*14d0ab18SJacob Faibussowitsch `func` should set the essential boundary data for the local portion of the solution, as 198*14d0ab18SJacob Faibussowitsch well its time derivative (if it is not `NULL`). 199*14d0ab18SJacob Faibussowitsch 200*14d0ab18SJacob Faibussowitsch Vectors are initialized to zero before this function, so it is only needed for non 201*14d0ab18SJacob Faibussowitsch homogeneous data. 202*14d0ab18SJacob Faibussowitsch 203*14d0ab18SJacob Faibussowitsch This function is somewhat optional: boundary data could potentially be inserted by a function 204*14d0ab18SJacob Faibussowitsch passed to `DMTSSetIFunctionLocal()`. The use case for this function is for discretizations 205*14d0ab18SJacob Faibussowitsch with constraints (see `DMGetDefaultConstraints()`): this function inserts boundary values 206*14d0ab18SJacob Faibussowitsch before constraint interpolation. 2072fe279fdSBarry Smith 2081cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `TS`, `DMTSSetIFunction()`, `DMTSSetIJacobianLocal()` 2097eb36faeSMatthew G. Knepley @*/ 210d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetBoundaryLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx) 211d71ae5a4SJacob Faibussowitsch { 2127eb36faeSMatthew G. Knepley DMTS tdm; 2137eb36faeSMatthew G. Knepley DMTS_Local *dmlocalts; 2147eb36faeSMatthew G. Knepley 2157eb36faeSMatthew G. Knepley PetscFunctionBegin; 2167eb36faeSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2179566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 2189566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 2197eb36faeSMatthew G. Knepley 2207eb36faeSMatthew G. Knepley dmlocalts->boundarylocal = func; 2217eb36faeSMatthew G. Knepley dmlocalts->boundarylocalctx = ctx; 222a40652d4SToby Isaac 2233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2247eb36faeSMatthew G. Knepley } 2257eb36faeSMatthew G. Knepley 226d433e6cbSMatthew G. Knepley /*@C 2270c9409e4SMatthew G. Knepley DMTSGetIFunctionLocal - get the local implicit function evaluation function. This function is called with local vector 2280c9409e4SMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 229bcf0153eSBarry Smith elements and `DM` will automatically accumulate the overlapping values. 2300c9409e4SMatthew G. Knepley 2310c9409e4SMatthew G. Knepley Logically Collective 2320c9409e4SMatthew G. Knepley 2330c9409e4SMatthew G. Knepley Input Parameter: 234bcf0153eSBarry Smith . dm - `DM` to associate callback with 2350c9409e4SMatthew G. Knepley 2360c9409e4SMatthew G. Knepley Output Parameters: 2370c9409e4SMatthew G. Knepley + func - local function evaluation 2380c9409e4SMatthew G. Knepley - ctx - context for function evaluation 2390c9409e4SMatthew G. Knepley 2400c9409e4SMatthew G. Knepley Level: beginner 2410c9409e4SMatthew G. Knepley 2421cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSSetIFunctionLocal()`, `DMTSSetIFunction()`, `DMTSSetIJacobianLocal()` 2430c9409e4SMatthew G. Knepley @*/ 244d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIFunctionLocal(DM dm, PetscErrorCode (**func)(DM, PetscReal, Vec, Vec, Vec, void *), void **ctx) 245d71ae5a4SJacob Faibussowitsch { 2460c9409e4SMatthew G. Knepley DMTS tdm; 2470c9409e4SMatthew G. Knepley DMTS_Local *dmlocalts; 2480c9409e4SMatthew G. Knepley PetscErrorCode ierr; 2490c9409e4SMatthew G. Knepley 2500c9409e4SMatthew G. Knepley PetscFunctionBegin; 2510c9409e4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2529371c9d4SSatish Balay ierr = DMGetDMTS(dm, &tdm); 2539371c9d4SSatish Balay CHKERRQ(ierr); 2549371c9d4SSatish Balay ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts); 2559371c9d4SSatish Balay CHKERRQ(ierr); 2569371c9d4SSatish Balay if (func) { 2574f572ea9SToby Isaac PetscAssertPointer(func, 2); 2589371c9d4SSatish Balay *func = dmlocalts->ifunctionlocal; 2599371c9d4SSatish Balay } 2609371c9d4SSatish Balay if (ctx) { 2614f572ea9SToby Isaac PetscAssertPointer(ctx, 3); 2629371c9d4SSatish Balay *ctx = dmlocalts->ifunctionlocalctx; 2639371c9d4SSatish Balay } 2643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2650c9409e4SMatthew G. Knepley } 2660c9409e4SMatthew G. Knepley 2670c9409e4SMatthew G. Knepley /*@C 268d433e6cbSMatthew G. Knepley DMTSSetIFunctionLocal - set a local implicit function evaluation function. This function is called with local vector 269d433e6cbSMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 270bcf0153eSBarry Smith elements and `DM` will automatically accumulate the overlapping values. 271d433e6cbSMatthew G. Knepley 272d433e6cbSMatthew G. Knepley Logically Collective 273d433e6cbSMatthew G. Knepley 2744165533cSJose E. Roman Input Parameters: 275bcf0153eSBarry Smith + dm - `DM` to associate callback with 276d433e6cbSMatthew G. Knepley . func - local function evaluation 277d433e6cbSMatthew G. Knepley - ctx - context for function evaluation 278d433e6cbSMatthew G. Knepley 279d433e6cbSMatthew G. Knepley Level: beginner 280d433e6cbSMatthew G. Knepley 2811cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSGetIFunctionLocal()`, `DMTSSetIFunction()`, `DMTSSetIJacobianLocal()` 282d433e6cbSMatthew G. Knepley @*/ 283d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, Vec, void *), void *ctx) 284d71ae5a4SJacob Faibussowitsch { 285d433e6cbSMatthew G. Knepley DMTS tdm; 286d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 287d433e6cbSMatthew G. Knepley 288d433e6cbSMatthew G. Knepley PetscFunctionBegin; 289d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2909566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 2919566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 292d433e6cbSMatthew G. Knepley 293d433e6cbSMatthew G. Knepley dmlocalts->ifunctionlocal = func; 294d433e6cbSMatthew G. Knepley dmlocalts->ifunctionlocalctx = ctx; 295d433e6cbSMatthew G. Knepley 2969566063dSJacob Faibussowitsch PetscCall(DMTSSetIFunction(dm, TSComputeIFunction_DMLocal, dmlocalts)); 297d433e6cbSMatthew G. Knepley if (!tdm->ops->ijacobian) { /* Call us for the Jacobian too, can be overridden by the user. */ 2989566063dSJacob Faibussowitsch PetscCall(DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts)); 299d433e6cbSMatthew G. Knepley } 3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 301d433e6cbSMatthew G. Knepley } 302d433e6cbSMatthew G. Knepley 303d433e6cbSMatthew G. Knepley /*@C 3040c9409e4SMatthew G. Knepley DMTSGetIJacobianLocal - get a local Jacobian evaluation function 3050c9409e4SMatthew G. Knepley 3060c9409e4SMatthew G. Knepley Logically Collective 3070c9409e4SMatthew G. Knepley 3080c9409e4SMatthew G. Knepley Input Parameter: 309bcf0153eSBarry Smith . dm - `DM` to associate callback with 3100c9409e4SMatthew G. Knepley 3110c9409e4SMatthew G. Knepley Output Parameters: 3120c9409e4SMatthew G. Knepley + func - local Jacobian evaluation 3130c9409e4SMatthew G. Knepley - ctx - optional context for local Jacobian evaluation 3140c9409e4SMatthew G. Knepley 3150c9409e4SMatthew G. Knepley Level: beginner 3160c9409e4SMatthew G. Knepley 3171cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSSetIJacobianLocal()`, `DMTSSetIFunctionLocal()`, `DMTSSetIJacobian()`, `DMTSSetIFunction()` 3180c9409e4SMatthew G. Knepley @*/ 319d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetIJacobianLocal(DM dm, PetscErrorCode (**func)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *), void **ctx) 320d71ae5a4SJacob Faibussowitsch { 3210c9409e4SMatthew G. Knepley DMTS tdm; 3220c9409e4SMatthew G. Knepley DMTS_Local *dmlocalts; 3230c9409e4SMatthew G. Knepley PetscErrorCode ierr; 3240c9409e4SMatthew G. Knepley 3250c9409e4SMatthew G. Knepley PetscFunctionBegin; 3260c9409e4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3279371c9d4SSatish Balay ierr = DMGetDMTS(dm, &tdm); 3289371c9d4SSatish Balay CHKERRQ(ierr); 3299371c9d4SSatish Balay ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts); 3309371c9d4SSatish Balay CHKERRQ(ierr); 3319371c9d4SSatish Balay if (func) { 3324f572ea9SToby Isaac PetscAssertPointer(func, 2); 3339371c9d4SSatish Balay *func = dmlocalts->ijacobianlocal; 3349371c9d4SSatish Balay } 3359371c9d4SSatish Balay if (ctx) { 3364f572ea9SToby Isaac PetscAssertPointer(ctx, 3); 3379371c9d4SSatish Balay *ctx = dmlocalts->ijacobianlocalctx; 3389371c9d4SSatish Balay } 3393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3400c9409e4SMatthew G. Knepley } 3410c9409e4SMatthew G. Knepley 3420c9409e4SMatthew G. Knepley /*@C 343d433e6cbSMatthew G. Knepley DMTSSetIJacobianLocal - set a local Jacobian evaluation function 344d433e6cbSMatthew G. Knepley 345d433e6cbSMatthew G. Knepley Logically Collective 346d433e6cbSMatthew G. Knepley 3474165533cSJose E. Roman Input Parameters: 348bcf0153eSBarry Smith + dm - `DM` to associate callback with 349d433e6cbSMatthew G. Knepley . func - local Jacobian evaluation 350d433e6cbSMatthew G. Knepley - ctx - optional context for local Jacobian evaluation 351d433e6cbSMatthew G. Knepley 352d433e6cbSMatthew G. Knepley Level: beginner 353d433e6cbSMatthew G. Knepley 3541cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSGetIJacobianLocal()`, `DMTSSetIFunctionLocal()`, `DMTSSetIJacobian()`, `DMTSSetIFunction()` 355d433e6cbSMatthew G. Knepley @*/ 356d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetIJacobianLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, PetscReal, Mat, Mat, void *), void *ctx) 357d71ae5a4SJacob Faibussowitsch { 358d433e6cbSMatthew G. Knepley DMTS tdm; 359d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 360d433e6cbSMatthew G. Knepley 361d433e6cbSMatthew G. Knepley PetscFunctionBegin; 362d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3639566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 3649566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 365d433e6cbSMatthew G. Knepley 366d433e6cbSMatthew G. Knepley dmlocalts->ijacobianlocal = func; 367d433e6cbSMatthew G. Knepley dmlocalts->ijacobianlocalctx = ctx; 368d433e6cbSMatthew G. Knepley 3699566063dSJacob Faibussowitsch PetscCall(DMTSSetIJacobian(dm, TSComputeIJacobian_DMLocal, dmlocalts)); 3703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 371d433e6cbSMatthew G. Knepley } 372d433e6cbSMatthew G. Knepley 373d433e6cbSMatthew G. Knepley /*@C 3740c9409e4SMatthew G. Knepley DMTSGetRHSFunctionLocal - get a local rhs function evaluation function. This function is called with local vector 3750c9409e4SMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 376bcf0153eSBarry Smith elements and `DM` will automatically accumulate the overlapping values. 3770c9409e4SMatthew G. Knepley 3780c9409e4SMatthew G. Knepley Logically Collective 3790c9409e4SMatthew G. Knepley 3800c9409e4SMatthew G. Knepley Input Parameter: 381bcf0153eSBarry Smith . dm - `DM` to associate callback with 3820c9409e4SMatthew G. Knepley 3830c9409e4SMatthew G. Knepley Output Parameters: 3840c9409e4SMatthew G. Knepley + func - local function evaluation 3850c9409e4SMatthew G. Knepley - ctx - context for function evaluation 3860c9409e4SMatthew G. Knepley 3870c9409e4SMatthew G. Knepley Level: beginner 3880c9409e4SMatthew G. Knepley 3891cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSSetRHSFunctionLocal()`, `DMTSSetRHSFunction()`, `DMTSSetIFunction()`, `DMTSSetIJacobianLocal()` 3900c9409e4SMatthew G. Knepley @*/ 391d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSGetRHSFunctionLocal(DM dm, PetscErrorCode (**func)(DM, PetscReal, Vec, Vec, void *), void **ctx) 392d71ae5a4SJacob Faibussowitsch { 3930c9409e4SMatthew G. Knepley DMTS tdm; 3940c9409e4SMatthew G. Knepley DMTS_Local *dmlocalts; 3950c9409e4SMatthew G. Knepley PetscErrorCode ierr; 3960c9409e4SMatthew G. Knepley 3970c9409e4SMatthew G. Knepley PetscFunctionBegin; 3980c9409e4SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3999371c9d4SSatish Balay ierr = DMGetDMTS(dm, &tdm); 4009371c9d4SSatish Balay CHKERRQ(ierr); 4019371c9d4SSatish Balay ierr = DMLocalTSGetContext(dm, tdm, &dmlocalts); 4029371c9d4SSatish Balay CHKERRQ(ierr); 4039371c9d4SSatish Balay if (func) { 4044f572ea9SToby Isaac PetscAssertPointer(func, 2); 4059371c9d4SSatish Balay *func = dmlocalts->rhsfunctionlocal; 4069371c9d4SSatish Balay } 4079371c9d4SSatish Balay if (ctx) { 4084f572ea9SToby Isaac PetscAssertPointer(ctx, 3); 4099371c9d4SSatish Balay *ctx = dmlocalts->rhsfunctionlocalctx; 4109371c9d4SSatish Balay } 4113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4120c9409e4SMatthew G. Knepley } 4130c9409e4SMatthew G. Knepley 4140c9409e4SMatthew G. Knepley /*@C 415d433e6cbSMatthew G. Knepley DMTSSetRHSFunctionLocal - set a local rhs function evaluation function. This function is called with local vector 416d433e6cbSMatthew G. Knepley containing the local vector information PLUS ghost point information. It should compute a result for all local 417bcf0153eSBarry Smith elements and `DM` will automatically accumulate the overlapping values. 418d433e6cbSMatthew G. Knepley 419d433e6cbSMatthew G. Knepley Logically Collective 420d433e6cbSMatthew G. Knepley 4214165533cSJose E. Roman Input Parameters: 422bcf0153eSBarry Smith + dm - `DM` to associate callback with 423d433e6cbSMatthew G. Knepley . func - local function evaluation 424d433e6cbSMatthew G. Knepley - ctx - context for function evaluation 425d433e6cbSMatthew G. Knepley 426d433e6cbSMatthew G. Knepley Level: beginner 427d433e6cbSMatthew G. Knepley 4281cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSGetRHSFunctionLocal()`, `DMTSSetRHSFunction()`, `DMTSSetIFunction()`, `DMTSSetIJacobianLocal()` 429d433e6cbSMatthew G. Knepley @*/ 430d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSSetRHSFunctionLocal(DM dm, PetscErrorCode (*func)(DM, PetscReal, Vec, Vec, void *), void *ctx) 431d71ae5a4SJacob Faibussowitsch { 432d433e6cbSMatthew G. Knepley DMTS tdm; 433d433e6cbSMatthew G. Knepley DMTS_Local *dmlocalts; 434d433e6cbSMatthew G. Knepley 435d433e6cbSMatthew G. Knepley PetscFunctionBegin; 436d433e6cbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4379566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 4389566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 439d433e6cbSMatthew G. Knepley 440d433e6cbSMatthew G. Knepley dmlocalts->rhsfunctionlocal = func; 441d433e6cbSMatthew G. Knepley dmlocalts->rhsfunctionlocalctx = ctx; 442d433e6cbSMatthew G. Knepley 4439566063dSJacob Faibussowitsch PetscCall(DMTSSetRHSFunction(dm, TSComputeRHSFunction_DMLocal, dmlocalts)); 4443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445d433e6cbSMatthew G. Knepley } 446b4937a87SMatthew G. Knepley 447b4937a87SMatthew G. Knepley /*@C 448bcf0153eSBarry Smith DMTSCreateRHSMassMatrix - This creates the mass matrix associated with the given `DM`, and a solver to invert it, and stores them in the `DM` context. 449b4937a87SMatthew G. Knepley 450c3339decSBarry Smith Collective 451b4937a87SMatthew G. Knepley 4522fe279fdSBarry Smith Input Parameter: 453bcf0153eSBarry Smith . dm - `DM` providing the mass matrix 454b4937a87SMatthew G. Knepley 455b4937a87SMatthew G. Knepley Level: developer 456b4937a87SMatthew G. Knepley 457bcf0153eSBarry Smith Note: 458bcf0153eSBarry Smith The idea here is that an explicit system can be given a mass matrix, based on the `DM`, which is inverted on the RHS at each step. 459bcf0153eSBarry Smith 4601cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSCreateRHSMassMatrixLumped()`, `DMTSDestroyRHSMassMatrix()`, `DMCreateMassMatrix()`, `DMTS` 461b4937a87SMatthew G. Knepley @*/ 462d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSCreateRHSMassMatrix(DM dm) 463d71ae5a4SJacob Faibussowitsch { 464b4937a87SMatthew G. Knepley DMTS tdm; 465b4937a87SMatthew G. Knepley DMTS_Local *dmlocalts; 466b4937a87SMatthew G. Knepley const char *prefix; 467b4937a87SMatthew G. Knepley 468b4937a87SMatthew G. Knepley PetscFunctionBegin; 469b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4709566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 4719566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 4729566063dSJacob Faibussowitsch PetscCall(DMCreateMassMatrix(dm, dm, &dmlocalts->mass)); 4739566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)dm), &dmlocalts->kspmass)); 4749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix)); 4759566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(dmlocalts->kspmass, prefix)); 4769566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(dmlocalts->kspmass, "mass_")); 4779566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(dmlocalts->kspmass)); 4789566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(dmlocalts->kspmass, dmlocalts->mass, dmlocalts->mass)); 4793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 480b4937a87SMatthew G. Knepley } 481b4937a87SMatthew G. Knepley 482b4937a87SMatthew G. Knepley /*@C 483bcf0153eSBarry Smith DMTSCreateRHSMassMatrixLumped - This creates the lumped mass matrix associated with the given `DM`, and a solver to invert it, and stores them in the `DM` context. 484b4937a87SMatthew G. Knepley 485c3339decSBarry Smith Collective 486b4937a87SMatthew G. Knepley 4872fe279fdSBarry Smith Input Parameter: 488bcf0153eSBarry Smith . dm - `DM` providing the mass matrix 489b4937a87SMatthew G. Knepley 490b4937a87SMatthew G. Knepley Level: developer 491b4937a87SMatthew G. Knepley 492bcf0153eSBarry Smith Note: 493bcf0153eSBarry Smith The idea here is that an explicit system can be given a mass matrix, based on the `DM`, which is inverted on the RHS at each step. 494bcf0153eSBarry Smith Since the matrix is lumped, inversion is trivial. 495bcf0153eSBarry Smith 4961cc06b55SBarry Smith .seealso: [](ch_ts), `DM`, `DMTSCreateRHSMassMatrix()`, `DMTSDestroyRHSMassMatrix()`, `DMCreateMassMatrix()`, `DMTS` 497b4937a87SMatthew G. Knepley @*/ 498d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSCreateRHSMassMatrixLumped(DM dm) 499d71ae5a4SJacob Faibussowitsch { 500b4937a87SMatthew G. Knepley DMTS tdm; 501b4937a87SMatthew G. Knepley DMTS_Local *dmlocalts; 502b4937a87SMatthew G. Knepley 503b4937a87SMatthew G. Knepley PetscFunctionBegin; 504b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5059566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 5069566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 5079566063dSJacob Faibussowitsch PetscCall(DMCreateMassMatrixLumped(dm, &dmlocalts->lumpedmassinv)); 5089566063dSJacob Faibussowitsch PetscCall(VecReciprocal(dmlocalts->lumpedmassinv)); 5099566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(dmlocalts->lumpedmassinv, NULL, "-lumped_mass_inv_view")); 5103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 511b4937a87SMatthew G. Knepley } 512b4937a87SMatthew G. Knepley 513b4937a87SMatthew G. Knepley /*@C 514bcf0153eSBarry Smith DMTSDestroyRHSMassMatrix - Destroys the mass matrix and solver stored in the `DM` context, if they exist. 515b4937a87SMatthew G. Knepley 516b4937a87SMatthew G. Knepley Logically Collective 517b4937a87SMatthew G. Knepley 5182fe279fdSBarry Smith Input Parameter: 519bcf0153eSBarry Smith . dm - `DM` providing the mass matrix 520b4937a87SMatthew G. Knepley 521b4937a87SMatthew G. Knepley Level: developer 522b4937a87SMatthew G. Knepley 523b43aa488SJacob Faibussowitsch .seealso: [](ch_ts), `DM`, `DMTSCreateRHSMassMatrixLumped()`, `DMCreateMassMatrix()`, `DMTS` 524b4937a87SMatthew G. Knepley @*/ 525d71ae5a4SJacob Faibussowitsch PetscErrorCode DMTSDestroyRHSMassMatrix(DM dm) 526d71ae5a4SJacob Faibussowitsch { 527b4937a87SMatthew G. Knepley DMTS tdm; 528b4937a87SMatthew G. Knepley DMTS_Local *dmlocalts; 529b4937a87SMatthew G. Knepley 530b4937a87SMatthew G. Knepley PetscFunctionBegin; 531b4937a87SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5329566063dSJacob Faibussowitsch PetscCall(DMGetDMTSWrite(dm, &tdm)); 5339566063dSJacob Faibussowitsch PetscCall(DMLocalTSGetContext(dm, tdm, &dmlocalts)); 5349566063dSJacob Faibussowitsch PetscCall(VecDestroy(&dmlocalts->lumpedmassinv)); 5359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&dmlocalts->mass)); 5369566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&dmlocalts->kspmass)); 5373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 538b4937a87SMatthew G. Knepley } 539