1af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 2af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 3ff35dfedSBarry Smith 4ff35dfedSBarry Smith typedef struct { 56493148fSStefano Zampini PetscErrorCode (*objectivelocal)(DM, Vec, PetscReal *, void *); 6ff35dfedSBarry Smith PetscErrorCode (*residuallocal)(DM, Vec, Vec, void *); 7d1e9a80fSBarry Smith PetscErrorCode (*jacobianlocal)(DM, Vec, Mat, Mat, void *); 8bdd6f66aSToby Isaac PetscErrorCode (*boundarylocal)(DM, Vec, void *); 96493148fSStefano Zampini void *objectivelocalctx; 10ff35dfedSBarry Smith void *residuallocalctx; 11ff35dfedSBarry Smith void *jacobianlocalctx; 12bdd6f66aSToby Isaac void *boundarylocalctx; 13942e3340SBarry Smith } DMSNES_Local; 14ff35dfedSBarry Smith 15d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESDestroy_DMLocal(DMSNES sdm) 16d71ae5a4SJacob Faibussowitsch { 17ff35dfedSBarry Smith PetscFunctionBegin; 189566063dSJacob Faibussowitsch PetscCall(PetscFree(sdm->data)); 195ed5e208SMatthew G. Knepley sdm->data = NULL; 203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21ff35dfedSBarry Smith } 22ff35dfedSBarry Smith 23d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMSNESDuplicate_DMLocal(DMSNES oldsdm, DMSNES sdm) 24d71ae5a4SJacob Faibussowitsch { 25ff35dfedSBarry Smith PetscFunctionBegin; 265ed5e208SMatthew G. Knepley if (sdm->data != oldsdm->data) { 279566063dSJacob Faibussowitsch PetscCall(PetscFree(sdm->data)); 284dfa11a4SJacob Faibussowitsch PetscCall(PetscNew((DMSNES_Local **)&sdm->data)); 299566063dSJacob Faibussowitsch if (oldsdm->data) PetscCall(PetscMemcpy(sdm->data, oldsdm->data, sizeof(DMSNES_Local))); 30ff35dfedSBarry Smith } 313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32ff35dfedSBarry Smith } 33ff35dfedSBarry Smith 34d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLocalSNESGetContext(DM dm, DMSNES sdm, DMSNES_Local **dmlocalsnes) 35d71ae5a4SJacob Faibussowitsch { 36ff35dfedSBarry Smith PetscFunctionBegin; 370298fd71SBarry Smith *dmlocalsnes = NULL; 38ff35dfedSBarry Smith if (!sdm->data) { 394dfa11a4SJacob Faibussowitsch PetscCall(PetscNew((DMSNES_Local **)&sdm->data)); 401aa26658SKarl Rupp 4122c6f798SBarry Smith sdm->ops->destroy = DMSNESDestroy_DMLocal; 4222c6f798SBarry Smith sdm->ops->duplicate = DMSNESDuplicate_DMLocal; 43ff35dfedSBarry Smith } 44942e3340SBarry Smith *dmlocalsnes = (DMSNES_Local *)sdm->data; 453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 46ff35dfedSBarry Smith } 47ff35dfedSBarry Smith 48*2a8381b2SBarry Smith static PetscErrorCode SNESComputeObjective_DMLocal(SNES snes, Vec X, PetscReal *obj, PetscCtx ctx) 496493148fSStefano Zampini { 506493148fSStefano Zampini DMSNES_Local *dmlocalsnes = (DMSNES_Local *)ctx; 516493148fSStefano Zampini DM dm; 526493148fSStefano Zampini Vec Xloc; 536493148fSStefano Zampini PetscBool transform; 546493148fSStefano Zampini 556493148fSStefano Zampini PetscFunctionBegin; 566493148fSStefano Zampini PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 576493148fSStefano Zampini PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 586493148fSStefano Zampini PetscCall(SNESGetDM(snes, &dm)); 596493148fSStefano Zampini PetscCall(DMGetLocalVector(dm, &Xloc)); 606493148fSStefano Zampini PetscCall(VecZeroEntries(Xloc)); 616493148fSStefano Zampini /* Non-conforming routines needs boundary values before G2L */ 626493148fSStefano Zampini if (dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 636493148fSStefano Zampini PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, Xloc)); 646493148fSStefano Zampini PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, Xloc)); 656493148fSStefano Zampini /* Need to reset boundary values if we transformed */ 666493148fSStefano Zampini PetscCall(DMHasBasisTransform(dm, &transform)); 676493148fSStefano Zampini if (transform && dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 686493148fSStefano Zampini CHKMEMQ; 696493148fSStefano Zampini PetscCall((*dmlocalsnes->objectivelocal)(dm, Xloc, obj, dmlocalsnes->objectivelocalctx)); 706493148fSStefano Zampini CHKMEMQ; 71462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, obj, 1, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)snes))); 726493148fSStefano Zampini PetscCall(DMRestoreLocalVector(dm, &Xloc)); 736493148fSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 746493148fSStefano Zampini } 756493148fSStefano Zampini 76*2a8381b2SBarry Smith static PetscErrorCode SNESComputeFunction_DMLocal(SNES snes, Vec X, Vec F, PetscCtx ctx) 77d71ae5a4SJacob Faibussowitsch { 78942e3340SBarry Smith DMSNES_Local *dmlocalsnes = (DMSNES_Local *)ctx; 797a1e7fa1SMatthew G. Knepley DM dm; 80ff35dfedSBarry Smith Vec Xloc, Floc; 817a1e7fa1SMatthew G. Knepley PetscBool transform; 82ff35dfedSBarry Smith 83ff35dfedSBarry Smith PetscFunctionBegin; 84ff35dfedSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 85ff35dfedSBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 86ff35dfedSBarry Smith PetscValidHeaderSpecific(F, VEC_CLASSID, 3); 879566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 889566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &Xloc)); 899566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &Floc)); 909566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Xloc)); 919566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Floc)); 927a1e7fa1SMatthew G. Knepley /* Non-conforming routines needs boundary values before G2L */ 939566063dSJacob Faibussowitsch if (dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 949566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, Xloc)); 959566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, Xloc)); 967a1e7fa1SMatthew G. Knepley /* Need to reset boundary values if we transformed */ 979566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 989566063dSJacob Faibussowitsch if (transform && dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 99ff35dfedSBarry Smith CHKMEMQ; 1009566063dSJacob Faibussowitsch PetscCall((*dmlocalsnes->residuallocal)(dm, Xloc, Floc, dmlocalsnes->residuallocalctx)); 101ff35dfedSBarry Smith CHKMEMQ; 1029566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(F)); 1039566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalBegin(dm, Floc, ADD_VALUES, F)); 1049566063dSJacob Faibussowitsch PetscCall(DMLocalToGlobalEnd(dm, Floc, ADD_VALUES, F)); 1059566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &Floc)); 1069566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &Xloc)); 107afa9dec6SMatthew G. Knepley { 108afa9dec6SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 109f2f0fc17SMatthew G. Knepley char oldname[PETSC_MAX_PATH_LEN]; 110f2f0fc17SMatthew G. Knepley const char *tmp; 111afa9dec6SMatthew G. Knepley PetscInt it; 112afa9dec6SMatthew G. Knepley 1139566063dSJacob Faibussowitsch PetscCall(SNESGetIterationNumber(snes, &it)); 114835f2295SStefano Zampini PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN, "Solution, Iterate %" PetscInt_FMT, it)); 1159566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)X, &tmp)); 1169566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(oldname, tmp, PETSC_MAX_PATH_LEN - 1)); 1179566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, name)); 1189566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(X, (PetscObject)snes, "-dmsnes_solution_vec_view")); 1199566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)X, oldname)); 120835f2295SStefano Zampini PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN, "Residual, Iterate %" PetscInt_FMT, it)); 1219566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)F, name)); 1229566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(F, (PetscObject)snes, "-dmsnes_residual_vec_view")); 123afa9dec6SMatthew G. Knepley } 1243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 125ff35dfedSBarry Smith } 126ff35dfedSBarry Smith 127*2a8381b2SBarry Smith static PetscErrorCode SNESComputeJacobian_DMLocal(SNES snes, Vec X, Mat A, Mat B, PetscCtx ctx) 128d71ae5a4SJacob Faibussowitsch { 129942e3340SBarry Smith DMSNES_Local *dmlocalsnes = (DMSNES_Local *)ctx; 1307a1e7fa1SMatthew G. Knepley DM dm; 131ff35dfedSBarry Smith Vec Xloc; 1327a1e7fa1SMatthew G. Knepley PetscBool transform; 133ff35dfedSBarry Smith 134ff35dfedSBarry Smith PetscFunctionBegin; 1359566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 136ff35dfedSBarry Smith if (dmlocalsnes->jacobianlocal) { 1379566063dSJacob Faibussowitsch PetscCall(DMGetLocalVector(dm, &Xloc)); 1389566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Xloc)); 1397a1e7fa1SMatthew G. Knepley /* Non-conforming routines needs boundary values before G2L */ 1409566063dSJacob Faibussowitsch if (dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 1419566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalBegin(dm, X, INSERT_VALUES, Xloc)); 1429566063dSJacob Faibussowitsch PetscCall(DMGlobalToLocalEnd(dm, X, INSERT_VALUES, Xloc)); 1437a1e7fa1SMatthew G. Knepley /* Need to reset boundary values if we transformed */ 1449566063dSJacob Faibussowitsch PetscCall(DMHasBasisTransform(dm, &transform)); 1459566063dSJacob Faibussowitsch if (transform && dmlocalsnes->boundarylocal) PetscCall((*dmlocalsnes->boundarylocal)(dm, Xloc, dmlocalsnes->boundarylocalctx)); 146ff35dfedSBarry Smith CHKMEMQ; 1479566063dSJacob Faibussowitsch PetscCall((*dmlocalsnes->jacobianlocal)(dm, Xloc, A, B, dmlocalsnes->jacobianlocalctx)); 148ff35dfedSBarry Smith CHKMEMQ; 1499566063dSJacob Faibussowitsch PetscCall(DMRestoreLocalVector(dm, &Xloc)); 150ff35dfedSBarry Smith } else { 151ff35dfedSBarry Smith MatFDColoring fdcoloring; 1529566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 153ff35dfedSBarry Smith if (!fdcoloring) { 154ff35dfedSBarry Smith ISColoring coloring; 155ff35dfedSBarry Smith 1569566063dSJacob Faibussowitsch PetscCall(DMCreateColoring(dm, dm->coloringtype, &coloring)); 1579566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(B, coloring, &fdcoloring)); 1589566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&coloring)); 159ff35dfedSBarry Smith switch (dm->coloringtype) { 160d71ae5a4SJacob Faibussowitsch case IS_COLORING_GLOBAL: 1612ba42892SBarry Smith PetscCall(MatFDColoringSetFunction(fdcoloring, (MatFDColoringFn *)SNESComputeFunction_DMLocal, dmlocalsnes)); 162d71ae5a4SJacob Faibussowitsch break; 163d71ae5a4SJacob Faibussowitsch default: 164d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)snes), PETSC_ERR_SUP, "No support for coloring type '%s'", ISColoringTypes[dm->coloringtype]); 165ff35dfedSBarry Smith } 1669566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)fdcoloring, ((PetscObject)dm)->prefix)); 1679566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(fdcoloring)); 1689566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(B, coloring, fdcoloring)); 1699566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject)fdcoloring)); 1709566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)fdcoloring)); 171ff35dfedSBarry Smith 172ff35dfedSBarry Smith /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call 173ff35dfedSBarry Smith * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the 174ff35dfedSBarry Smith * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually 175ff35dfedSBarry Smith * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be 176140e18c1SBarry Smith * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed. 177ff35dfedSBarry Smith */ 1789566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)dm)); 179ff35dfedSBarry Smith } 1809566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(B, fdcoloring, X, snes)); 181ff35dfedSBarry Smith } 182ff35dfedSBarry Smith /* This will be redundant if the user called both, but it's too common to forget. */ 18394ab13aaSBarry Smith if (A != B) { 1849566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1859566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 186ff35dfedSBarry Smith } 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 188ff35dfedSBarry Smith } 189ff35dfedSBarry Smith 190ff35dfedSBarry Smith /*@C 1916493148fSStefano Zampini DMSNESSetObjectiveLocal - set a local objective evaluation function. This function is called with local vector 1926493148fSStefano Zampini containing the local vector information PLUS ghost point information. It should compute a result for all local 1936493148fSStefano Zampini elements and `DMSNES` will automatically accumulate the overlapping values. 1946493148fSStefano Zampini 1956493148fSStefano Zampini Logically Collective 1966493148fSStefano Zampini 1976493148fSStefano Zampini Input Parameters: 1986493148fSStefano Zampini + dm - `DM` to associate callback with 1996493148fSStefano Zampini . func - local objective evaluation 2006493148fSStefano Zampini - ctx - optional context for local residual evaluation 2016493148fSStefano Zampini 2026493148fSStefano Zampini Level: advanced 2036493148fSStefano Zampini 2046493148fSStefano Zampini .seealso: `DMSNESSetFunctionLocal()`, `DMSNESSetJacobianLocal()` 2056493148fSStefano Zampini @*/ 206*2a8381b2SBarry Smith PetscErrorCode DMSNESSetObjectiveLocal(DM dm, PetscErrorCode (*func)(DM, Vec, PetscReal *, void *), PetscCtx ctx) 2076493148fSStefano Zampini { 2086493148fSStefano Zampini DMSNES sdm; 2096493148fSStefano Zampini DMSNES_Local *dmlocalsnes; 2106493148fSStefano Zampini 2116493148fSStefano Zampini PetscFunctionBegin; 2126493148fSStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2136493148fSStefano Zampini PetscCall(DMGetDMSNESWrite(dm, &sdm)); 2146493148fSStefano Zampini PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 2156493148fSStefano Zampini 2166493148fSStefano Zampini dmlocalsnes->objectivelocal = func; 2176493148fSStefano Zampini dmlocalsnes->objectivelocalctx = ctx; 2186493148fSStefano Zampini 2196493148fSStefano Zampini PetscCall(DMSNESSetObjective(dm, SNESComputeObjective_DMLocal, dmlocalsnes)); 2206493148fSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 2216493148fSStefano Zampini } 2226493148fSStefano Zampini 2236493148fSStefano Zampini /*@C 224ff35dfedSBarry Smith DMSNESSetFunctionLocal - set a local residual evaluation function. This function is called with local vector 225ff35dfedSBarry Smith containing the local vector information PLUS ghost point information. It should compute a result for all local 226f6dfbefdSBarry Smith elements and `DMSNES` will automatically accumulate the overlapping values. 227ff35dfedSBarry Smith 228ff35dfedSBarry Smith Logically Collective 229ff35dfedSBarry Smith 2304165533cSJose E. Roman Input Parameters: 231f6dfbefdSBarry Smith + dm - `DM` to associate callback with 232ff35dfedSBarry Smith . func - local residual evaluation 233ff35dfedSBarry Smith - ctx - optional context for local residual evaluation 234ff35dfedSBarry Smith 235420bcc1bSBarry Smith Calling sequence of `func`: 236420bcc1bSBarry Smith + dm - `DM` for the function 237420bcc1bSBarry Smith . x - vector to state at which to evaluate residual 238420bcc1bSBarry Smith . f - vector to hold the function evaluation 239420bcc1bSBarry Smith - ctx - optional context passed above 240420bcc1bSBarry Smith 241f6dfbefdSBarry Smith Level: advanced 242ff35dfedSBarry Smith 2436493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetFunction()`, `DMSNESSetJacobianLocal()` 244ff35dfedSBarry Smith @*/ 245*2a8381b2SBarry Smith PetscErrorCode DMSNESSetFunctionLocal(DM dm, PetscErrorCode (*func)(DM dm, Vec x, Vec f, PetscCtx ctx), PetscCtx ctx) 246d71ae5a4SJacob Faibussowitsch { 247942e3340SBarry Smith DMSNES sdm; 248942e3340SBarry Smith DMSNES_Local *dmlocalsnes; 249ff35dfedSBarry Smith 250ff35dfedSBarry Smith PetscFunctionBegin; 251ff35dfedSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2529566063dSJacob Faibussowitsch PetscCall(DMGetDMSNESWrite(dm, &sdm)); 2539566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 2541aa26658SKarl Rupp 255ff35dfedSBarry Smith dmlocalsnes->residuallocal = func; 256ff35dfedSBarry Smith dmlocalsnes->residuallocalctx = ctx; 2571aa26658SKarl Rupp 2589566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, SNESComputeFunction_DMLocal, dmlocalsnes)); 25922c6f798SBarry Smith if (!sdm->ops->computejacobian) { /* Call us for the Jacobian too, can be overridden by the user. */ 2609566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobian_DMLocal, dmlocalsnes)); 261ff35dfedSBarry Smith } 2623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 263ff35dfedSBarry Smith } 264ff35dfedSBarry Smith 265bdd6f66aSToby Isaac /*@C 2660b4db180SJacob Faibussowitsch DMSNESSetBoundaryLocal - set a function to insert, for example, essential boundary conditions into a ghosted solution vector 267bdd6f66aSToby Isaac 268bdd6f66aSToby Isaac Logically Collective 269bdd6f66aSToby Isaac 2704165533cSJose E. Roman Input Parameters: 271f6dfbefdSBarry Smith + dm - `DM` to associate callback with 272bdd6f66aSToby Isaac . func - local boundary value evaluation 273bdd6f66aSToby Isaac - ctx - optional context for local boundary value evaluation 274bdd6f66aSToby Isaac 2750b4db180SJacob Faibussowitsch Calling sequence of `func`: 2760b4db180SJacob Faibussowitsch + dm - the `DM` context 277baca6076SPierre Jolivet . X - ghosted solution vector, appropriate locations (such as essential boundary condition nodes) should be filled 278420bcc1bSBarry Smith - ctx - option context passed in `DMSNESSetBoundaryLocal()` 2790b4db180SJacob Faibussowitsch 280f6dfbefdSBarry Smith Level: advanced 281bdd6f66aSToby Isaac 2826493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetObjectiveLocal()`, `DMSNESSetFunctionLocal()`, `DMSNESSetJacobianLocal()` 283bdd6f66aSToby Isaac @*/ 284*2a8381b2SBarry Smith PetscErrorCode DMSNESSetBoundaryLocal(DM dm, PetscErrorCode (*func)(DM dm, Vec X, PetscCtx ctx), PetscCtx ctx) 285d71ae5a4SJacob Faibussowitsch { 286bdd6f66aSToby Isaac DMSNES sdm; 287bdd6f66aSToby Isaac DMSNES_Local *dmlocalsnes; 288bdd6f66aSToby Isaac 289bdd6f66aSToby Isaac PetscFunctionBegin; 290bdd6f66aSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2919566063dSJacob Faibussowitsch PetscCall(DMGetDMSNESWrite(dm, &sdm)); 2929566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 293bdd6f66aSToby Isaac 294bdd6f66aSToby Isaac dmlocalsnes->boundarylocal = func; 295bdd6f66aSToby Isaac dmlocalsnes->boundarylocalctx = ctx; 2963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 297bdd6f66aSToby Isaac } 298bdd6f66aSToby Isaac 299ff35dfedSBarry Smith /*@C 300ff35dfedSBarry Smith DMSNESSetJacobianLocal - set a local Jacobian evaluation function 301ff35dfedSBarry Smith 302ff35dfedSBarry Smith Logically Collective 303ff35dfedSBarry Smith 3044165533cSJose E. Roman Input Parameters: 305420bcc1bSBarry Smith + dm - `DM` to associate callback with 306ff35dfedSBarry Smith . func - local Jacobian evaluation 307ff35dfedSBarry Smith - ctx - optional context for local Jacobian evaluation 308ff35dfedSBarry Smith 3090b4db180SJacob Faibussowitsch Calling sequence of `func`: 3100b4db180SJacob Faibussowitsch + dm - the `DM` context 3110b4db180SJacob Faibussowitsch . X - current solution vector (ghosted or not?) 3120b4db180SJacob Faibussowitsch . J - the Jacobian 3130b4db180SJacob Faibussowitsch . Jp - approximate Jacobian used to compute the preconditioner, often `J` 3140b4db180SJacob Faibussowitsch - ctx - a user provided context 3150b4db180SJacob Faibussowitsch 316f6dfbefdSBarry Smith Level: advanced 317ff35dfedSBarry Smith 3186493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetObjectiveLocal()`, `DMSNESSetFunctionLocal()`, `DMSNESSetBoundaryLocal()` 319ff35dfedSBarry Smith @*/ 320*2a8381b2SBarry Smith PetscErrorCode DMSNESSetJacobianLocal(DM dm, PetscErrorCode (*func)(DM dm, Vec X, Mat J, Mat Jp, PetscCtx ctx), PetscCtx ctx) 321d71ae5a4SJacob Faibussowitsch { 322942e3340SBarry Smith DMSNES sdm; 323942e3340SBarry Smith DMSNES_Local *dmlocalsnes; 324ff35dfedSBarry Smith 325ff35dfedSBarry Smith PetscFunctionBegin; 326ff35dfedSBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3279566063dSJacob Faibussowitsch PetscCall(DMGetDMSNESWrite(dm, &sdm)); 3289566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 3291aa26658SKarl Rupp 330ff35dfedSBarry Smith dmlocalsnes->jacobianlocal = func; 331ff35dfedSBarry Smith dmlocalsnes->jacobianlocalctx = ctx; 3321aa26658SKarl Rupp 3339566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobian_DMLocal, dmlocalsnes)); 3343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33528d58a37SPierre Jolivet } 33628d58a37SPierre Jolivet 33728d58a37SPierre Jolivet /*@C 3386493148fSStefano Zampini DMSNESGetObjectiveLocal - get the local objective evaluation function information set with `DMSNESSetObjectiveLocal()`. 3396493148fSStefano Zampini 3406493148fSStefano Zampini Not Collective 3416493148fSStefano Zampini 3426493148fSStefano Zampini Input Parameter: 3436493148fSStefano Zampini . dm - `DM` with the associated callback 3446493148fSStefano Zampini 3456493148fSStefano Zampini Output Parameters: 3466493148fSStefano Zampini + func - local objective evaluation 3476493148fSStefano Zampini - ctx - context for local residual evaluation 3486493148fSStefano Zampini 3496493148fSStefano Zampini Level: beginner 3506493148fSStefano Zampini 3516493148fSStefano Zampini .seealso: `DMSNESSetObjective()`, `DMSNESSetObjectiveLocal()`, `DMSNESSetFunctionLocal()` 3526493148fSStefano Zampini @*/ 353*2a8381b2SBarry Smith PetscErrorCode DMSNESGetObjectiveLocal(DM dm, PetscErrorCode (**func)(DM, Vec, PetscReal *, void *), PetscCtxRt ctx) 3546493148fSStefano Zampini { 3556493148fSStefano Zampini DMSNES sdm; 3566493148fSStefano Zampini DMSNES_Local *dmlocalsnes; 3576493148fSStefano Zampini 3586493148fSStefano Zampini PetscFunctionBegin; 3596493148fSStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3606493148fSStefano Zampini PetscCall(DMGetDMSNES(dm, &sdm)); 3616493148fSStefano Zampini PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 3626493148fSStefano Zampini if (func) *func = dmlocalsnes->objectivelocal; 363*2a8381b2SBarry Smith if (ctx) *(void **)ctx = dmlocalsnes->objectivelocalctx; 3646493148fSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3656493148fSStefano Zampini } 3666493148fSStefano Zampini 3676493148fSStefano Zampini /*@C 368f6dfbefdSBarry Smith DMSNESGetFunctionLocal - get the local residual evaluation function information set with `DMSNESSetFunctionLocal()`. 36928d58a37SPierre Jolivet 37028d58a37SPierre Jolivet Not Collective 37128d58a37SPierre Jolivet 3724165533cSJose E. Roman Input Parameter: 373f6dfbefdSBarry Smith . dm - `DM` with the associated callback 37428d58a37SPierre Jolivet 3754165533cSJose E. Roman Output Parameters: 37628d58a37SPierre Jolivet + func - local residual evaluation 37728d58a37SPierre Jolivet - ctx - context for local residual evaluation 37828d58a37SPierre Jolivet 37928d58a37SPierre Jolivet Level: beginner 38028d58a37SPierre Jolivet 3816493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetFunction()`, `DMSNESSetFunctionLocal()`, `DMSNESSetJacobianLocal()` 38228d58a37SPierre Jolivet @*/ 383*2a8381b2SBarry Smith PetscErrorCode DMSNESGetFunctionLocal(DM dm, PetscErrorCode (**func)(DM, Vec, Vec, void *), PetscCtxRt ctx) 384d71ae5a4SJacob Faibussowitsch { 38528d58a37SPierre Jolivet DMSNES sdm; 38628d58a37SPierre Jolivet DMSNES_Local *dmlocalsnes; 38728d58a37SPierre Jolivet 38828d58a37SPierre Jolivet PetscFunctionBegin; 38928d58a37SPierre Jolivet PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3909566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 3919566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 39228d58a37SPierre Jolivet if (func) *func = dmlocalsnes->residuallocal; 393*2a8381b2SBarry Smith if (ctx) *(void **)ctx = dmlocalsnes->residuallocalctx; 3943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39528d58a37SPierre Jolivet } 39628d58a37SPierre Jolivet 39728d58a37SPierre Jolivet /*@C 398f6dfbefdSBarry Smith DMSNESGetBoundaryLocal - get the local boundary value function set with `DMSNESSetBoundaryLocal()`. 39928d58a37SPierre Jolivet 40028d58a37SPierre Jolivet Not Collective 40128d58a37SPierre Jolivet 4024165533cSJose E. Roman Input Parameter: 403f6dfbefdSBarry Smith . dm - `DM` with the associated callback 40428d58a37SPierre Jolivet 4054165533cSJose E. Roman Output Parameters: 40628d58a37SPierre Jolivet + func - local boundary value evaluation 40728d58a37SPierre Jolivet - ctx - context for local boundary value evaluation 40828d58a37SPierre Jolivet 40928d58a37SPierre Jolivet Level: intermediate 41028d58a37SPierre Jolivet 4116493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetFunctionLocal()`, `DMSNESSetBoundaryLocal()`, `DMSNESSetJacobianLocal()` 41228d58a37SPierre Jolivet @*/ 413*2a8381b2SBarry Smith PetscErrorCode DMSNESGetBoundaryLocal(DM dm, PetscErrorCode (**func)(DM, Vec, void *), PetscCtxRt ctx) 414d71ae5a4SJacob Faibussowitsch { 41528d58a37SPierre Jolivet DMSNES sdm; 41628d58a37SPierre Jolivet DMSNES_Local *dmlocalsnes; 41728d58a37SPierre Jolivet 41828d58a37SPierre Jolivet PetscFunctionBegin; 41928d58a37SPierre Jolivet PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4209566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 4219566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 42228d58a37SPierre Jolivet if (func) *func = dmlocalsnes->boundarylocal; 423*2a8381b2SBarry Smith if (ctx) *(void **)ctx = dmlocalsnes->boundarylocalctx; 4243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42528d58a37SPierre Jolivet } 42628d58a37SPierre Jolivet 42728d58a37SPierre Jolivet /*@C 428f6dfbefdSBarry Smith DMSNESGetJacobianLocal - the local Jacobian evaluation function set with `DMSNESSetJacobianLocal()`. 42928d58a37SPierre Jolivet 43028d58a37SPierre Jolivet Logically Collective 43128d58a37SPierre Jolivet 4324165533cSJose E. Roman Input Parameter: 433f6dfbefdSBarry Smith . dm - `DM` with the associated callback 43428d58a37SPierre Jolivet 4354165533cSJose E. Roman Output Parameters: 43628d58a37SPierre Jolivet + func - local Jacobian evaluation 43728d58a37SPierre Jolivet - ctx - context for local Jacobian evaluation 43828d58a37SPierre Jolivet 43928d58a37SPierre Jolivet Level: beginner 44028d58a37SPierre Jolivet 4416493148fSStefano Zampini .seealso: [](ch_snes), `DMSNESSetJacobianLocal()`, `DMSNESSetJacobian()` 44228d58a37SPierre Jolivet @*/ 443*2a8381b2SBarry Smith PetscErrorCode DMSNESGetJacobianLocal(DM dm, PetscErrorCode (**func)(DM, Vec, Mat, Mat, void *), PetscCtxRt ctx) 444d71ae5a4SJacob Faibussowitsch { 44528d58a37SPierre Jolivet DMSNES sdm; 44628d58a37SPierre Jolivet DMSNES_Local *dmlocalsnes; 44728d58a37SPierre Jolivet 44828d58a37SPierre Jolivet PetscFunctionBegin; 44928d58a37SPierre Jolivet PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4509566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 4519566063dSJacob Faibussowitsch PetscCall(DMLocalSNESGetContext(dm, sdm, &dmlocalsnes)); 45228d58a37SPierre Jolivet if (func) *func = dmlocalsnes->jacobianlocal; 453*2a8381b2SBarry Smith if (ctx) *(void **)ctx = dmlocalsnes->jacobianlocalctx; 4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 455ff35dfedSBarry Smith } 456