xref: /petsc/src/dm/dt/interface/dtds.c (revision e87b5d96567786df49b4af65cff3120eb2cdf5c2)
1af0996ceSBarry Smith #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/
22764a2aaSMatthew G. Knepley 
32764a2aaSMatthew G. Knepley PetscClassId PETSCDS_CLASSID = 0;
42764a2aaSMatthew G. Knepley 
52764a2aaSMatthew G. Knepley PetscFunctionList PetscDSList              = NULL;
62764a2aaSMatthew G. Knepley PetscBool         PetscDSRegisterAllCalled = PETSC_FALSE;
72764a2aaSMatthew G. Knepley 
894dcdc3fSMatthew G. Knepley /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of
994dcdc3fSMatthew G. Knepley    nonlinear continuum equations. The equations can have multiple fields, each field having a different
1094dcdc3fSMatthew G. Knepley    discretization. In addition, different pieces of the domain can have different field combinations and equations.
1194dcdc3fSMatthew G. Knepley 
1294dcdc3fSMatthew G. Knepley    The DS provides the user a description of the approximation space on any given cell. It also gives pointwise
1394dcdc3fSMatthew G. Knepley    functions representing the equations.
1494dcdc3fSMatthew G. Knepley 
1594dcdc3fSMatthew G. Knepley    Each field is associated with a label, marking the cells on which it is supported. Note that a field can be
1694dcdc3fSMatthew G. Knepley    supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM
1794dcdc3fSMatthew G. Knepley    then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for
1894dcdc3fSMatthew G. Knepley    the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop.
1994dcdc3fSMatthew G. Knepley */
2094dcdc3fSMatthew G. Knepley 
212764a2aaSMatthew G. Knepley /*@C
22dce8aebaSBarry Smith   PetscDSRegister - Adds a new `PetscDS` implementation
232764a2aaSMatthew G. Knepley 
2420f4b53cSBarry Smith   Not Collective; No Fortran Support
252764a2aaSMatthew G. Knepley 
262764a2aaSMatthew G. Knepley   Input Parameters:
2720f4b53cSBarry Smith + sname    - The name of a new user-defined creation routine
2820f4b53cSBarry Smith - function - The creation routine itself
292764a2aaSMatthew G. Knepley 
3060225df5SJacob Faibussowitsch   Example Usage:
312764a2aaSMatthew G. Knepley .vb
322764a2aaSMatthew G. Knepley     PetscDSRegister("my_ds", MyPetscDSCreate);
332764a2aaSMatthew G. Knepley .ve
342764a2aaSMatthew G. Knepley 
352764a2aaSMatthew G. Knepley   Then, your PetscDS type can be chosen with the procedural interface via
362764a2aaSMatthew G. Knepley .vb
372764a2aaSMatthew G. Knepley     PetscDSCreate(MPI_Comm, PetscDS *);
382764a2aaSMatthew G. Knepley     PetscDSSetType(PetscDS, "my_ds");
392764a2aaSMatthew G. Knepley .ve
402764a2aaSMatthew G. Knepley   or at runtime via the option
412764a2aaSMatthew G. Knepley .vb
422764a2aaSMatthew G. Knepley     -petscds_type my_ds
432764a2aaSMatthew G. Knepley .ve
442764a2aaSMatthew G. Knepley 
452764a2aaSMatthew G. Knepley   Level: advanced
462764a2aaSMatthew G. Knepley 
47dce8aebaSBarry Smith   Note:
48dce8aebaSBarry Smith   `PetscDSRegister()` may be called multiple times to add several user-defined `PetscDSs`
49dce8aebaSBarry Smith 
50dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
512764a2aaSMatthew G. Knepley @*/
52d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
53d71ae5a4SJacob Faibussowitsch {
542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
559566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
572764a2aaSMatthew G. Knepley }
582764a2aaSMatthew G. Knepley 
59cc4c1da9SBarry Smith /*@
60dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
612764a2aaSMatthew G. Knepley 
6220f4b53cSBarry Smith   Collective; No Fortran Support
632764a2aaSMatthew G. Knepley 
642764a2aaSMatthew G. Knepley   Input Parameters:
65dce8aebaSBarry Smith + prob - The `PetscDS` object
66dce8aebaSBarry Smith - name - The `PetscDSType`
672764a2aaSMatthew G. Knepley 
682764a2aaSMatthew G. Knepley   Options Database Key:
692764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
702764a2aaSMatthew G. Knepley 
712764a2aaSMatthew G. Knepley   Level: intermediate
722764a2aaSMatthew G. Knepley 
73dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
742764a2aaSMatthew G. Knepley @*/
75d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
76d71ae5a4SJacob Faibussowitsch {
772764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
782764a2aaSMatthew G. Knepley   PetscBool match;
792764a2aaSMatthew G. Knepley 
802764a2aaSMatthew G. Knepley   PetscFunctionBegin;
812764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
833ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
842764a2aaSMatthew G. Knepley 
859566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
869566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
8728b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
882764a2aaSMatthew G. Knepley 
89dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
902764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
91dbbe0bcdSBarry Smith 
929566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
952764a2aaSMatthew G. Knepley }
962764a2aaSMatthew G. Knepley 
97cc4c1da9SBarry Smith /*@
98dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
992764a2aaSMatthew G. Knepley 
10020f4b53cSBarry Smith   Not Collective; No Fortran Support
1012764a2aaSMatthew G. Knepley 
1022764a2aaSMatthew G. Knepley   Input Parameter:
103dce8aebaSBarry Smith . prob - The `PetscDS`
1042764a2aaSMatthew G. Knepley 
1052764a2aaSMatthew G. Knepley   Output Parameter:
106dce8aebaSBarry Smith . name - The `PetscDSType` name
1072764a2aaSMatthew G. Knepley 
1082764a2aaSMatthew G. Knepley   Level: intermediate
1092764a2aaSMatthew G. Knepley 
110dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
1112764a2aaSMatthew G. Knepley @*/
112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
113d71ae5a4SJacob Faibussowitsch {
1142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1164f572ea9SToby Isaac   PetscAssertPointer(name, 2);
1179566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1182764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1202764a2aaSMatthew G. Knepley }
1212764a2aaSMatthew G. Knepley 
122d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
123d71ae5a4SJacob Faibussowitsch {
1247d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
12597b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1265fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1277d8a60eaSMatthew G. Knepley 
1287d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1309566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1329566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
13363a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1349566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1355fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
13640967b3bSMatthew G. Knepley     DSBoundary      b;
1377d8a60eaSMatthew G. Knepley     PetscObject     obj;
1387d8a60eaSMatthew G. Knepley     PetscClassId    id;
139f35450b9SMatthew G. Knepley     PetscQuadrature q;
1407d8a60eaSMatthew G. Knepley     const char     *name;
141f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1427d8a60eaSMatthew G. Knepley 
1439566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1449566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1459566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1487d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1499566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1509566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1519566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1527d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1539566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1549566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1559566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1569371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
15763a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
15863a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1599566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1609566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1613e60c2a6SMatthew G. Knepley     if (q) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
16363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1643e60c2a6SMatthew G. Knepley     }
16563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1669566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1679566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1689566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1699566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1709566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
17240967b3bSMatthew G. Knepley 
1735fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
17406ad1575SMatthew G. Knepley       char    *name;
17540967b3bSMatthew G. Knepley       PetscInt c, i;
17640967b3bSMatthew G. Knepley 
17740967b3bSMatthew G. Knepley       if (b->field != f) continue;
1789566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
18045480ffeSMatthew G. Knepley       if (!b->Nc) {
1819566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
18240967b3bSMatthew G. Knepley       } else {
1839566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1849566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
18545480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1869566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
18763a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
18840967b3bSMatthew G. Knepley         }
1899566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1909566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
19140967b3bSMatthew G. Knepley       }
1929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
1939566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
19445480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
1959566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
19663a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
19740967b3bSMatthew G. Knepley       }
1989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20015943bb8SPierre Jolivet #if defined(__clang__)
201a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic")
20215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
203a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat")
20415943bb8SPierre Jolivet #endif
2058e0d8d9cSMatthew G. Knepley       if (b->func) {
2069566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2079566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2089566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2099566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2108e0d8d9cSMatthew G. Knepley       }
2118e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2129566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2139566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2149566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2159566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2168e0d8d9cSMatthew G. Knepley       }
217a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END()
2189566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2199566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
22040967b3bSMatthew G. Knepley     }
2217d8a60eaSMatthew G. Knepley   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
22397b6e6e8SMatthew G. Knepley   if (numConstants) {
22463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2269566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
22897b6e6e8SMatthew G. Knepley   }
2299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2327d8a60eaSMatthew G. Knepley }
2337d8a60eaSMatthew G. Knepley 
234ffeef943SBarry Smith /*@
235dce8aebaSBarry Smith   PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
236fe2efc57SMark 
23720f4b53cSBarry Smith   Collective
238fe2efc57SMark 
239fe2efc57SMark   Input Parameters:
240dce8aebaSBarry Smith + A    - the `PetscDS` object
24120f4b53cSBarry Smith . obj  - Optional object that provides the options prefix used in the search
242736c3998SJose E. Roman - name - command line option
243fe2efc57SMark 
244fe2efc57SMark   Level: intermediate
245dce8aebaSBarry Smith 
246dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
247fe2efc57SMark @*/
248d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
249d71ae5a4SJacob Faibussowitsch {
250fe2efc57SMark   PetscFunctionBegin;
251fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
254fe2efc57SMark }
255fe2efc57SMark 
256ffeef943SBarry Smith /*@
257dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2582764a2aaSMatthew G. Knepley 
25920f4b53cSBarry Smith   Collective
2602764a2aaSMatthew G. Knepley 
261d8d19677SJose E. Roman   Input Parameters:
262dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2632764a2aaSMatthew G. Knepley - v    - the viewer
2642764a2aaSMatthew G. Knepley 
2652764a2aaSMatthew G. Knepley   Level: developer
2662764a2aaSMatthew G. Knepley 
26720f4b53cSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`, `PetscDSViewFromOptions()`
2682764a2aaSMatthew G. Knepley @*/
269d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
270d71ae5a4SJacob Faibussowitsch {
2717d8a60eaSMatthew G. Knepley   PetscBool iascii;
2722764a2aaSMatthew G. Knepley 
2732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2742764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2759566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
276ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2789566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
279dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2812764a2aaSMatthew G. Knepley }
2822764a2aaSMatthew G. Knepley 
2832764a2aaSMatthew G. Knepley /*@
284dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2852764a2aaSMatthew G. Knepley 
28620f4b53cSBarry Smith   Collective
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   Input Parameter:
289dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2902764a2aaSMatthew G. Knepley 
291dce8aebaSBarry Smith   Options Database Keys:
292dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
293dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
294147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
295147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
296147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
2972764a2aaSMatthew G. Knepley 
298dce8aebaSBarry Smith   Level: intermediate
2992764a2aaSMatthew G. Knepley 
300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3012764a2aaSMatthew G. Knepley @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
303d71ae5a4SJacob Faibussowitsch {
304f1fd5e65SToby Isaac   DSBoundary  b;
3052764a2aaSMatthew G. Knepley   const char *defaultType;
3062764a2aaSMatthew G. Knepley   char        name[256];
3072764a2aaSMatthew G. Knepley   PetscBool   flg;
3082764a2aaSMatthew G. Knepley 
3092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3102764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3112764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3122764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3132764a2aaSMatthew G. Knepley   } else {
3142764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3152764a2aaSMatthew G. Knepley   }
3169566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3172764a2aaSMatthew G. Knepley 
318d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
319f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
320f1fd5e65SToby Isaac     char      optname[1024];
321f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
322f1fd5e65SToby Isaac     PetscBool flg;
323f1fd5e65SToby Isaac 
3249566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3259566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
327f1fd5e65SToby Isaac     if (flg) {
32845480ffeSMatthew G. Knepley       b->Nv = len;
3299566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3309566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3319566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3329566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
333f1fd5e65SToby Isaac     }
334e7b0402cSSander Arens     len = 1024;
3359566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3369566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
338f1fd5e65SToby Isaac     if (flg) {
33945480ffeSMatthew G. Knepley       b->Nc = len;
3409566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3429566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
343f1fd5e65SToby Isaac     }
344f1fd5e65SToby Isaac   }
3459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3462764a2aaSMatthew G. Knepley   if (flg) {
3479566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3482764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3499566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3502764a2aaSMatthew G. Knepley   }
3519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
35212fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
353b2deab97SMatthew G. Knepley   PetscCall(PetscOptionsInt("-petscds_print_integrate", "Discrete System", "", prob->printIntegrate, &prob->printIntegrate, NULL));
354dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3552764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
356dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
357d0609cedSBarry Smith   PetscOptionsEnd();
3589566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3602764a2aaSMatthew G. Knepley }
3612764a2aaSMatthew G. Knepley 
362cc4c1da9SBarry Smith /*@
363dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3642764a2aaSMatthew G. Knepley 
36520f4b53cSBarry Smith   Collective
3662764a2aaSMatthew G. Knepley 
3672764a2aaSMatthew G. Knepley   Input Parameter:
368dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3692764a2aaSMatthew G. Knepley 
3702764a2aaSMatthew G. Knepley   Level: developer
3712764a2aaSMatthew G. Knepley 
372dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3732764a2aaSMatthew G. Knepley @*/
374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
375d71ae5a4SJacob Faibussowitsch {
3762764a2aaSMatthew G. Knepley   const PetscInt Nf          = prob->Nf;
377f9244615SMatthew G. Knepley   PetscBool      hasH        = PETSC_FALSE;
378e59ddd55SMatthew G. Knepley   PetscInt       maxOrder[4] = {-2, -2, -2, -2};
3794bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3802764a2aaSMatthew G. Knepley 
3812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3822764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3833ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3842764a2aaSMatthew G. Knepley   /* Calculate sizes */
3859566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3869566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
387f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3899566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3909566063dSJacob Faibussowitsch   PetscCall(PetscCalloc6(Nf + 1, &prob->offCohesive[0], Nf + 1, &prob->offCohesive[1], Nf + 1, &prob->offCohesive[2], Nf + 1, &prob->offDerCohesive[0], Nf + 1, &prob->offDerCohesive[1], Nf + 1, &prob->offDerCohesive[2]));
3919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
39212fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
39307218a29SMatthew G. Knepley     // Note: This assumes we have one kind of cell at each dimension.
39407218a29SMatthew G. Knepley     //       We can fix this by having quadrature hold the celltype
39507218a29SMatthew G. Knepley     PetscQuadrature maxQuad[4] = {NULL, NULL, NULL, NULL};
39612fc5b22SMatthew G. Knepley 
39712fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
39812fc5b22SMatthew G. Knepley       PetscObject     obj;
39912fc5b22SMatthew G. Knepley       PetscClassId    id;
40012fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
40107218a29SMatthew G. Knepley       PetscInt        dim = -1, order = -1, forder = -1;
40212fc5b22SMatthew G. Knepley 
40312fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40412fc5b22SMatthew G. Knepley       if (!obj) continue;
40512fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
40612fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
40712fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
40812fc5b22SMatthew G. Knepley 
40912fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
41012fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
41112fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41212fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
41312fc5b22SMatthew G. Knepley 
41412fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
41512fc5b22SMatthew G. Knepley       }
41607218a29SMatthew G. Knepley       if (q) {
41707218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
41807218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(q, &order));
41907218a29SMatthew G. Knepley         if (order > maxOrder[dim]) {
42007218a29SMatthew G. Knepley           maxOrder[dim] = order;
42107218a29SMatthew G. Knepley           maxQuad[dim]  = q;
42212fc5b22SMatthew G. Knepley         }
42307218a29SMatthew G. Knepley       }
42407218a29SMatthew G. Knepley       if (fq) {
42507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
42607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(fq, &forder));
42707218a29SMatthew G. Knepley         if (forder > maxOrder[dim]) {
42807218a29SMatthew G. Knepley           maxOrder[dim] = forder;
42907218a29SMatthew G. Knepley           maxQuad[dim]  = fq;
43007218a29SMatthew G. Knepley         }
43112fc5b22SMatthew G. Knepley       }
43212fc5b22SMatthew G. Knepley     }
43312fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
43412fc5b22SMatthew G. Knepley       PetscObject     obj;
43512fc5b22SMatthew G. Knepley       PetscClassId    id;
43607218a29SMatthew G. Knepley       PetscQuadrature q;
43707218a29SMatthew G. Knepley       PetscInt        dim;
43812fc5b22SMatthew G. Knepley 
43912fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
44012fc5b22SMatthew G. Knepley       if (!obj) continue;
44112fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44212fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44312fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44412fc5b22SMatthew G. Knepley 
44507218a29SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
44607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
44707218a29SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, maxQuad[dim]));
448aa9788aaSMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, dim ? maxQuad[dim - 1] : NULL));
44912fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
45012fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
45112fc5b22SMatthew G. Knepley 
45207218a29SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
45307218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
45407218a29SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, maxQuad[dim]));
45512fc5b22SMatthew G. Knepley       }
45612fc5b22SMatthew G. Knepley     }
45712fc5b22SMatthew G. Knepley   }
4582764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4599de99aefSMatthew G. Knepley     PetscObject     obj;
4609de99aefSMatthew G. Knepley     PetscClassId    id;
461665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4629de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4632764a2aaSMatthew G. Knepley 
4649566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
465f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
466665f567fSMatthew G. Knepley     if (!obj) {
467665f567fSMatthew G. Knepley       /* Empty mesh */
468665f567fSMatthew G. Knepley       Nb = Nc    = 0;
469665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
470665f567fSMatthew G. Knepley     } else {
4719566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4729de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4739de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4749de99aefSMatthew G. Knepley 
4759566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
47649ae0b56SMatthew G. Knepley         {
47749ae0b56SMatthew G. Knepley           PetscQuadrature fq;
47807218a29SMatthew G. Knepley           PetscInt        dim, order;
47949ae0b56SMatthew G. Knepley 
48007218a29SMatthew G. Knepley           PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
48149ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
48207218a29SMatthew G. Knepley           if (maxOrder[dim] < 0) maxOrder[dim] = order;
48307218a29SMatthew G. Knepley           PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, maxOrder[dim]);
48449ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
48549ae0b56SMatthew G. Knepley           if (fq) {
48607218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
48707218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &order));
48807218a29SMatthew G. Knepley             if (maxOrder[dim] < 0) maxOrder[dim] = order;
48907218a29SMatthew G. Knepley             PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, order, maxOrder[dim]);
49049ae0b56SMatthew G. Knepley           }
49149ae0b56SMatthew G. Knepley         }
4929566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4949566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4959566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4969de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4979de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4989de99aefSMatthew G. Knepley 
4999566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
5009566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
5019c3cf19fSMatthew G. Knepley         Nb = Nc;
5029566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
5034d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
50463a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
505665f567fSMatthew G. Knepley     }
50647e57110SSander Arens     prob->Nc[f]                    = Nc;
50747e57110SSander Arens     prob->Nb[f]                    = Nb;
508194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
509194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5109ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5119ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5129ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5139ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5149ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5159ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5169566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5172764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5184bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5192764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5209c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5212764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5225fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5235fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5242764a2aaSMatthew G. Knepley   }
5259ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5269ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5272764a2aaSMatthew G. Knepley   /* Allocate works space */
5285fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(NsMax * prob->totComp, &prob->u, NsMax * prob->totComp, &prob->u_t, NsMax * prob->totComp * dimEmbed + (hasH ? NsMax * prob->totComp * dimEmbed * dimEmbed : 0), &prob->u_x));
5309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5319371c9d4SSatish Balay   PetscCall(PetscMalloc6(NsMax * NqMax * NcMax, &prob->f0, NsMax * NqMax * NcMax * dimEmbed, &prob->f1, NsMax * NsMax * NqMax * NcMax * NcMax, &prob->g0, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed, &prob->g1, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed,
5329371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
533dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5342764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5362764a2aaSMatthew G. Knepley }
5372764a2aaSMatthew G. Knepley 
538d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
539d71ae5a4SJacob Faibussowitsch {
5402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5429566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5439566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5449566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5459566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5479566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5492764a2aaSMatthew G. Knepley }
5502764a2aaSMatthew G. Knepley 
551d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
552d71ae5a4SJacob Faibussowitsch {
553f744cafaSSander Arens   PetscObject         *tmpd;
55434aa8a36SMatthew G. Knepley   PetscBool           *tmpi;
555f9244615SMatthew G. Knepley   PetscInt            *tmpk;
5565fedec97SMatthew G. Knepley   PetscBool           *tmpc;
5576528b96dSMatthew G. Knepley   PetscPointFunc      *tmpup;
558342bd5aaSMatthew G. Knepley   PetscSimplePointFn **tmpexactSol, **tmpexactSol_t, **tmplowerBound, **tmpupperBound;
559342bd5aaSMatthew G. Knepley   void               **tmpexactCtx, **tmpexactCtx_t, **tmplowerCtx, **tmpupperCtx;
5600c2f2876SMatthew G. Knepley   void               **tmpctx;
56134aa8a36SMatthew G. Knepley   PetscInt             Nf = prob->Nf, f;
5622764a2aaSMatthew G. Knepley 
5632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5643ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5652764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5669566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5679566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5689371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5699371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5709371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5719371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5729371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5739371c9d4SSatish Balay   }
5749371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5759371c9d4SSatish Balay     tmpd[f] = NULL;
5769371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5779371c9d4SSatish Balay     tmpk[f] = 1;
5789371c9d4SSatish Balay   }
5799566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5812764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5822764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
583249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5845fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
585f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5869566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58732d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5880c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58932d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5900c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5919566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59232d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5930c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5949566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
595342bd5aaSMatthew G. Knepley   PetscCall(PetscCalloc4(NfNew, &tmplowerBound, NfNew, &tmplowerCtx, NfNew, &tmpupperBound, NfNew, &tmpupperCtx));
596c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59795cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
598f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
599f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
600342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerBound[f] = prob->lowerBound[f];
601342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerCtx[f] = prob->lowerCtx[f];
602342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperBound[f] = prob->upperBound[f];
603342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperCtx[f] = prob->upperCtx[f];
604c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
60595cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
606f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
607f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
608342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerBound[f] = NULL;
609342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerCtx[f] = NULL;
610342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperBound[f] = NULL;
611342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperCtx[f] = NULL;
6129566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
613342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4(prob->lowerBound, prob->lowerCtx, prob->upperBound, prob->upperCtx));
614c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
61595cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
616f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
617f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
618342bd5aaSMatthew G. Knepley   prob->lowerBound = tmplowerBound;
619342bd5aaSMatthew G. Knepley   prob->lowerCtx   = tmplowerCtx;
620342bd5aaSMatthew G. Knepley   prob->upperBound = tmpupperBound;
621342bd5aaSMatthew G. Knepley   prob->upperCtx   = tmpupperCtx;
6223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6232764a2aaSMatthew G. Knepley }
6242764a2aaSMatthew G. Knepley 
6252764a2aaSMatthew G. Knepley /*@
62620f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6272764a2aaSMatthew G. Knepley 
62820f4b53cSBarry Smith   Collective
6292764a2aaSMatthew G. Knepley 
6302764a2aaSMatthew G. Knepley   Input Parameter:
63160225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6322764a2aaSMatthew G. Knepley 
6332764a2aaSMatthew G. Knepley   Level: developer
6342764a2aaSMatthew G. Knepley 
635dce8aebaSBarry Smith .seealso: `PetscDSView()`
6362764a2aaSMatthew G. Knepley @*/
637d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
638d71ae5a4SJacob Faibussowitsch {
6392764a2aaSMatthew G. Knepley   PetscInt f;
6402764a2aaSMatthew G. Knepley 
6412764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6423ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
643f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6442764a2aaSMatthew G. Knepley 
645f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6469371c9d4SSatish Balay     *ds = NULL;
6473ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6489371c9d4SSatish Balay   }
649f4f49eeaSPierre Jolivet   ((PetscObject)*ds)->refct = 0;
6506528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
651df3a45bdSMatthew G. Knepley     PetscInt dim, d;
652df3a45bdSMatthew G. Knepley 
6539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6549566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
655df3a45bdSMatthew G. Knepley   }
6569566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6579566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
65848a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6599566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6609566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6619566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6629566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
663342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4((*ds)->lowerBound, (*ds)->lowerCtx, (*ds)->upperBound, (*ds)->upperCtx));
664f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ds, destroy);
6659566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6669566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6674366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
66885036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((DMPolytopeType)c);
6694366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6704366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6714366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6724366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6734366bac7SMatthew G. Knepley   }
6749566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6762764a2aaSMatthew G. Knepley }
6772764a2aaSMatthew G. Knepley 
6782764a2aaSMatthew G. Knepley /*@
679dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6802764a2aaSMatthew G. Knepley 
681d083f849SBarry Smith   Collective
6822764a2aaSMatthew G. Knepley 
6832764a2aaSMatthew G. Knepley   Input Parameter:
684dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6852764a2aaSMatthew G. Knepley 
6862764a2aaSMatthew G. Knepley   Output Parameter:
687dce8aebaSBarry Smith . ds - The `PetscDS` object
6882764a2aaSMatthew G. Knepley 
6892764a2aaSMatthew G. Knepley   Level: beginner
6902764a2aaSMatthew G. Knepley 
691dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6922764a2aaSMatthew G. Knepley @*/
693d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
694d71ae5a4SJacob Faibussowitsch {
6952764a2aaSMatthew G. Knepley   PetscDS p;
6962764a2aaSMatthew G. Knepley 
6972764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6984f572ea9SToby Isaac   PetscAssertPointer(ds, 2);
6999566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
7002764a2aaSMatthew G. Knepley 
7019566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
7022764a2aaSMatthew G. Knepley   p->Nf               = 0;
7032764a2aaSMatthew G. Knepley   p->setup            = PETSC_FALSE;
70497b6e6e8SMatthew G. Knepley   p->numConstants     = 0;
70587510d7dSMatthew G. Knepley   p->numFuncConstants = 3; // Row and col fields, cell size
706a859676bSMatthew G. Knepley   p->dimEmbed         = -1;
70755c1f793SMatthew G. Knepley   p->useJacPre        = PETSC_TRUE;
70812fc5b22SMatthew G. Knepley   p->forceQuad        = PETSC_TRUE;
709a102dd69SStefano Zampini   PetscCall(PetscMalloc1(p->numConstants + p->numFuncConstants, &p->constants));
7109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
7114366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
7126528b96dSMatthew G. Knepley   *ds = p;
7133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7142764a2aaSMatthew G. Knepley }
7152764a2aaSMatthew G. Knepley 
716bc4ae4beSMatthew G. Knepley /*@
717dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
718bc4ae4beSMatthew G. Knepley 
71920f4b53cSBarry Smith   Not Collective
720bc4ae4beSMatthew G. Knepley 
721bc4ae4beSMatthew G. Knepley   Input Parameter:
72220f4b53cSBarry Smith . prob - The `PetscDS` object
723bc4ae4beSMatthew G. Knepley 
724bc4ae4beSMatthew G. Knepley   Output Parameter:
725bc4ae4beSMatthew G. Knepley . Nf - The number of fields
726bc4ae4beSMatthew G. Knepley 
727bc4ae4beSMatthew G. Knepley   Level: beginner
728bc4ae4beSMatthew G. Knepley 
729dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
730bc4ae4beSMatthew G. Knepley @*/
731d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
732d71ae5a4SJacob Faibussowitsch {
7332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7342764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7354f572ea9SToby Isaac   PetscAssertPointer(Nf, 2);
7362764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7382764a2aaSMatthew G. Knepley }
7392764a2aaSMatthew G. Knepley 
740bc4ae4beSMatthew G. Knepley /*@
741dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
742bc4ae4beSMatthew G. Knepley 
74320f4b53cSBarry Smith   Not Collective
744bc4ae4beSMatthew G. Knepley 
745bc4ae4beSMatthew G. Knepley   Input Parameter:
746dce8aebaSBarry Smith . prob - The `PetscDS` object
747bc4ae4beSMatthew G. Knepley 
748bc4ae4beSMatthew G. Knepley   Output Parameter:
749bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
750bc4ae4beSMatthew G. Knepley 
751bc4ae4beSMatthew G. Knepley   Level: beginner
752bc4ae4beSMatthew G. Knepley 
753dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
754bc4ae4beSMatthew G. Knepley @*/
755d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
756d71ae5a4SJacob Faibussowitsch {
7572764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7582764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7594f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
7602764a2aaSMatthew G. Knepley   *dim = 0;
7619de99aefSMatthew G. Knepley   if (prob->Nf) {
7629de99aefSMatthew G. Knepley     PetscObject  obj;
7639de99aefSMatthew G. Knepley     PetscClassId id;
7649de99aefSMatthew G. Knepley 
7659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
766665f567fSMatthew G. Knepley     if (obj) {
7679566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7689566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7699566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
77098921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7719de99aefSMatthew G. Knepley     }
772665f567fSMatthew G. Knepley   }
7733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7742764a2aaSMatthew G. Knepley }
7752764a2aaSMatthew G. Knepley 
776bc4ae4beSMatthew G. Knepley /*@
777dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
778a859676bSMatthew G. Knepley 
77920f4b53cSBarry Smith   Not Collective
780a859676bSMatthew G. Knepley 
781a859676bSMatthew G. Knepley   Input Parameter:
782dce8aebaSBarry Smith . prob - The `PetscDS` object
783a859676bSMatthew G. Knepley 
784a859676bSMatthew G. Knepley   Output Parameter:
785a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
786a859676bSMatthew G. Knepley 
787a859676bSMatthew G. Knepley   Level: beginner
788a859676bSMatthew G. Knepley 
789dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
790a859676bSMatthew G. Knepley @*/
791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
792d71ae5a4SJacob Faibussowitsch {
793a859676bSMatthew G. Knepley   PetscFunctionBegin;
794a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7954f572ea9SToby Isaac   PetscAssertPointer(dimEmbed, 2);
79608401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
797a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
799a859676bSMatthew G. Knepley }
800a859676bSMatthew G. Knepley 
801a859676bSMatthew G. Knepley /*@
802dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
803a859676bSMatthew G. Knepley 
80420f4b53cSBarry Smith   Logically Collective
805a859676bSMatthew G. Knepley 
806a859676bSMatthew G. Knepley   Input Parameters:
807dce8aebaSBarry Smith + prob     - The `PetscDS` object
808a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
809a859676bSMatthew G. Knepley 
810a859676bSMatthew G. Knepley   Level: beginner
811a859676bSMatthew G. Knepley 
812dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
813a859676bSMatthew G. Knepley @*/
814d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
815d71ae5a4SJacob Faibussowitsch {
816a859676bSMatthew G. Knepley   PetscFunctionBegin;
817a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
81863a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
819a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
821a859676bSMatthew G. Knepley }
822a859676bSMatthew G. Knepley 
823a859676bSMatthew G. Knepley /*@
82412fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
82512fc5b22SMatthew G. Knepley 
82612fc5b22SMatthew G. Knepley   Not collective
82712fc5b22SMatthew G. Knepley 
82812fc5b22SMatthew G. Knepley   Input Parameter:
82960225df5SJacob Faibussowitsch . ds - The `PetscDS` object
83012fc5b22SMatthew G. Knepley 
83112fc5b22SMatthew G. Knepley   Output Parameter:
83212fc5b22SMatthew G. Knepley . forceQuad - The flag
83312fc5b22SMatthew G. Knepley 
83412fc5b22SMatthew G. Knepley   Level: intermediate
83512fc5b22SMatthew G. Knepley 
83612fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
83712fc5b22SMatthew G. Knepley @*/
83812fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
83912fc5b22SMatthew G. Knepley {
84012fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84112fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8424f572ea9SToby Isaac   PetscAssertPointer(forceQuad, 2);
84312fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
84412fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
84512fc5b22SMatthew G. Knepley }
84612fc5b22SMatthew G. Knepley 
84712fc5b22SMatthew G. Knepley /*@
84812fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
84912fc5b22SMatthew G. Knepley 
85012fc5b22SMatthew G. Knepley   Logically collective on ds
85112fc5b22SMatthew G. Knepley 
85212fc5b22SMatthew G. Knepley   Input Parameters:
85312fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
85412fc5b22SMatthew G. Knepley - forceQuad - The flag
85512fc5b22SMatthew G. Knepley 
85612fc5b22SMatthew G. Knepley   Level: intermediate
85712fc5b22SMatthew G. Knepley 
85812fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
85912fc5b22SMatthew G. Knepley @*/
86012fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
86112fc5b22SMatthew G. Knepley {
86212fc5b22SMatthew G. Knepley   PetscFunctionBegin;
86312fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
86412fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
86512fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
86612fc5b22SMatthew G. Knepley }
86712fc5b22SMatthew G. Knepley 
86812fc5b22SMatthew G. Knepley /*@
869dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8708edf6225SMatthew G. Knepley 
87120f4b53cSBarry Smith   Not Collective
8728edf6225SMatthew G. Knepley 
8738edf6225SMatthew G. Knepley   Input Parameter:
874dce8aebaSBarry Smith . ds - The `PetscDS` object
8758edf6225SMatthew G. Knepley 
8768edf6225SMatthew G. Knepley   Output Parameter:
8775fedec97SMatthew G. Knepley . isCohesive - The flag
8788edf6225SMatthew G. Knepley 
8798edf6225SMatthew G. Knepley   Level: developer
8808edf6225SMatthew G. Knepley 
881dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8828edf6225SMatthew G. Knepley @*/
883d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
884d71ae5a4SJacob Faibussowitsch {
8858edf6225SMatthew G. Knepley   PetscFunctionBegin;
8865fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8874f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 2);
8885fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8908edf6225SMatthew G. Knepley }
8918edf6225SMatthew G. Knepley 
8928edf6225SMatthew G. Knepley /*@
893be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8945fedec97SMatthew G. Knepley 
89520f4b53cSBarry Smith   Not Collective
8965fedec97SMatthew G. Knepley 
8975fedec97SMatthew G. Knepley   Input Parameter:
898dce8aebaSBarry Smith . ds - The `PetscDS` object
8995fedec97SMatthew G. Knepley 
9005fedec97SMatthew G. Knepley   Output Parameter:
9015fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
9025fedec97SMatthew G. Knepley 
9035fedec97SMatthew G. Knepley   Level: developer
9045fedec97SMatthew G. Knepley 
905dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
9065fedec97SMatthew G. Knepley @*/
907d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
908d71ae5a4SJacob Faibussowitsch {
9095fedec97SMatthew G. Knepley   PetscInt f;
9105fedec97SMatthew G. Knepley 
9115fedec97SMatthew G. Knepley   PetscFunctionBegin;
9125fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9134f572ea9SToby Isaac   PetscAssertPointer(numCohesive, 2);
9145fedec97SMatthew G. Knepley   *numCohesive = 0;
9155fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9175fedec97SMatthew G. Knepley }
9185fedec97SMatthew G. Knepley 
9195fedec97SMatthew G. Knepley /*@
9205fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9215fedec97SMatthew G. Knepley 
92220f4b53cSBarry Smith   Not Collective
9235fedec97SMatthew G. Knepley 
924f1a722f8SMatthew G. Knepley   Input Parameters:
925dce8aebaSBarry Smith + ds - The `PetscDS` object
9265fedec97SMatthew G. Knepley - f  - The field index
9275fedec97SMatthew G. Knepley 
9285fedec97SMatthew G. Knepley   Output Parameter:
9295fedec97SMatthew G. Knepley . isCohesive - The flag
9305fedec97SMatthew G. Knepley 
9315fedec97SMatthew G. Knepley   Level: developer
9325fedec97SMatthew G. Knepley 
933dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9345fedec97SMatthew G. Knepley @*/
935d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
936d71ae5a4SJacob Faibussowitsch {
9375fedec97SMatthew G. Knepley   PetscFunctionBegin;
9385fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9394f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 3);
94063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9415fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9435fedec97SMatthew G. Knepley }
9445fedec97SMatthew G. Knepley 
9455fedec97SMatthew G. Knepley /*@
9465fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9478edf6225SMatthew G. Knepley 
94820f4b53cSBarry Smith   Not Collective
9498edf6225SMatthew G. Knepley 
9508edf6225SMatthew G. Knepley   Input Parameters:
951dce8aebaSBarry Smith + ds         - The `PetscDS` object
9525fedec97SMatthew G. Knepley . f          - The field index
9535fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9548edf6225SMatthew G. Knepley 
9558edf6225SMatthew G. Knepley   Level: developer
9568edf6225SMatthew G. Knepley 
957dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9588edf6225SMatthew G. Knepley @*/
959d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
960d71ae5a4SJacob Faibussowitsch {
9615fedec97SMatthew G. Knepley   PetscInt i;
9625fedec97SMatthew G. Knepley 
9638edf6225SMatthew G. Knepley   PetscFunctionBegin;
9645fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
96563a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9665fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9675fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9685fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9708edf6225SMatthew G. Knepley }
9718edf6225SMatthew G. Knepley 
9728edf6225SMatthew G. Knepley /*@
973bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
974bc4ae4beSMatthew G. Knepley 
97520f4b53cSBarry Smith   Not Collective
976bc4ae4beSMatthew G. Knepley 
977bc4ae4beSMatthew G. Knepley   Input Parameter:
978dce8aebaSBarry Smith . prob - The `PetscDS` object
979bc4ae4beSMatthew G. Knepley 
980bc4ae4beSMatthew G. Knepley   Output Parameter:
981bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
982bc4ae4beSMatthew G. Knepley 
983bc4ae4beSMatthew G. Knepley   Level: beginner
984bc4ae4beSMatthew G. Knepley 
985dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
986bc4ae4beSMatthew G. Knepley @*/
987d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
988d71ae5a4SJacob Faibussowitsch {
9892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9902764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9919566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
9924f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
9932764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9952764a2aaSMatthew G. Knepley }
9962764a2aaSMatthew G. Knepley 
997bc4ae4beSMatthew G. Knepley /*@
998bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
999bc4ae4beSMatthew G. Knepley 
100020f4b53cSBarry Smith   Not Collective
1001bc4ae4beSMatthew G. Knepley 
1002bc4ae4beSMatthew G. Knepley   Input Parameter:
1003dce8aebaSBarry Smith . prob - The `PetscDS` object
1004bc4ae4beSMatthew G. Knepley 
1005bc4ae4beSMatthew G. Knepley   Output Parameter:
100660225df5SJacob Faibussowitsch . Nc - The total number of components
1007bc4ae4beSMatthew G. Knepley 
1008bc4ae4beSMatthew G. Knepley   Level: beginner
1009bc4ae4beSMatthew G. Knepley 
1010dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1011bc4ae4beSMatthew G. Knepley @*/
1012d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
1013d71ae5a4SJacob Faibussowitsch {
10142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
10174f572ea9SToby Isaac   PetscAssertPointer(Nc, 2);
10182764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10202764a2aaSMatthew G. Knepley }
10212764a2aaSMatthew G. Knepley 
1022bc4ae4beSMatthew G. Knepley /*@
1023bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1024bc4ae4beSMatthew G. Knepley 
102520f4b53cSBarry Smith   Not Collective
1026bc4ae4beSMatthew G. Knepley 
1027bc4ae4beSMatthew G. Knepley   Input Parameters:
1028dce8aebaSBarry Smith + prob - The `PetscDS` object
1029bc4ae4beSMatthew G. Knepley - f    - The field number
1030bc4ae4beSMatthew G. Knepley 
1031bc4ae4beSMatthew G. Knepley   Output Parameter:
1032bc4ae4beSMatthew G. Knepley . disc - The discretization object
1033bc4ae4beSMatthew G. Knepley 
1034bc4ae4beSMatthew G. Knepley   Level: beginner
1035bc4ae4beSMatthew G. Knepley 
1036dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1037bc4ae4beSMatthew G. Knepley @*/
1038d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1039d71ae5a4SJacob Faibussowitsch {
10406528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10412764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10424f572ea9SToby Isaac   PetscAssertPointer(disc, 3);
104363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
10442764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10462764a2aaSMatthew G. Knepley }
10472764a2aaSMatthew G. Knepley 
1048bc4ae4beSMatthew G. Knepley /*@
1049bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1050bc4ae4beSMatthew G. Knepley 
105120f4b53cSBarry Smith   Not Collective
1052bc4ae4beSMatthew G. Knepley 
1053bc4ae4beSMatthew G. Knepley   Input Parameters:
1054dce8aebaSBarry Smith + prob - The `PetscDS` object
1055bc4ae4beSMatthew G. Knepley . f    - The field number
1056bc4ae4beSMatthew G. Knepley - disc - The discretization object
1057bc4ae4beSMatthew G. Knepley 
1058bc4ae4beSMatthew G. Knepley   Level: beginner
1059bc4ae4beSMatthew G. Knepley 
1060dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1061bc4ae4beSMatthew G. Knepley @*/
1062d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1063d71ae5a4SJacob Faibussowitsch {
10642764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10652764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10664f572ea9SToby Isaac   if (disc) PetscAssertPointer(disc, 3);
106763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10689566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10699566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10702764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10719566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1072665f567fSMatthew G. Knepley   if (disc) {
1073249df284SMatthew G. Knepley     PetscClassId id;
1074249df284SMatthew G. Knepley 
10759566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10761cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10779566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10781cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10799566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1080a6cbbb48SMatthew G. Knepley     }
10819566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1082249df284SMatthew G. Knepley   }
10833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10842764a2aaSMatthew G. Knepley }
10852764a2aaSMatthew G. Knepley 
1086bc4ae4beSMatthew G. Knepley /*@
10876528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10886528b96dSMatthew G. Knepley 
108920f4b53cSBarry Smith   Not Collective
10906528b96dSMatthew G. Knepley 
10916528b96dSMatthew G. Knepley   Input Parameter:
1092dce8aebaSBarry Smith . ds - The `PetscDS` object
10936528b96dSMatthew G. Knepley 
10946528b96dSMatthew G. Knepley   Output Parameter:
10956528b96dSMatthew G. Knepley . wf - The weak form object
10966528b96dSMatthew G. Knepley 
10976528b96dSMatthew G. Knepley   Level: beginner
10986528b96dSMatthew G. Knepley 
1099dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11006528b96dSMatthew G. Knepley @*/
1101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1102d71ae5a4SJacob Faibussowitsch {
11036528b96dSMatthew G. Knepley   PetscFunctionBegin;
11046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11054f572ea9SToby Isaac   PetscAssertPointer(wf, 2);
11066528b96dSMatthew G. Knepley   *wf = ds->wf;
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11086528b96dSMatthew G. Knepley }
11096528b96dSMatthew G. Knepley 
11106528b96dSMatthew G. Knepley /*@
11116528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
11126528b96dSMatthew G. Knepley 
111320f4b53cSBarry Smith   Not Collective
11146528b96dSMatthew G. Knepley 
11156528b96dSMatthew G. Knepley   Input Parameters:
1116dce8aebaSBarry Smith + ds - The `PetscDS` object
11176528b96dSMatthew G. Knepley - wf - The weak form object
11186528b96dSMatthew G. Knepley 
11196528b96dSMatthew G. Knepley   Level: beginner
11206528b96dSMatthew G. Knepley 
1121dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11226528b96dSMatthew G. Knepley @*/
1123d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1124d71ae5a4SJacob Faibussowitsch {
11256528b96dSMatthew G. Knepley   PetscFunctionBegin;
11266528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11276528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11289566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11296528b96dSMatthew G. Knepley   ds->wf = wf;
11309566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11336528b96dSMatthew G. Knepley }
11346528b96dSMatthew G. Knepley 
11356528b96dSMatthew G. Knepley /*@
1136bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1137bc4ae4beSMatthew G. Knepley 
113820f4b53cSBarry Smith   Not Collective
1139bc4ae4beSMatthew G. Knepley 
1140bc4ae4beSMatthew G. Knepley   Input Parameters:
1141dce8aebaSBarry Smith + prob - The `PetscDS` object
1142bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1143bc4ae4beSMatthew G. Knepley 
1144bc4ae4beSMatthew G. Knepley   Level: beginner
1145bc4ae4beSMatthew G. Knepley 
1146dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1147bc4ae4beSMatthew G. Knepley @*/
1148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1149d71ae5a4SJacob Faibussowitsch {
11502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11532764a2aaSMatthew G. Knepley }
11542764a2aaSMatthew G. Knepley 
1155249df284SMatthew G. Knepley /*@
1156dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1157083401c6SMatthew G. Knepley 
115820f4b53cSBarry Smith   Not Collective
1159083401c6SMatthew G. Knepley 
1160083401c6SMatthew G. Knepley   Input Parameter:
1161dce8aebaSBarry Smith . prob - The `PetscDS` object
1162083401c6SMatthew G. Knepley 
1163083401c6SMatthew G. Knepley   Output Parameter:
1164083401c6SMatthew G. Knepley . q - The quadrature object
1165083401c6SMatthew G. Knepley 
1166083401c6SMatthew G. Knepley   Level: intermediate
1167083401c6SMatthew G. Knepley 
1168dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1169083401c6SMatthew G. Knepley @*/
1170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1171d71ae5a4SJacob Faibussowitsch {
1172083401c6SMatthew G. Knepley   PetscObject  obj;
1173083401c6SMatthew G. Knepley   PetscClassId id;
1174083401c6SMatthew G. Knepley 
1175083401c6SMatthew G. Knepley   PetscFunctionBegin;
1176083401c6SMatthew G. Knepley   *q = NULL;
11773ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11789566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11799566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11809566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11819566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
118298921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1184083401c6SMatthew G. Knepley }
1185083401c6SMatthew G. Knepley 
1186083401c6SMatthew G. Knepley /*@
11873dddbd81SStefano Zampini   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1188249df284SMatthew G. Knepley 
118920f4b53cSBarry Smith   Not Collective
1190249df284SMatthew G. Knepley 
1191249df284SMatthew G. Knepley   Input Parameters:
1192dce8aebaSBarry Smith + prob - The `PetscDS` object
1193249df284SMatthew G. Knepley - f    - The field number
1194249df284SMatthew G. Knepley 
1195249df284SMatthew G. Knepley   Output Parameter:
1196249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1197249df284SMatthew G. Knepley 
1198249df284SMatthew G. Knepley   Level: developer
1199249df284SMatthew G. Knepley 
12003dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1201249df284SMatthew G. Knepley @*/
1202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1203d71ae5a4SJacob Faibussowitsch {
1204249df284SMatthew G. Knepley   PetscFunctionBegin;
1205249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
12064f572ea9SToby Isaac   PetscAssertPointer(implicit, 3);
120763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1208249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
12093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1210249df284SMatthew G. Knepley }
1211249df284SMatthew G. Knepley 
1212249df284SMatthew G. Knepley /*@
12133dddbd81SStefano Zampini   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1214249df284SMatthew G. Knepley 
121520f4b53cSBarry Smith   Not Collective
1216249df284SMatthew G. Knepley 
1217249df284SMatthew G. Knepley   Input Parameters:
1218dce8aebaSBarry Smith + prob     - The `PetscDS` object
1219249df284SMatthew G. Knepley . f        - The field number
1220249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1221249df284SMatthew G. Knepley 
1222249df284SMatthew G. Knepley   Level: developer
1223249df284SMatthew G. Knepley 
12243dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1225249df284SMatthew G. Knepley @*/
1226d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1227d71ae5a4SJacob Faibussowitsch {
1228249df284SMatthew G. Knepley   PetscFunctionBegin;
1229249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
123063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1231249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1233249df284SMatthew G. Knepley }
1234249df284SMatthew G. Knepley 
1235f9244615SMatthew G. Knepley /*@
1236f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1237f9244615SMatthew G. Knepley 
123820f4b53cSBarry Smith   Not Collective
1239f9244615SMatthew G. Knepley 
1240f9244615SMatthew G. Knepley   Input Parameters:
1241dce8aebaSBarry Smith + ds - The `PetscDS` object
1242f9244615SMatthew G. Knepley - f  - The field number
1243f9244615SMatthew G. Knepley 
1244f9244615SMatthew G. Knepley   Output Parameter:
1245f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1246f9244615SMatthew G. Knepley 
1247f9244615SMatthew G. Knepley   Level: developer
1248f9244615SMatthew G. Knepley 
1249dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1250f9244615SMatthew G. Knepley @*/
1251d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1252d71ae5a4SJacob Faibussowitsch {
1253f9244615SMatthew G. Knepley   PetscFunctionBegin;
1254f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12554f572ea9SToby Isaac   PetscAssertPointer(k, 3);
125663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1257f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1259f9244615SMatthew G. Knepley }
1260f9244615SMatthew G. Knepley 
1261f9244615SMatthew G. Knepley /*@
1262f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1263f9244615SMatthew G. Knepley 
126420f4b53cSBarry Smith   Not Collective
1265f9244615SMatthew G. Knepley 
1266f9244615SMatthew G. Knepley   Input Parameters:
1267dce8aebaSBarry Smith + ds - The `PetscDS` object
1268f9244615SMatthew G. Knepley . f  - The field number
1269f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1270f9244615SMatthew G. Knepley 
1271f9244615SMatthew G. Knepley   Level: developer
1272f9244615SMatthew G. Knepley 
1273a94f484eSPierre Jolivet .seealso: `PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1274f9244615SMatthew G. Knepley @*/
1275d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1276d71ae5a4SJacob Faibussowitsch {
1277f9244615SMatthew G. Knepley   PetscFunctionBegin;
1278f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
127963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1280f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1282f9244615SMatthew G. Knepley }
1283f9244615SMatthew G. Knepley 
1284c8943706SMatthew G. Knepley /*@C
1285c8943706SMatthew G. Knepley   PetscDSGetObjective - Get the pointwise objective function for a given test field
1286c8943706SMatthew G. Knepley 
1287c8943706SMatthew G. Knepley   Not Collective
1288c8943706SMatthew G. Knepley 
1289c8943706SMatthew G. Knepley   Input Parameters:
1290c8943706SMatthew G. Knepley + ds - The `PetscDS`
1291c8943706SMatthew G. Knepley - f  - The test field number
1292c8943706SMatthew G. Knepley 
1293a4e35b19SJacob Faibussowitsch   Output Parameter:
1294c8943706SMatthew G. Knepley . obj - integrand for the test function term
1295c8943706SMatthew G. Knepley 
1296c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1297ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1298c8943706SMatthew G. Knepley . Nf           - the number of fields
1299a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1300b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1301b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1302c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1303c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1304c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1305b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1306b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1307c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1308c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1309c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1310c8943706SMatthew G. Knepley . t            - current time
1311c8943706SMatthew G. Knepley . x            - coordinates of the current point
1312c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1313c8943706SMatthew G. Knepley . constants    - constant parameters
1314c8943706SMatthew G. Knepley - obj          - output values at the current point
1315c8943706SMatthew G. Knepley 
1316c8943706SMatthew G. Knepley   Level: intermediate
1317c8943706SMatthew G. Knepley 
1318c8943706SMatthew G. Knepley   Note:
13191702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1320c8943706SMatthew G. Knepley 
1321c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1322c8943706SMatthew G. Knepley @*/
1323d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f, void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1324d71ae5a4SJacob Faibussowitsch {
13256528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13266528b96dSMatthew G. Knepley   PetscInt        n;
13276528b96dSMatthew G. Knepley 
13282764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13296528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13304f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
133163a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
13329566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13336528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13352764a2aaSMatthew G. Knepley }
13362764a2aaSMatthew G. Knepley 
1337c8943706SMatthew G. Knepley /*@C
1338c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1339c8943706SMatthew G. Knepley 
1340c8943706SMatthew G. Knepley   Not Collective
1341c8943706SMatthew G. Knepley 
1342c8943706SMatthew G. Knepley   Input Parameters:
1343c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1344c8943706SMatthew G. Knepley . f   - The test field number
1345c8943706SMatthew G. Knepley - obj - integrand for the test function term
1346c8943706SMatthew G. Knepley 
1347c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1348ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1349c8943706SMatthew G. Knepley . Nf           - the number of fields
1350a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1351b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1352b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1353c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1354c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1355c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1356b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1357b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1358c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1359c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1360c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1361c8943706SMatthew G. Knepley . t            - current time
1362c8943706SMatthew G. Knepley . x            - coordinates of the current point
1363c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1364c8943706SMatthew G. Knepley . constants    - constant parameters
1365c8943706SMatthew G. Knepley - obj          - output values at the current point
1366c8943706SMatthew G. Knepley 
1367c8943706SMatthew G. Knepley   Level: intermediate
1368c8943706SMatthew G. Knepley 
1369c8943706SMatthew G. Knepley   Note:
13701702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1371c8943706SMatthew G. Knepley 
1372c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1373c8943706SMatthew G. Knepley @*/
1374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f, void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1375d71ae5a4SJacob Faibussowitsch {
13762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13786528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
137963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13822764a2aaSMatthew G. Knepley }
13832764a2aaSMatthew G. Knepley 
1384194d53e6SMatthew G. Knepley /*@C
1385194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1386194d53e6SMatthew G. Knepley 
138720f4b53cSBarry Smith   Not Collective
1388194d53e6SMatthew G. Knepley 
1389194d53e6SMatthew G. Knepley   Input Parameters:
1390dce8aebaSBarry Smith + ds - The `PetscDS`
1391194d53e6SMatthew G. Knepley - f  - The test field number
1392194d53e6SMatthew G. Knepley 
1393194d53e6SMatthew G. Knepley   Output Parameters:
1394194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1395194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1396194d53e6SMatthew G. Knepley 
1397a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1398ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1399194d53e6SMatthew G. Knepley . Nf           - the number of fields
1400a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1401b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1402b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1403194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1404194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1405194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1406b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1407b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1408194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1409194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1410194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1411194d53e6SMatthew G. Knepley . t            - current time
1412194d53e6SMatthew G. Knepley . x            - coordinates of the current point
141397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
141497b6e6e8SMatthew G. Knepley . constants    - constant parameters
1415194d53e6SMatthew G. Knepley - f0           - output values at the current point
1416194d53e6SMatthew G. Knepley 
1417194d53e6SMatthew G. Knepley   Level: intermediate
1418194d53e6SMatthew G. Knepley 
1419dce8aebaSBarry Smith   Note:
1420a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1421a4e35b19SJacob Faibussowitsch 
14221d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1423dce8aebaSBarry Smith 
1424dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1425194d53e6SMatthew G. Knepley @*/
1426a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1427d71ae5a4SJacob Faibussowitsch {
14286528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14296528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14306528b96dSMatthew G. Knepley 
14312764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
143363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
14349566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14356528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14366528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14382764a2aaSMatthew G. Knepley }
14392764a2aaSMatthew G. Knepley 
1440194d53e6SMatthew G. Knepley /*@C
1441194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1442194d53e6SMatthew G. Knepley 
144320f4b53cSBarry Smith   Not Collective
1444194d53e6SMatthew G. Knepley 
1445194d53e6SMatthew G. Knepley   Input Parameters:
1446dce8aebaSBarry Smith + ds - The `PetscDS`
1447194d53e6SMatthew G. Knepley . f  - The test field number
1448194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1449194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1450194d53e6SMatthew G. Knepley 
1451a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1452ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1453194d53e6SMatthew G. Knepley . Nf           - the number of fields
1454a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1455b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1456b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1457194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1458194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1459194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1460b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1461b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1462194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1463194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1464194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1465194d53e6SMatthew G. Knepley . t            - current time
1466194d53e6SMatthew G. Knepley . x            - coordinates of the current point
146797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
146897b6e6e8SMatthew G. Knepley . constants    - constant parameters
1469194d53e6SMatthew G. Knepley - f0           - output values at the current point
1470194d53e6SMatthew G. Knepley 
1471194d53e6SMatthew G. Knepley   Level: intermediate
1472194d53e6SMatthew G. Knepley 
1473dce8aebaSBarry Smith   Note:
1474a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1475a4e35b19SJacob Faibussowitsch 
14761d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1477dce8aebaSBarry Smith 
1478dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1479194d53e6SMatthew G. Knepley @*/
1480a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1481d71ae5a4SJacob Faibussowitsch {
14822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14836528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1484f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1485f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
148663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14879566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14892764a2aaSMatthew G. Knepley }
14902764a2aaSMatthew G. Knepley 
14913e75805dSMatthew G. Knepley /*@C
1492cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1493cb36c0f9SMatthew G. Knepley 
149420f4b53cSBarry Smith   Not Collective
1495cb36c0f9SMatthew G. Knepley 
1496cb36c0f9SMatthew G. Knepley   Input Parameters:
1497dce8aebaSBarry Smith + ds - The `PetscDS`
1498cb36c0f9SMatthew G. Knepley - f  - The test field number
1499cb36c0f9SMatthew G. Knepley 
1500cb36c0f9SMatthew G. Knepley   Output Parameters:
1501cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1502cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1503cb36c0f9SMatthew G. Knepley 
1504a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1505ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1506cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1507a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1508b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1509b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1510cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1511cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1512cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1513b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1514b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1515cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1516cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1517cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1518cb36c0f9SMatthew G. Knepley . t            - current time
1519cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1520cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1521cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1522cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1523cb36c0f9SMatthew G. Knepley 
1524cb36c0f9SMatthew G. Knepley   Level: intermediate
1525cb36c0f9SMatthew G. Knepley 
1526dce8aebaSBarry Smith   Note:
1527a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1528a4e35b19SJacob Faibussowitsch 
15291d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $ \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1530dce8aebaSBarry Smith 
1531dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1532cb36c0f9SMatthew G. Knepley @*/
1533a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1534d71ae5a4SJacob Faibussowitsch {
1535cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1536cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1537cb36c0f9SMatthew G. Knepley 
1538cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1539cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
154063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
15419566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1542cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1543cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1545cb36c0f9SMatthew G. Knepley }
1546cb36c0f9SMatthew G. Knepley 
1547cb36c0f9SMatthew G. Knepley /*@C
1548cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1549cb36c0f9SMatthew G. Knepley 
155020f4b53cSBarry Smith   Not Collective
1551cb36c0f9SMatthew G. Knepley 
1552cb36c0f9SMatthew G. Knepley   Input Parameters:
1553dce8aebaSBarry Smith + ds - The `PetscDS`
1554cb36c0f9SMatthew G. Knepley . f  - The test field number
1555cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1556cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1557cb36c0f9SMatthew G. Knepley 
1558a4e35b19SJacob Faibussowitsch   Calling sequence for the callbacks `f0`:
1559ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1560cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1561a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1562b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1563b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1564cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1565cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1566cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1567b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1568b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1569cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1570cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1571cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1572cb36c0f9SMatthew G. Knepley . t            - current time
1573cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1574cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1575cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1576cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1577cb36c0f9SMatthew G. Knepley 
1578cb36c0f9SMatthew G. Knepley   Level: intermediate
1579cb36c0f9SMatthew G. Knepley 
1580dce8aebaSBarry Smith   Note:
1581a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1582a4e35b19SJacob Faibussowitsch 
15831d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $ \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1584dce8aebaSBarry Smith 
1585dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1586cb36c0f9SMatthew G. Knepley @*/
1587a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1588d71ae5a4SJacob Faibussowitsch {
1589cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1590cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1591cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1592cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
159363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1596cb36c0f9SMatthew G. Knepley }
1597cb36c0f9SMatthew G. Knepley 
1598cc4c1da9SBarry Smith /*@
1599dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
16003e75805dSMatthew G. Knepley 
160120f4b53cSBarry Smith   Not Collective
16023e75805dSMatthew G. Knepley 
16033e75805dSMatthew G. Knepley   Input Parameter:
160460225df5SJacob Faibussowitsch . ds - The `PetscDS`
16053e75805dSMatthew G. Knepley 
16063e75805dSMatthew G. Knepley   Output Parameter:
16073e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
16083e75805dSMatthew G. Knepley 
16093e75805dSMatthew G. Knepley   Level: intermediate
16103e75805dSMatthew G. Knepley 
1611dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
16123e75805dSMatthew G. Knepley @*/
1613d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1614d71ae5a4SJacob Faibussowitsch {
16153e75805dSMatthew G. Knepley   PetscFunctionBegin;
16166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16193e75805dSMatthew G. Knepley }
16203e75805dSMatthew G. Knepley 
1621194d53e6SMatthew G. Knepley /*@C
1622194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1623194d53e6SMatthew G. Knepley 
162420f4b53cSBarry Smith   Not Collective
1625194d53e6SMatthew G. Knepley 
1626194d53e6SMatthew G. Knepley   Input Parameters:
1627dce8aebaSBarry Smith + ds - The `PetscDS`
1628194d53e6SMatthew G. Knepley . f  - The test field number
1629194d53e6SMatthew G. Knepley - g  - The field number
1630194d53e6SMatthew G. Knepley 
1631194d53e6SMatthew G. Knepley   Output Parameters:
1632194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1633194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1634194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1635194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1636194d53e6SMatthew G. Knepley 
1637a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1638ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1639194d53e6SMatthew G. Knepley . Nf           - the number of fields
1640a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1641b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1642b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1643194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1644194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1645194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1646b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1647b44f4de4SBarry Smith . aOff_x       - the offset into a_`x`[] for each auxiliary field
1648194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1649194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1650194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1651194d53e6SMatthew G. Knepley . t            - current time
1652b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
1653194d53e6SMatthew G. Knepley . x            - coordinates of the current point
165497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
165597b6e6e8SMatthew G. Knepley . constants    - constant parameters
1656194d53e6SMatthew G. Knepley - g0           - output values at the current point
1657194d53e6SMatthew G. Knepley 
1658194d53e6SMatthew G. Knepley   Level: intermediate
1659194d53e6SMatthew G. Knepley 
1660dce8aebaSBarry Smith   Note:
1661a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
166260225df5SJacob Faibussowitsch 
1663a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16641d27aa22SBarry Smith 
16651d27aa22SBarry Smith   $$
16661702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
16671702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
16681d27aa22SBarry Smith   $$
1669dce8aebaSBarry Smith 
1670dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1671194d53e6SMatthew G. Knepley @*/
1672a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1673d71ae5a4SJacob Faibussowitsch {
16746528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16756528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16766528b96dSMatthew G. Knepley 
16772764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
167963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
168063a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
16819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16826528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16836528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16846528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16856528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16872764a2aaSMatthew G. Knepley }
16882764a2aaSMatthew G. Knepley 
1689194d53e6SMatthew G. Knepley /*@C
1690194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1691194d53e6SMatthew G. Knepley 
169220f4b53cSBarry Smith   Not Collective
1693194d53e6SMatthew G. Knepley 
1694194d53e6SMatthew G. Knepley   Input Parameters:
1695dce8aebaSBarry Smith + ds - The `PetscDS`
1696194d53e6SMatthew G. Knepley . f  - The test field number
1697194d53e6SMatthew G. Knepley . g  - The field number
1698194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1699194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1700194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1701194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1702194d53e6SMatthew G. Knepley 
1703a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1704ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1705194d53e6SMatthew G. Knepley . Nf           - the number of fields
1706a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1707b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1708b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1709194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1710194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1711194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1712b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1713b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1714194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1715194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1716194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1717194d53e6SMatthew G. Knepley . t            - current time
1718b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
1719194d53e6SMatthew G. Knepley . x            - coordinates of the current point
172097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
172197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1722194d53e6SMatthew G. Knepley - g0           - output values at the current point
1723194d53e6SMatthew G. Knepley 
1724194d53e6SMatthew G. Knepley   Level: intermediate
1725194d53e6SMatthew G. Knepley 
1726dce8aebaSBarry Smith   Note:
1727a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
172860225df5SJacob Faibussowitsch 
1729a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
17301702e181SMatthew Knepley 
17311702e181SMatthew Knepley   $$
17321702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
17331702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
17341702e181SMatthew Knepley   $$
1735dce8aebaSBarry Smith 
1736dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1737194d53e6SMatthew G. Knepley @*/
1738a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1739d71ae5a4SJacob Faibussowitsch {
17402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17416528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17422764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17432764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17442764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17452764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
174663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
174763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17489566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17502764a2aaSMatthew G. Knepley }
17512764a2aaSMatthew G. Knepley 
1752cc4c1da9SBarry Smith /*@
1753dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
175455c1f793SMatthew G. Knepley 
175520f4b53cSBarry Smith   Not Collective
175655c1f793SMatthew G. Knepley 
175755c1f793SMatthew G. Knepley   Input Parameters:
1758dce8aebaSBarry Smith + prob      - The `PetscDS`
175955c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
176055c1f793SMatthew G. Knepley 
176155c1f793SMatthew G. Knepley   Level: intermediate
176255c1f793SMatthew G. Knepley 
1763cc4c1da9SBarry Smith   Developer Note:
1764cc4c1da9SBarry Smith   Should be called `PetscDSSetUseJacobianPreconditioner()`
1765cc4c1da9SBarry Smith 
1766dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
176755c1f793SMatthew G. Knepley @*/
1768d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1769d71ae5a4SJacob Faibussowitsch {
177055c1f793SMatthew G. Knepley   PetscFunctionBegin;
177155c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
177255c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
177455c1f793SMatthew G. Knepley }
177555c1f793SMatthew G. Knepley 
1776cc4c1da9SBarry Smith /*@
17777addb90fSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian matrix for constructing a preconditioner has been set
1778475e0ac9SMatthew G. Knepley 
177920f4b53cSBarry Smith   Not Collective
1780475e0ac9SMatthew G. Knepley 
1781475e0ac9SMatthew G. Knepley   Input Parameter:
178260225df5SJacob Faibussowitsch . ds - The `PetscDS`
1783475e0ac9SMatthew G. Knepley 
1784475e0ac9SMatthew G. Knepley   Output Parameter:
17857addb90fSBarry Smith . hasJacPre - the flag
1786475e0ac9SMatthew G. Knepley 
1787475e0ac9SMatthew G. Knepley   Level: intermediate
1788475e0ac9SMatthew G. Knepley 
1789dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1790475e0ac9SMatthew G. Knepley @*/
1791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1792d71ae5a4SJacob Faibussowitsch {
1793475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17946528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1795475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17963ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1799475e0ac9SMatthew G. Knepley }
1800475e0ac9SMatthew G. Knepley 
1801475e0ac9SMatthew G. Knepley /*@C
18027addb90fSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian matrx function for constructing a preconditioner for given test and basis field.
18037addb90fSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1804475e0ac9SMatthew G. Knepley 
180520f4b53cSBarry Smith   Not Collective
1806475e0ac9SMatthew G. Knepley 
1807475e0ac9SMatthew G. Knepley   Input Parameters:
1808dce8aebaSBarry Smith + ds - The `PetscDS`
1809475e0ac9SMatthew G. Knepley . f  - The test field number
1810475e0ac9SMatthew G. Knepley - g  - The field number
1811475e0ac9SMatthew G. Knepley 
1812475e0ac9SMatthew G. Knepley   Output Parameters:
1813475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1814475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1815475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1816475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1817475e0ac9SMatthew G. Knepley 
1818a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1819ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1820475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1821a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1822b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1823b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1824475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1825475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1826475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1827b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1828b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1829475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1830475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1831475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1832475e0ac9SMatthew G. Knepley . t            - current time
1833b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $ dF/dU_t $
1834475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
183597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
183697b6e6e8SMatthew G. Knepley . constants    - constant parameters
1837475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1838475e0ac9SMatthew G. Knepley 
1839475e0ac9SMatthew G. Knepley   Level: intermediate
1840475e0ac9SMatthew G. Knepley 
1841dce8aebaSBarry Smith   Note:
1842a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1843a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
18441702e181SMatthew Knepley 
18451702e181SMatthew Knepley   $$
18461702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
18471702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
18481702e181SMatthew Knepley   $$
1849dce8aebaSBarry Smith 
1850dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1851475e0ac9SMatthew G. Knepley @*/
1852a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1853d71ae5a4SJacob Faibussowitsch {
18546528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18556528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18566528b96dSMatthew G. Knepley 
1857475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18586528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
185963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
186063a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
18619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18626528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18636528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18646528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18656528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1867475e0ac9SMatthew G. Knepley }
1868475e0ac9SMatthew G. Knepley 
1869475e0ac9SMatthew G. Knepley /*@C
1870dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1871dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1872475e0ac9SMatthew G. Knepley 
187320f4b53cSBarry Smith   Not Collective
1874475e0ac9SMatthew G. Knepley 
1875475e0ac9SMatthew G. Knepley   Input Parameters:
1876dce8aebaSBarry Smith + ds - The `PetscDS`
1877475e0ac9SMatthew G. Knepley . f  - The test field number
1878475e0ac9SMatthew G. Knepley . g  - The field number
1879475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1880475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1881475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1882475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1883475e0ac9SMatthew G. Knepley 
1884a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1885ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1886475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1887a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1888b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1889b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1890475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1891475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1892475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1893b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1894b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1895475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1896475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1897475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1898475e0ac9SMatthew G. Knepley . t            - current time
1899b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
1900475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
190197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
190297b6e6e8SMatthew G. Knepley . constants    - constant parameters
1903475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1904475e0ac9SMatthew G. Knepley 
1905475e0ac9SMatthew G. Knepley   Level: intermediate
1906475e0ac9SMatthew G. Knepley 
1907dce8aebaSBarry Smith   Note:
1908a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
190960225df5SJacob Faibussowitsch 
1910a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
19111702e181SMatthew Knepley 
19121702e181SMatthew Knepley   $$
19131702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
19141702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
19151702e181SMatthew Knepley   $$
1916dce8aebaSBarry Smith 
1917dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1918475e0ac9SMatthew G. Knepley @*/
1919a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1920d71ae5a4SJacob Faibussowitsch {
1921475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
19226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1923475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1924475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1925475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1926475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
192763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
192863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1931475e0ac9SMatthew G. Knepley }
1932475e0ac9SMatthew G. Knepley 
1933cc4c1da9SBarry Smith /*@
1934b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1935b7e05686SMatthew G. Knepley 
193620f4b53cSBarry Smith   Not Collective
1937b7e05686SMatthew G. Knepley 
1938b7e05686SMatthew G. Knepley   Input Parameter:
1939dce8aebaSBarry Smith . ds - The `PetscDS`
1940b7e05686SMatthew G. Knepley 
1941b7e05686SMatthew G. Knepley   Output Parameter:
1942b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1943b7e05686SMatthew G. Knepley 
1944b7e05686SMatthew G. Knepley   Level: intermediate
1945b7e05686SMatthew G. Knepley 
1946dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1947b7e05686SMatthew G. Knepley @*/
1948d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1949d71ae5a4SJacob Faibussowitsch {
1950b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19516528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19529566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1954b7e05686SMatthew G. Knepley }
1955b7e05686SMatthew G. Knepley 
1956b7e05686SMatthew G. Knepley /*@C
1957b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1958b7e05686SMatthew G. Knepley 
195920f4b53cSBarry Smith   Not Collective
1960b7e05686SMatthew G. Knepley 
1961b7e05686SMatthew G. Knepley   Input Parameters:
1962dce8aebaSBarry Smith + ds - The `PetscDS`
1963b7e05686SMatthew G. Knepley . f  - The test field number
1964b7e05686SMatthew G. Knepley - g  - The field number
1965b7e05686SMatthew G. Knepley 
1966b7e05686SMatthew G. Knepley   Output Parameters:
1967b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1968b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1969b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1970b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1971b7e05686SMatthew G. Knepley 
1972a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1973ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
1974b7e05686SMatthew G. Knepley . Nf           - the number of fields
1975a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1976b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
1977b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
1978b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1979b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1980b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1981b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
1982b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
1983b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1984b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1985b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1986b7e05686SMatthew G. Knepley . t            - current time
1987b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
1988b7e05686SMatthew G. Knepley . x            - coordinates of the current point
198997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
199097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1991b7e05686SMatthew G. Knepley - g0           - output values at the current point
1992b7e05686SMatthew G. Knepley 
1993b7e05686SMatthew G. Knepley   Level: intermediate
1994b7e05686SMatthew G. Knepley 
1995dce8aebaSBarry Smith   Note:
1996a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
199760225df5SJacob Faibussowitsch 
1998a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
19991702e181SMatthew Knepley 
20001702e181SMatthew Knepley   $$
20011702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
20021702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
20031702e181SMatthew Knepley   $$
2004dce8aebaSBarry Smith 
2005dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
2006b7e05686SMatthew G. Knepley @*/
2007a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2008d71ae5a4SJacob Faibussowitsch {
20096528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
20106528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
20116528b96dSMatthew G. Knepley 
2012b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
201463a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
201563a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
20169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
20176528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
20186528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
20196528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
20206528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
20213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2022b7e05686SMatthew G. Knepley }
2023b7e05686SMatthew G. Knepley 
2024b7e05686SMatthew G. Knepley /*@C
2025b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
2026b7e05686SMatthew G. Knepley 
202720f4b53cSBarry Smith   Not Collective
2028b7e05686SMatthew G. Knepley 
2029b7e05686SMatthew G. Knepley   Input Parameters:
2030dce8aebaSBarry Smith + ds - The `PetscDS`
2031b7e05686SMatthew G. Knepley . f  - The test field number
2032b7e05686SMatthew G. Knepley . g  - The field number
2033b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2034b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2035b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2036b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2037b7e05686SMatthew G. Knepley 
2038a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2039ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
2040b7e05686SMatthew G. Knepley . Nf           - the number of fields
2041a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2042b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2043b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
2044b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2045b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2046b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2047b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2048b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
2049b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2050b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2051b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2052b7e05686SMatthew G. Knepley . t            - current time
2053b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
2054b7e05686SMatthew G. Knepley . x            - coordinates of the current point
205597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
205697b6e6e8SMatthew G. Knepley . constants    - constant parameters
2057b7e05686SMatthew G. Knepley - g0           - output values at the current point
2058b7e05686SMatthew G. Knepley 
2059b7e05686SMatthew G. Knepley   Level: intermediate
2060b7e05686SMatthew G. Knepley 
2061dce8aebaSBarry Smith   Note:
2062a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
206360225df5SJacob Faibussowitsch 
2064a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
20651702e181SMatthew Knepley 
20661702e181SMatthew Knepley   $$
20671702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
20681702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
20691702e181SMatthew Knepley   $$
2070dce8aebaSBarry Smith 
2071dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2072b7e05686SMatthew G. Knepley @*/
2073a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2074d71ae5a4SJacob Faibussowitsch {
2075b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2077b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2078b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2079b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2080b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
208163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
208263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2085b7e05686SMatthew G. Knepley }
2086b7e05686SMatthew G. Knepley 
20870c2f2876SMatthew G. Knepley /*@C
20880c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20890c2f2876SMatthew G. Knepley 
209020f4b53cSBarry Smith   Not Collective
20910c2f2876SMatthew G. Knepley 
20924165533cSJose E. Roman   Input Parameters:
2093dce8aebaSBarry Smith + ds - The `PetscDS` object
20940c2f2876SMatthew G. Knepley - f  - The field number
20950c2f2876SMatthew G. Knepley 
20964165533cSJose E. Roman   Output Parameter:
20970c2f2876SMatthew G. Knepley . r - Riemann solver
20980c2f2876SMatthew G. Knepley 
209920f4b53cSBarry Smith   Calling sequence of `r`:
2100ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
21015db36cf9SMatthew G. Knepley . Nf           - The number of fields
21025db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21030c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21040c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21050c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21060c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
210797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
210897b6e6e8SMatthew G. Knepley . constants    - constant parameters
21090c2f2876SMatthew G. Knepley - ctx          - optional user context
21100c2f2876SMatthew G. Knepley 
21110c2f2876SMatthew G. Knepley   Level: intermediate
21120c2f2876SMatthew G. Knepley 
2113dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
21140c2f2876SMatthew G. Knepley @*/
2115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f, void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2116d71ae5a4SJacob Faibussowitsch {
21176528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
21186528b96dSMatthew G. Knepley   PetscInt          n;
21196528b96dSMatthew G. Knepley 
21200c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21224f572ea9SToby Isaac   PetscAssertPointer(r, 3);
212363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
21249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
21256528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
21263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21270c2f2876SMatthew G. Knepley }
21280c2f2876SMatthew G. Knepley 
21290c2f2876SMatthew G. Knepley /*@C
21300c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
21310c2f2876SMatthew G. Knepley 
213220f4b53cSBarry Smith   Not Collective
21330c2f2876SMatthew G. Knepley 
21344165533cSJose E. Roman   Input Parameters:
2135dce8aebaSBarry Smith + ds - The `PetscDS` object
21360c2f2876SMatthew G. Knepley . f  - The field number
21370c2f2876SMatthew G. Knepley - r  - Riemann solver
21380c2f2876SMatthew G. Knepley 
213920f4b53cSBarry Smith   Calling sequence of `r`:
2140ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
21415db36cf9SMatthew G. Knepley . Nf           - The number of fields
21425db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21430c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21440c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21450c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21460c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
214797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
214897b6e6e8SMatthew G. Knepley . constants    - constant parameters
21490c2f2876SMatthew G. Knepley - ctx          - optional user context
21500c2f2876SMatthew G. Knepley 
21510c2f2876SMatthew G. Knepley   Level: intermediate
21520c2f2876SMatthew G. Knepley 
2153dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21540c2f2876SMatthew G. Knepley @*/
2155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f, void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2156d71ae5a4SJacob Faibussowitsch {
21570c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21586528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2159de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
216063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21630c2f2876SMatthew G. Knepley }
21640c2f2876SMatthew G. Knepley 
216532d2bbc9SMatthew G. Knepley /*@C
216632d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
216732d2bbc9SMatthew G. Knepley 
216820f4b53cSBarry Smith   Not Collective
216932d2bbc9SMatthew G. Knepley 
217032d2bbc9SMatthew G. Knepley   Input Parameters:
2171dce8aebaSBarry Smith + ds - The `PetscDS`
217232d2bbc9SMatthew G. Knepley - f  - The field number
217332d2bbc9SMatthew G. Knepley 
2174f899ff85SJose E. Roman   Output Parameter:
2175a2b725a8SWilliam Gropp . update - update function
217632d2bbc9SMatthew G. Knepley 
217720f4b53cSBarry Smith   Calling sequence of `update`:
2178ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
217932d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2180a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2181b44f4de4SBarry Smith . uOff         - the offset into `u`[] and` u_t`[] for each field
2182b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
218332d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
218432d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
218532d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2186b44f4de4SBarry Smith . aOff         - the offset into `a[]` and a_t[] for each auxiliary field
2187b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
218832d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
218932d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
219032d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
219132d2bbc9SMatthew G. Knepley . t            - current time
219232d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2193a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2194a4e35b19SJacob Faibussowitsch . constants    - constant parameters
219532d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
219632d2bbc9SMatthew G. Knepley 
219732d2bbc9SMatthew G. Knepley   Level: intermediate
219832d2bbc9SMatthew G. Knepley 
2199dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
220032d2bbc9SMatthew G. Knepley @*/
2201d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f, void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2202d71ae5a4SJacob Faibussowitsch {
220332d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
220563a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
22069371c9d4SSatish Balay   if (update) {
22074f572ea9SToby Isaac     PetscAssertPointer(update, 3);
22089371c9d4SSatish Balay     *update = ds->update[f];
22099371c9d4SSatish Balay   }
22103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
221132d2bbc9SMatthew G. Knepley }
221232d2bbc9SMatthew G. Knepley 
221332d2bbc9SMatthew G. Knepley /*@C
22143fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
221532d2bbc9SMatthew G. Knepley 
221620f4b53cSBarry Smith   Not Collective
221732d2bbc9SMatthew G. Knepley 
221832d2bbc9SMatthew G. Knepley   Input Parameters:
2219dce8aebaSBarry Smith + ds     - The `PetscDS`
222032d2bbc9SMatthew G. Knepley . f      - The field number
222132d2bbc9SMatthew G. Knepley - update - update function
222232d2bbc9SMatthew G. Knepley 
222320f4b53cSBarry Smith   Calling sequence of `update`:
2224ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
222532d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2226a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2227b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2228b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
222932d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
223032d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
223132d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2232b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2233b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
223432d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
223532d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
223632d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
223732d2bbc9SMatthew G. Knepley . t            - current time
223832d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2239a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2240a4e35b19SJacob Faibussowitsch . constants    - constant parameters
224132d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
224232d2bbc9SMatthew G. Knepley 
224332d2bbc9SMatthew G. Knepley   Level: intermediate
224432d2bbc9SMatthew G. Knepley 
2245dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
224632d2bbc9SMatthew G. Knepley @*/
2247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f, void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2248d71ae5a4SJacob Faibussowitsch {
224932d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22506528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225132d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
225263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22539566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22546528b96dSMatthew G. Knepley   ds->update[f] = update;
22553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
225632d2bbc9SMatthew G. Knepley }
225732d2bbc9SMatthew G. Knepley 
2258d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2259d71ae5a4SJacob Faibussowitsch {
22600c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22616528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
226263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
22634f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22643ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22660c2f2876SMatthew G. Knepley }
22670c2f2876SMatthew G. Knepley 
2268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2269d71ae5a4SJacob Faibussowitsch {
22700c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22716528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
227263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22739566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22746528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22760c2f2876SMatthew G. Knepley }
22770c2f2876SMatthew G. Knepley 
2278194d53e6SMatthew G. Knepley /*@C
2279194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2280194d53e6SMatthew G. Knepley 
228120f4b53cSBarry Smith   Not Collective
2282194d53e6SMatthew G. Knepley 
2283194d53e6SMatthew G. Knepley   Input Parameters:
22846528b96dSMatthew G. Knepley + ds - The PetscDS
2285194d53e6SMatthew G. Knepley - f  - The test field number
2286194d53e6SMatthew G. Knepley 
2287194d53e6SMatthew G. Knepley   Output Parameters:
2288194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2289194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2290194d53e6SMatthew G. Knepley 
2291a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2292ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
2293194d53e6SMatthew G. Knepley . Nf           - the number of fields
2294a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2295b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2296b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
2297194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2298194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2299194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2300b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2301b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
2302194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2303194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2304194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2305194d53e6SMatthew G. Knepley . t            - current time
2306194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2307194d53e6SMatthew G. Knepley . n            - unit normal at the current point
230897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
230997b6e6e8SMatthew G. Knepley . constants    - constant parameters
2310194d53e6SMatthew G. Knepley - f0           - output values at the current point
2311194d53e6SMatthew G. Knepley 
2312194d53e6SMatthew G. Knepley   Level: intermediate
2313194d53e6SMatthew G. Knepley 
2314dce8aebaSBarry Smith   Note:
2315a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
231660225df5SJacob Faibussowitsch 
2317a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
23181702e181SMatthew Knepley 
23191702e181SMatthew Knepley   $$
2320dce8aebaSBarry Smith   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n
23211702e181SMatthew Knepley   $$
2322dce8aebaSBarry Smith 
2323dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2324194d53e6SMatthew G. Knepley @*/
2325a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2326d71ae5a4SJacob Faibussowitsch {
23276528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
23286528b96dSMatthew G. Knepley   PetscInt          n0, n1;
23296528b96dSMatthew G. Knepley 
23302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
233263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
23339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
23346528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
23356528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
23363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23372764a2aaSMatthew G. Knepley }
23382764a2aaSMatthew G. Knepley 
2339194d53e6SMatthew G. Knepley /*@C
2340194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2341194d53e6SMatthew G. Knepley 
234220f4b53cSBarry Smith   Not Collective
2343194d53e6SMatthew G. Knepley 
2344194d53e6SMatthew G. Knepley   Input Parameters:
2345dce8aebaSBarry Smith + ds - The `PetscDS`
2346194d53e6SMatthew G. Knepley . f  - The test field number
2347194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2348194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2349194d53e6SMatthew G. Knepley 
2350a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2351ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
2352194d53e6SMatthew G. Knepley . Nf           - the number of fields
2353a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2354b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2355b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
2356194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2357194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2358194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2359b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2360b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
2361194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2362194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2363194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2364194d53e6SMatthew G. Knepley . t            - current time
2365194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2366194d53e6SMatthew G. Knepley . n            - unit normal at the current point
236797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
236897b6e6e8SMatthew G. Knepley . constants    - constant parameters
2369194d53e6SMatthew G. Knepley - f0           - output values at the current point
2370194d53e6SMatthew G. Knepley 
2371194d53e6SMatthew G. Knepley   Level: intermediate
2372194d53e6SMatthew G. Knepley 
2373dce8aebaSBarry Smith   Note:
2374a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
237560225df5SJacob Faibussowitsch 
2376a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
23771702e181SMatthew Knepley 
23781702e181SMatthew Knepley   $$
2379dce8aebaSBarry Smith   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n
23801702e181SMatthew Knepley   $$
2381dce8aebaSBarry Smith 
2382dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2383194d53e6SMatthew G. Knepley @*/
2384a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2385d71ae5a4SJacob Faibussowitsch {
23862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
238863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23912764a2aaSMatthew G. Knepley }
23922764a2aaSMatthew G. Knepley 
239327f02ce8SMatthew G. Knepley /*@
2394dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
239527f02ce8SMatthew G. Knepley 
239620f4b53cSBarry Smith   Not Collective
239727f02ce8SMatthew G. Knepley 
239827f02ce8SMatthew G. Knepley   Input Parameter:
2399dce8aebaSBarry Smith . ds - The `PetscDS`
240027f02ce8SMatthew G. Knepley 
240127f02ce8SMatthew G. Knepley   Output Parameter:
240227f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
240327f02ce8SMatthew G. Knepley 
240427f02ce8SMatthew G. Knepley   Level: intermediate
240527f02ce8SMatthew G. Knepley 
2406dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
240727f02ce8SMatthew G. Knepley @*/
2408d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2409d71ae5a4SJacob Faibussowitsch {
241027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24116528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24124f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
24139566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
24143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
241527f02ce8SMatthew G. Knepley }
241627f02ce8SMatthew G. Knepley 
2417194d53e6SMatthew G. Knepley /*@C
2418194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2419194d53e6SMatthew G. Knepley 
242020f4b53cSBarry Smith   Not Collective
2421194d53e6SMatthew G. Knepley 
2422194d53e6SMatthew G. Knepley   Input Parameters:
2423dce8aebaSBarry Smith + ds - The `PetscDS`
2424194d53e6SMatthew G. Knepley . f  - The test field number
2425194d53e6SMatthew G. Knepley - g  - The field number
2426194d53e6SMatthew G. Knepley 
2427194d53e6SMatthew G. Knepley   Output Parameters:
2428194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2429194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2430194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2431194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2432194d53e6SMatthew G. Knepley 
2433a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2434ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
2435194d53e6SMatthew G. Knepley . Nf           - the number of fields
2436a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2437b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2438b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
2439194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2440194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2441194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2442b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2443b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
2444194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2445194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2446194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2447194d53e6SMatthew G. Knepley . t            - current time
2448b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
2449194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2450194d53e6SMatthew G. Knepley . n            - normal at the current point
245197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
245297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2453194d53e6SMatthew G. Knepley - g0           - output values at the current point
2454194d53e6SMatthew G. Knepley 
2455194d53e6SMatthew G. Knepley   Level: intermediate
2456194d53e6SMatthew G. Knepley 
2457dce8aebaSBarry Smith   Note:
2458a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
245960225df5SJacob Faibussowitsch 
2460a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
24611702e181SMatthew Knepley 
24621702e181SMatthew Knepley   $$
24631702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
24641702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
24651702e181SMatthew Knepley   $$
2466dce8aebaSBarry Smith 
2467dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2468194d53e6SMatthew G. Knepley @*/
2469a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2470d71ae5a4SJacob Faibussowitsch {
24716528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24726528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24736528b96dSMatthew G. Knepley 
24742764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24756528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
247663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
247763a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
24789566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24796528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24806528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24816528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24826528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24842764a2aaSMatthew G. Knepley }
24852764a2aaSMatthew G. Knepley 
2486194d53e6SMatthew G. Knepley /*@C
2487194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2488194d53e6SMatthew G. Knepley 
248920f4b53cSBarry Smith   Not Collective
2490194d53e6SMatthew G. Knepley 
2491194d53e6SMatthew G. Knepley   Input Parameters:
24926528b96dSMatthew G. Knepley + ds - The PetscDS
2493194d53e6SMatthew G. Knepley . f  - The test field number
2494194d53e6SMatthew G. Knepley . g  - The field number
2495194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2496194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2497194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2498194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2499194d53e6SMatthew G. Knepley 
2500a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2501ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
2502194d53e6SMatthew G. Knepley . Nf           - the number of fields
2503a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2504b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2505b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
2506194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2507194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2508194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2509b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2510b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
2511194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2512194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2513194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2514194d53e6SMatthew G. Knepley . t            - current time
2515b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
2516194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2517194d53e6SMatthew G. Knepley . n            - normal at the current point
251897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
251997b6e6e8SMatthew G. Knepley . constants    - constant parameters
2520194d53e6SMatthew G. Knepley - g0           - output values at the current point
2521194d53e6SMatthew G. Knepley 
2522194d53e6SMatthew G. Knepley   Level: intermediate
2523194d53e6SMatthew G. Knepley 
2524dce8aebaSBarry Smith   Note:
2525a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
252660225df5SJacob Faibussowitsch 
2527a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
25281702e181SMatthew Knepley 
25291702e181SMatthew Knepley   $$
25301702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
25311702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
25321702e181SMatthew Knepley   $$
2533dce8aebaSBarry Smith 
2534dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2535194d53e6SMatthew G. Knepley @*/
2536a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2537d71ae5a4SJacob Faibussowitsch {
25382764a2aaSMatthew G. Knepley   PetscFunctionBegin;
25396528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25402764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
25412764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
25422764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
25432764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
254463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
254563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
25469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
25473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25482764a2aaSMatthew G. Knepley }
25492764a2aaSMatthew G. Knepley 
255027f02ce8SMatthew G. Knepley /*@
255127f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
255227f02ce8SMatthew G. Knepley 
255320f4b53cSBarry Smith   Not Collective
255427f02ce8SMatthew G. Knepley 
255527f02ce8SMatthew G. Knepley   Input Parameter:
2556dce8aebaSBarry Smith . ds - The `PetscDS`
255727f02ce8SMatthew G. Knepley 
255827f02ce8SMatthew G. Knepley   Output Parameter:
255960225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
256027f02ce8SMatthew G. Knepley 
256127f02ce8SMatthew G. Knepley   Level: intermediate
256227f02ce8SMatthew G. Knepley 
2563dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
256427f02ce8SMatthew G. Knepley @*/
2565d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2566d71ae5a4SJacob Faibussowitsch {
256727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25694f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
257227f02ce8SMatthew G. Knepley }
257327f02ce8SMatthew G. Knepley 
257427f02ce8SMatthew G. Knepley /*@C
257527f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
257627f02ce8SMatthew G. Knepley 
257720f4b53cSBarry Smith   Not Collective; No Fortran Support
257827f02ce8SMatthew G. Knepley 
257927f02ce8SMatthew G. Knepley   Input Parameters:
2580dce8aebaSBarry Smith + ds - The `PetscDS`
258127f02ce8SMatthew G. Knepley . f  - The test field number
258227f02ce8SMatthew G. Knepley - g  - The field number
258327f02ce8SMatthew G. Knepley 
258427f02ce8SMatthew G. Knepley   Output Parameters:
258527f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
258627f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
258727f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
258827f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
258927f02ce8SMatthew G. Knepley 
2590a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2591ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
259227f02ce8SMatthew G. Knepley . Nf           - the number of fields
259327f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
2594b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2595b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
259627f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
259727f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
259827f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2599b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2600b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
260127f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
260227f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
260327f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
260427f02ce8SMatthew G. Knepley . t            - current time
2605b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
260627f02ce8SMatthew G. Knepley . x            - coordinates of the current point
260727f02ce8SMatthew G. Knepley . n            - normal at the current point
260827f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
260927f02ce8SMatthew G. Knepley . constants    - constant parameters
261027f02ce8SMatthew G. Knepley - g0           - output values at the current point
261127f02ce8SMatthew G. Knepley 
261227f02ce8SMatthew G. Knepley   Level: intermediate
261327f02ce8SMatthew G. Knepley 
2614dce8aebaSBarry Smith   Note:
2615a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
261660225df5SJacob Faibussowitsch 
2617a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
26181702e181SMatthew Knepley 
26191702e181SMatthew Knepley   $$
26201702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
26211702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
26221702e181SMatthew Knepley   $$
2623dce8aebaSBarry Smith 
2624dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
262527f02ce8SMatthew G. Knepley @*/
2626a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2627d71ae5a4SJacob Faibussowitsch {
26286528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
26296528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
26306528b96dSMatthew G. Knepley 
263127f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
263363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
263463a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
26359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
26366528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
26376528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
26386528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
26396528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
26403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264127f02ce8SMatthew G. Knepley }
264227f02ce8SMatthew G. Knepley 
264327f02ce8SMatthew G. Knepley /*@C
264427f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
264527f02ce8SMatthew G. Knepley 
264620f4b53cSBarry Smith   Not Collective; No Fortran Support
264727f02ce8SMatthew G. Knepley 
264827f02ce8SMatthew G. Knepley   Input Parameters:
2649dce8aebaSBarry Smith + ds - The `PetscDS`
265027f02ce8SMatthew G. Knepley . f  - The test field number
265127f02ce8SMatthew G. Knepley . g  - The field number
265227f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
265327f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
265427f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
265527f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
265627f02ce8SMatthew G. Knepley 
2657a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
2658ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
265927f02ce8SMatthew G. Knepley . Nf           - the number of fields
266027f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
2661b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
2662b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
266327f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
266427f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
266527f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2666b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
2667b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
266827f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
266927f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
267027f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
267127f02ce8SMatthew G. Knepley . t            - current time
2672b44f4de4SBarry Smith . u_tShift     - the multiplier `a` for $dF/dU_t$
267327f02ce8SMatthew G. Knepley . x            - coordinates of the current point
267427f02ce8SMatthew G. Knepley . n            - normal at the current point
267527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
267627f02ce8SMatthew G. Knepley . constants    - constant parameters
267727f02ce8SMatthew G. Knepley - g0           - output values at the current point
267827f02ce8SMatthew G. Knepley 
267927f02ce8SMatthew G. Knepley   Level: intermediate
268027f02ce8SMatthew G. Knepley 
2681dce8aebaSBarry Smith   Note:
2682a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
268360225df5SJacob Faibussowitsch 
2684a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
26851702e181SMatthew Knepley 
26861702e181SMatthew Knepley   $$
26871702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
26881702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
26891702e181SMatthew Knepley   $$
2690dce8aebaSBarry Smith 
2691dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
269227f02ce8SMatthew G. Knepley @*/
2693a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2694d71ae5a4SJacob Faibussowitsch {
269527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
269727f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
269827f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
269927f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
270027f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
270163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
270263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
27039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
27043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
270527f02ce8SMatthew G. Knepley }
270627f02ce8SMatthew G. Knepley 
27070d3e9b51SMatthew G. Knepley /*@C
2708c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2709c371a6d1SMatthew G. Knepley 
271020f4b53cSBarry Smith   Not Collective
2711c371a6d1SMatthew G. Knepley 
2712c371a6d1SMatthew G. Knepley   Input Parameters:
2713c371a6d1SMatthew G. Knepley + prob - The PetscDS
2714c371a6d1SMatthew G. Knepley - f    - The test field number
2715c371a6d1SMatthew G. Knepley 
2716d8d19677SJose E. Roman   Output Parameters:
2717a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2718a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2719c371a6d1SMatthew G. Knepley 
272020f4b53cSBarry Smith   Calling sequence of `exactSol`:
2721ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2722c371a6d1SMatthew G. Knepley . t   - current time
2723c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2724c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2725a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2726c371a6d1SMatthew G. Knepley - ctx - a user context
2727c371a6d1SMatthew G. Knepley 
2728c371a6d1SMatthew G. Knepley   Level: intermediate
2729c371a6d1SMatthew G. Knepley 
2730dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2731c371a6d1SMatthew G. Knepley @*/
2732d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2733d71ae5a4SJacob Faibussowitsch {
2734c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2735c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
273663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
27379371c9d4SSatish Balay   if (sol) {
27384f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27399371c9d4SSatish Balay     *sol = prob->exactSol[f];
27409371c9d4SSatish Balay   }
27419371c9d4SSatish Balay   if (ctx) {
27424f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27439371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
27449371c9d4SSatish Balay   }
27453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2746c371a6d1SMatthew G. Knepley }
2747c371a6d1SMatthew G. Knepley 
2748c371a6d1SMatthew G. Knepley /*@C
2749578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2750c371a6d1SMatthew G. Knepley 
275120f4b53cSBarry Smith   Not Collective
2752c371a6d1SMatthew G. Knepley 
2753c371a6d1SMatthew G. Knepley   Input Parameters:
2754dce8aebaSBarry Smith + prob - The `PetscDS`
2755c371a6d1SMatthew G. Knepley . f    - The test field number
275695cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
275720f4b53cSBarry Smith - ctx  - solution context or `NULL`
2758c371a6d1SMatthew G. Knepley 
275920f4b53cSBarry Smith   Calling sequence of `sol`:
2760ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2761c371a6d1SMatthew G. Knepley . t   - current time
2762c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2763c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2764c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2765c371a6d1SMatthew G. Knepley - ctx - a user context
2766c371a6d1SMatthew G. Knepley 
2767c371a6d1SMatthew G. Knepley   Level: intermediate
2768c371a6d1SMatthew G. Knepley 
2769dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2770c371a6d1SMatthew G. Knepley @*/
2771d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2772d71ae5a4SJacob Faibussowitsch {
2773c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2774c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
277563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27769566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27779371c9d4SSatish Balay   if (sol) {
27789371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27799371c9d4SSatish Balay     prob->exactSol[f] = sol;
27809371c9d4SSatish Balay   }
27819371c9d4SSatish Balay   if (ctx) {
27829371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27839371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27849371c9d4SSatish Balay   }
27853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2786c371a6d1SMatthew G. Knepley }
2787c371a6d1SMatthew G. Knepley 
27885638fd0eSMatthew G. Knepley /*@C
2789f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2790f2cacb80SMatthew G. Knepley 
279120f4b53cSBarry Smith   Not Collective
2792f2cacb80SMatthew G. Knepley 
2793f2cacb80SMatthew G. Knepley   Input Parameters:
2794dce8aebaSBarry Smith + prob - The `PetscDS`
2795f2cacb80SMatthew G. Knepley - f    - The test field number
2796f2cacb80SMatthew G. Knepley 
2797d8d19677SJose E. Roman   Output Parameters:
2798a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2799a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2800f2cacb80SMatthew G. Knepley 
280120f4b53cSBarry Smith   Calling sequence of `exactSol`:
2802ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2803f2cacb80SMatthew G. Knepley . t   - current time
2804f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2805f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2806a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2807f2cacb80SMatthew G. Knepley - ctx - a user context
2808f2cacb80SMatthew G. Knepley 
2809f2cacb80SMatthew G. Knepley   Level: intermediate
2810f2cacb80SMatthew G. Knepley 
2811dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2812f2cacb80SMatthew G. Knepley @*/
2813d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2814d71ae5a4SJacob Faibussowitsch {
2815f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2816f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
281763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
28189371c9d4SSatish Balay   if (sol) {
28194f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
28209371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
28219371c9d4SSatish Balay   }
28229371c9d4SSatish Balay   if (ctx) {
28234f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
28249371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
28259371c9d4SSatish Balay   }
28263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2827f2cacb80SMatthew G. Knepley }
2828f2cacb80SMatthew G. Knepley 
2829f2cacb80SMatthew G. Knepley /*@C
2830f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2831f2cacb80SMatthew G. Knepley 
283220f4b53cSBarry Smith   Not Collective
2833f2cacb80SMatthew G. Knepley 
2834f2cacb80SMatthew G. Knepley   Input Parameters:
2835dce8aebaSBarry Smith + prob - The `PetscDS`
2836f2cacb80SMatthew G. Knepley . f    - The test field number
2837f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
283820f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2839f2cacb80SMatthew G. Knepley 
284020f4b53cSBarry Smith   Calling sequence of `sol`:
2841ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2842f2cacb80SMatthew G. Knepley . t   - current time
2843f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2844f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2845f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2846f2cacb80SMatthew G. Knepley - ctx - a user context
2847f2cacb80SMatthew G. Knepley 
2848f2cacb80SMatthew G. Knepley   Level: intermediate
2849f2cacb80SMatthew G. Knepley 
2850dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2851f2cacb80SMatthew G. Knepley @*/
2852d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2853d71ae5a4SJacob Faibussowitsch {
2854f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2855f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28579566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28589371c9d4SSatish Balay   if (sol) {
28599371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28609371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28619371c9d4SSatish Balay   }
28629371c9d4SSatish Balay   if (ctx) {
28639371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28649371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28659371c9d4SSatish Balay   }
28663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2867f2cacb80SMatthew G. Knepley }
2868f2cacb80SMatthew G. Knepley 
2869f2cacb80SMatthew G. Knepley /*@C
2870342bd5aaSMatthew G. Knepley   PetscDSGetLowerBound - Get the pointwise lower bound function for a given field
2871342bd5aaSMatthew G. Knepley 
2872342bd5aaSMatthew G. Knepley   Not Collective
2873342bd5aaSMatthew G. Knepley 
2874342bd5aaSMatthew G. Knepley   Input Parameters:
2875342bd5aaSMatthew G. Knepley + ds - The PetscDS
2876342bd5aaSMatthew G. Knepley - f  - The field number
2877342bd5aaSMatthew G. Knepley 
2878342bd5aaSMatthew G. Knepley   Output Parameters:
2879342bd5aaSMatthew G. Knepley + lb  - lower bound for the field
2880342bd5aaSMatthew G. Knepley - ctx - lower bound context
2881342bd5aaSMatthew G. Knepley 
2882342bd5aaSMatthew G. Knepley   Calling sequence of `lb`:
2883ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2884342bd5aaSMatthew G. Knepley . t   - current time
2885342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2886342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2887342bd5aaSMatthew G. Knepley . u   - the lower bound evaluated at the current point
2888342bd5aaSMatthew G. Knepley - ctx - a user context
2889342bd5aaSMatthew G. Knepley 
2890342bd5aaSMatthew G. Knepley   Level: intermediate
2891342bd5aaSMatthew G. Knepley 
2892342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2893342bd5aaSMatthew G. Knepley @*/
2894342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSGetLowerBound(PetscDS ds, PetscInt f, PetscErrorCode (**lb)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2895342bd5aaSMatthew G. Knepley {
2896342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2897342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2898342bd5aaSMatthew G. Knepley   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
2899342bd5aaSMatthew G. Knepley   if (lb) {
2900342bd5aaSMatthew G. Knepley     PetscAssertPointer(lb, 3);
2901342bd5aaSMatthew G. Knepley     *lb = ds->lowerBound[f];
2902342bd5aaSMatthew G. Knepley   }
2903342bd5aaSMatthew G. Knepley   if (ctx) {
2904342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2905342bd5aaSMatthew G. Knepley     *ctx = ds->lowerCtx[f];
2906342bd5aaSMatthew G. Knepley   }
2907342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2908342bd5aaSMatthew G. Knepley }
2909342bd5aaSMatthew G. Knepley 
2910342bd5aaSMatthew G. Knepley /*@C
2911342bd5aaSMatthew G. Knepley   PetscDSSetLowerBound - Set the pointwise lower bound function for a given field
2912342bd5aaSMatthew G. Knepley 
2913342bd5aaSMatthew G. Knepley   Not Collective
2914342bd5aaSMatthew G. Knepley 
2915342bd5aaSMatthew G. Knepley   Input Parameters:
2916342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2917342bd5aaSMatthew G. Knepley . f   - The field number
2918342bd5aaSMatthew G. Knepley . lb  - solution function for the test fields
2919342bd5aaSMatthew G. Knepley - ctx - solution context or `NULL`
2920342bd5aaSMatthew G. Knepley 
2921342bd5aaSMatthew G. Knepley   Calling sequence of `lb`:
2922ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2923342bd5aaSMatthew G. Knepley . t   - current time
2924342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2925342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2926342bd5aaSMatthew G. Knepley . u   - the lower bound evaluated at the current point
2927342bd5aaSMatthew G. Knepley - ctx - a user context
2928342bd5aaSMatthew G. Knepley 
2929342bd5aaSMatthew G. Knepley   Level: intermediate
2930342bd5aaSMatthew G. Knepley 
2931342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2932342bd5aaSMatthew G. Knepley @*/
2933342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSSetLowerBound(PetscDS ds, PetscInt f, PetscErrorCode (*lb)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2934342bd5aaSMatthew G. Knepley {
2935342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2936342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2937342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
2938342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
2939342bd5aaSMatthew G. Knepley   if (lb) {
2940342bd5aaSMatthew G. Knepley     PetscValidFunction(lb, 3);
2941342bd5aaSMatthew G. Knepley     ds->lowerBound[f] = lb;
2942342bd5aaSMatthew G. Knepley   }
2943342bd5aaSMatthew G. Knepley   if (ctx) {
2944342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
2945342bd5aaSMatthew G. Knepley     ds->lowerCtx[f] = ctx;
2946342bd5aaSMatthew G. Knepley   }
2947342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2948342bd5aaSMatthew G. Knepley }
2949342bd5aaSMatthew G. Knepley 
2950342bd5aaSMatthew G. Knepley /*@C
2951342bd5aaSMatthew G. Knepley   PetscDSGetUpperBound - Get the pointwise upper bound function for a given field
2952342bd5aaSMatthew G. Knepley 
2953342bd5aaSMatthew G. Knepley   Not Collective
2954342bd5aaSMatthew G. Knepley 
2955342bd5aaSMatthew G. Knepley   Input Parameters:
2956342bd5aaSMatthew G. Knepley + ds - The PetscDS
2957342bd5aaSMatthew G. Knepley - f  - The field number
2958342bd5aaSMatthew G. Knepley 
2959342bd5aaSMatthew G. Knepley   Output Parameters:
2960342bd5aaSMatthew G. Knepley + ub  - upper bound for the field
2961342bd5aaSMatthew G. Knepley - ctx - upper bound context
2962342bd5aaSMatthew G. Knepley 
2963342bd5aaSMatthew G. Knepley   Calling sequence of `ub`:
2964ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
2965342bd5aaSMatthew G. Knepley . t   - current time
2966342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2967342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2968342bd5aaSMatthew G. Knepley . u   - the upper bound evaluated at the current point
2969342bd5aaSMatthew G. Knepley - ctx - a user context
2970342bd5aaSMatthew G. Knepley 
2971342bd5aaSMatthew G. Knepley   Level: intermediate
2972342bd5aaSMatthew G. Knepley 
2973342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
2974342bd5aaSMatthew G. Knepley @*/
2975342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSGetUpperBound(PetscDS ds, PetscInt f, PetscErrorCode (**ub)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2976342bd5aaSMatthew G. Knepley {
2977342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2978342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2979342bd5aaSMatthew G. Knepley   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
2980342bd5aaSMatthew G. Knepley   if (ub) {
2981342bd5aaSMatthew G. Knepley     PetscAssertPointer(ub, 3);
2982342bd5aaSMatthew G. Knepley     *ub = ds->upperBound[f];
2983342bd5aaSMatthew G. Knepley   }
2984342bd5aaSMatthew G. Knepley   if (ctx) {
2985342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2986342bd5aaSMatthew G. Knepley     *ctx = ds->upperCtx[f];
2987342bd5aaSMatthew G. Knepley   }
2988342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2989342bd5aaSMatthew G. Knepley }
2990342bd5aaSMatthew G. Knepley 
2991342bd5aaSMatthew G. Knepley /*@C
2992342bd5aaSMatthew G. Knepley   PetscDSSetUpperBound - Set the pointwise upper bound function for a given field
2993342bd5aaSMatthew G. Knepley 
2994342bd5aaSMatthew G. Knepley   Not Collective
2995342bd5aaSMatthew G. Knepley 
2996342bd5aaSMatthew G. Knepley   Input Parameters:
2997342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2998342bd5aaSMatthew G. Knepley . f   - The field number
2999342bd5aaSMatthew G. Knepley . ub  - solution function for the test fields
3000342bd5aaSMatthew G. Knepley - ctx - solution context or `NULL`
3001342bd5aaSMatthew G. Knepley 
3002342bd5aaSMatthew G. Knepley   Calling sequence of `ub`:
3003ac9d17c7SMatthew G. Knepley + dim - the coordinate dimension
3004342bd5aaSMatthew G. Knepley . t   - current time
3005342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
3006342bd5aaSMatthew G. Knepley . Nc  - the number of field components
3007342bd5aaSMatthew G. Knepley . u   - the upper bound evaluated at the current point
3008342bd5aaSMatthew G. Knepley - ctx - a user context
3009342bd5aaSMatthew G. Knepley 
3010342bd5aaSMatthew G. Knepley   Level: intermediate
3011342bd5aaSMatthew G. Knepley 
3012342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
3013342bd5aaSMatthew G. Knepley @*/
3014342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSSetUpperBound(PetscDS ds, PetscInt f, PetscErrorCode (*ub)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
3015342bd5aaSMatthew G. Knepley {
3016342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
3017342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3018342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
3019342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
3020342bd5aaSMatthew G. Knepley   if (ub) {
3021342bd5aaSMatthew G. Knepley     PetscValidFunction(ub, 3);
3022342bd5aaSMatthew G. Knepley     ds->upperBound[f] = ub;
3023342bd5aaSMatthew G. Knepley   }
3024342bd5aaSMatthew G. Knepley   if (ctx) {
3025342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
3026342bd5aaSMatthew G. Knepley     ds->upperCtx[f] = ctx;
3027342bd5aaSMatthew G. Knepley   }
3028342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
3029342bd5aaSMatthew G. Knepley }
3030342bd5aaSMatthew G. Knepley 
3031342bd5aaSMatthew G. Knepley /*@C
303297b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
303397b6e6e8SMatthew G. Knepley 
303420f4b53cSBarry Smith   Not Collective
303597b6e6e8SMatthew G. Knepley 
303697b6e6e8SMatthew G. Knepley   Input Parameter:
3037a102dd69SStefano Zampini . ds - The `PetscDS` object
303897b6e6e8SMatthew G. Knepley 
303997b6e6e8SMatthew G. Knepley   Output Parameters:
3040ce78bad3SBarry Smith + numConstants - The number of constants, or pass in `NULL` if not required
3041ce78bad3SBarry Smith - constants    - The array of constants, `NULL` if there are none
304297b6e6e8SMatthew G. Knepley 
304397b6e6e8SMatthew G. Knepley   Level: intermediate
304497b6e6e8SMatthew G. Knepley 
3045dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
304697b6e6e8SMatthew G. Knepley @*/
3047ce78bad3SBarry Smith PetscErrorCode PetscDSGetConstants(PetscDS ds, PeOp PetscInt *numConstants, PeOp const PetscScalar *constants[])
3048d71ae5a4SJacob Faibussowitsch {
304997b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
3050a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
30519371c9d4SSatish Balay   if (numConstants) {
30524f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
3053a102dd69SStefano Zampini     *numConstants = ds->numConstants;
30549371c9d4SSatish Balay   }
30559371c9d4SSatish Balay   if (constants) {
30564f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
3057a102dd69SStefano Zampini     *constants = ds->constants;
30589371c9d4SSatish Balay   }
30593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
306097b6e6e8SMatthew G. Knepley }
306197b6e6e8SMatthew G. Knepley 
30620d3e9b51SMatthew G. Knepley /*@C
306397b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
306497b6e6e8SMatthew G. Knepley 
306520f4b53cSBarry Smith   Not Collective
306697b6e6e8SMatthew G. Knepley 
306797b6e6e8SMatthew G. Knepley   Input Parameters:
3068a102dd69SStefano Zampini + ds           - The `PetscDS` object
306997b6e6e8SMatthew G. Knepley . numConstants - The number of constants
3070a3b724e8SBarry Smith - constants    - The array of constants, `NULL` if there are none
307197b6e6e8SMatthew G. Knepley 
307297b6e6e8SMatthew G. Knepley   Level: intermediate
307397b6e6e8SMatthew G. Knepley 
3074dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
307597b6e6e8SMatthew G. Knepley @*/
3076a102dd69SStefano Zampini PetscErrorCode PetscDSSetConstants(PetscDS ds, PetscInt numConstants, PetscScalar constants[])
3077d71ae5a4SJacob Faibussowitsch {
307897b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
3079a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3080a102dd69SStefano Zampini   if (numConstants != ds->numConstants) {
3081a102dd69SStefano Zampini     PetscCall(PetscFree(ds->constants));
3082a102dd69SStefano Zampini     ds->numConstants = numConstants;
3083a102dd69SStefano Zampini     PetscCall(PetscMalloc1(ds->numConstants + ds->numFuncConstants, &ds->constants));
308420be0f5bSMatthew G. Knepley   }
3085a102dd69SStefano Zampini   if (ds->numConstants) {
30864f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
3087a102dd69SStefano Zampini     PetscCall(PetscArraycpy(ds->constants, constants, ds->numConstants));
308897b6e6e8SMatthew G. Knepley   }
30893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309097b6e6e8SMatthew G. Knepley }
309197b6e6e8SMatthew G. Knepley 
3092a102dd69SStefano Zampini /*@C
3093a102dd69SStefano Zampini   PetscDSSetIntegrationParameters - Set the parameters for a particular integration
3094a102dd69SStefano Zampini 
3095a102dd69SStefano Zampini   Not Collective
3096a102dd69SStefano Zampini 
3097a102dd69SStefano Zampini   Input Parameters:
3098a102dd69SStefano Zampini + ds     - The `PetscDS` object
3099a102dd69SStefano Zampini . fieldI - The test field for a given point function, or PETSC_DETERMINE
3100a102dd69SStefano Zampini - fieldJ - The basis field for a given point function, or PETSC_DETERMINE
3101a102dd69SStefano Zampini 
3102a102dd69SStefano Zampini   Level: intermediate
3103a102dd69SStefano Zampini 
3104a102dd69SStefano Zampini .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
3105a102dd69SStefano Zampini @*/
3106a102dd69SStefano Zampini PetscErrorCode PetscDSSetIntegrationParameters(PetscDS ds, PetscInt fieldI, PetscInt fieldJ)
3107a102dd69SStefano Zampini {
3108a102dd69SStefano Zampini   PetscFunctionBegin;
3109a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3110a102dd69SStefano Zampini   ds->constants[ds->numConstants]     = fieldI;
3111a102dd69SStefano Zampini   ds->constants[ds->numConstants + 1] = fieldJ;
3112a102dd69SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
3113a102dd69SStefano Zampini }
3114a102dd69SStefano Zampini 
311587510d7dSMatthew G. Knepley /*@C
311687510d7dSMatthew G. Knepley   PetscDSSetCellParameters - Set the parameters for a particular cell
311787510d7dSMatthew G. Knepley 
311887510d7dSMatthew G. Knepley   Not Collective
311987510d7dSMatthew G. Knepley 
312087510d7dSMatthew G. Knepley   Input Parameters:
312187510d7dSMatthew G. Knepley + ds     - The `PetscDS` object
312287510d7dSMatthew G. Knepley - volume - The cell volume
312387510d7dSMatthew G. Knepley 
312487510d7dSMatthew G. Knepley   Level: intermediate
312587510d7dSMatthew G. Knepley 
312687510d7dSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
312787510d7dSMatthew G. Knepley @*/
312887510d7dSMatthew G. Knepley PetscErrorCode PetscDSSetCellParameters(PetscDS ds, PetscReal volume)
312987510d7dSMatthew G. Knepley {
313087510d7dSMatthew G. Knepley   PetscFunctionBegin;
313187510d7dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
313287510d7dSMatthew G. Knepley   ds->constants[ds->numConstants + 2] = volume;
313387510d7dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
313487510d7dSMatthew G. Knepley }
313587510d7dSMatthew G. Knepley 
31364cd1e086SMatthew G. Knepley /*@
31374cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
31384cd1e086SMatthew G. Knepley 
313920f4b53cSBarry Smith   Not Collective
31404cd1e086SMatthew G. Knepley 
31414cd1e086SMatthew G. Knepley   Input Parameters:
3142dce8aebaSBarry Smith + prob - The `PetscDS` object
31434cd1e086SMatthew G. Knepley - disc - The discretization object
31444cd1e086SMatthew G. Knepley 
31454cd1e086SMatthew G. Knepley   Output Parameter:
31464cd1e086SMatthew G. Knepley . f - The field number
31474cd1e086SMatthew G. Knepley 
31484cd1e086SMatthew G. Knepley   Level: beginner
31494cd1e086SMatthew G. Knepley 
3150dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31514cd1e086SMatthew G. Knepley @*/
3152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
3153d71ae5a4SJacob Faibussowitsch {
31544cd1e086SMatthew G. Knepley   PetscInt g;
31554cd1e086SMatthew G. Knepley 
31564cd1e086SMatthew G. Knepley   PetscFunctionBegin;
31574cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31584f572ea9SToby Isaac   PetscAssertPointer(f, 3);
31594cd1e086SMatthew G. Knepley   *f = -1;
31609371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
31619371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
31629371c9d4SSatish Balay   }
316308401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
31644cd1e086SMatthew G. Knepley   *f = g;
31653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31664cd1e086SMatthew G. Knepley }
31674cd1e086SMatthew G. Knepley 
31684cd1e086SMatthew G. Knepley /*@
31694cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
31704cd1e086SMatthew G. Knepley 
317120f4b53cSBarry Smith   Not Collective
31724cd1e086SMatthew G. Knepley 
31734cd1e086SMatthew G. Knepley   Input Parameters:
3174dce8aebaSBarry Smith + prob - The `PetscDS` object
31754cd1e086SMatthew G. Knepley - f    - The field number
31764cd1e086SMatthew G. Knepley 
31774cd1e086SMatthew G. Knepley   Output Parameter:
31784cd1e086SMatthew G. Knepley . size - The size
31794cd1e086SMatthew G. Knepley 
31804cd1e086SMatthew G. Knepley   Level: beginner
31814cd1e086SMatthew G. Knepley 
3182dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31834cd1e086SMatthew G. Knepley @*/
3184d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
3185d71ae5a4SJacob Faibussowitsch {
31864cd1e086SMatthew G. Knepley   PetscFunctionBegin;
31874cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31884f572ea9SToby Isaac   PetscAssertPointer(size, 3);
318963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
31909566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3191d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
31923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31934cd1e086SMatthew G. Knepley }
31944cd1e086SMatthew G. Knepley 
3195bc4ae4beSMatthew G. Knepley /*@
3196bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
3197bc4ae4beSMatthew G. Knepley 
319820f4b53cSBarry Smith   Not Collective
3199bc4ae4beSMatthew G. Knepley 
3200bc4ae4beSMatthew G. Knepley   Input Parameters:
3201dce8aebaSBarry Smith + prob - The `PetscDS` object
3202bc4ae4beSMatthew G. Knepley - f    - The field number
3203bc4ae4beSMatthew G. Knepley 
3204bc4ae4beSMatthew G. Knepley   Output Parameter:
3205bc4ae4beSMatthew G. Knepley . off - The offset
3206bc4ae4beSMatthew G. Knepley 
3207bc4ae4beSMatthew G. Knepley   Level: beginner
3208bc4ae4beSMatthew G. Knepley 
3209dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3210bc4ae4beSMatthew G. Knepley @*/
3211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
3212d71ae5a4SJacob Faibussowitsch {
32134cd1e086SMatthew G. Knepley   PetscInt size, g;
32142764a2aaSMatthew G. Knepley 
32152764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32162764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32174f572ea9SToby Isaac   PetscAssertPointer(off, 3);
321863a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
32192764a2aaSMatthew G. Knepley   *off = 0;
32202764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
32219566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
32224cd1e086SMatthew G. Knepley     *off += size;
32232764a2aaSMatthew G. Knepley   }
32243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32252764a2aaSMatthew G. Knepley }
32262764a2aaSMatthew G. Knepley 
3227bc4ae4beSMatthew G. Knepley /*@
32285fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
32295fedec97SMatthew G. Knepley 
323020f4b53cSBarry Smith   Not Collective
32315fedec97SMatthew G. Knepley 
32325fedec97SMatthew G. Knepley   Input Parameters:
323360225df5SJacob Faibussowitsch + ds - The `PetscDS` object
32345fedec97SMatthew G. Knepley - f  - The field number
32355fedec97SMatthew G. Knepley 
32365fedec97SMatthew G. Knepley   Output Parameter:
32375fedec97SMatthew G. Knepley . off - The offset
32385fedec97SMatthew G. Knepley 
32395fedec97SMatthew G. Knepley   Level: beginner
32405fedec97SMatthew G. Knepley 
3241dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32425fedec97SMatthew G. Knepley @*/
3243d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
3244d71ae5a4SJacob Faibussowitsch {
32455fedec97SMatthew G. Knepley   PetscInt size, g;
32465fedec97SMatthew G. Knepley 
32475fedec97SMatthew G. Knepley   PetscFunctionBegin;
32485fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32494f572ea9SToby Isaac   PetscAssertPointer(off, 3);
325063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
32515fedec97SMatthew G. Knepley   *off = 0;
32525fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
32535fedec97SMatthew G. Knepley     PetscBool cohesive;
32545fedec97SMatthew G. Knepley 
32559566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
32569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
32575fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
32585fedec97SMatthew G. Knepley   }
32593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32605fedec97SMatthew G. Knepley }
32615fedec97SMatthew G. Knepley 
32625fedec97SMatthew G. Knepley /*@
326347e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3264bc4ae4beSMatthew G. Knepley 
326520f4b53cSBarry Smith   Not Collective
3266bc4ae4beSMatthew G. Knepley 
326747e57110SSander Arens   Input Parameter:
3268dce8aebaSBarry Smith . prob - The `PetscDS` object
3269bc4ae4beSMatthew G. Knepley 
3270bc4ae4beSMatthew G. Knepley   Output Parameter:
327147e57110SSander Arens . dimensions - The number of dimensions
3272bc4ae4beSMatthew G. Knepley 
3273bc4ae4beSMatthew G. Knepley   Level: beginner
3274bc4ae4beSMatthew G. Knepley 
3275dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3276bc4ae4beSMatthew G. Knepley @*/
3277d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3278d71ae5a4SJacob Faibussowitsch {
32792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32802764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32819566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32824f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
328347e57110SSander Arens   *dimensions = prob->Nb;
32843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32856ce16762SMatthew G. Knepley }
328647e57110SSander Arens 
328747e57110SSander Arens /*@
328847e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
328947e57110SSander Arens 
329020f4b53cSBarry Smith   Not Collective
329147e57110SSander Arens 
329247e57110SSander Arens   Input Parameter:
3293dce8aebaSBarry Smith . prob - The `PetscDS` object
329447e57110SSander Arens 
329547e57110SSander Arens   Output Parameter:
329647e57110SSander Arens . components - The number of components
329747e57110SSander Arens 
329847e57110SSander Arens   Level: beginner
329947e57110SSander Arens 
3300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
330147e57110SSander Arens @*/
3302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3303d71ae5a4SJacob Faibussowitsch {
330447e57110SSander Arens   PetscFunctionBegin;
330547e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33069566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33074f572ea9SToby Isaac   PetscAssertPointer(components, 2);
330847e57110SSander Arens   *components = prob->Nc;
33093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33106ce16762SMatthew G. Knepley }
33116ce16762SMatthew G. Knepley 
33126ce16762SMatthew G. Knepley /*@
33136ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
33146ce16762SMatthew G. Knepley 
331520f4b53cSBarry Smith   Not Collective
33166ce16762SMatthew G. Knepley 
33176ce16762SMatthew G. Knepley   Input Parameters:
3318dce8aebaSBarry Smith + prob - The `PetscDS` object
33196ce16762SMatthew G. Knepley - f    - The field number
33206ce16762SMatthew G. Knepley 
33216ce16762SMatthew G. Knepley   Output Parameter:
33226ce16762SMatthew G. Knepley . off - The offset
33236ce16762SMatthew G. Knepley 
33246ce16762SMatthew G. Knepley   Level: beginner
33256ce16762SMatthew G. Knepley 
3326dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
33276ce16762SMatthew G. Knepley @*/
3328d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3329d71ae5a4SJacob Faibussowitsch {
33306ce16762SMatthew G. Knepley   PetscFunctionBegin;
33316ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33324f572ea9SToby Isaac   PetscAssertPointer(off, 3);
333363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
33349566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
333547e57110SSander Arens   *off = prob->off[f];
33363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33372764a2aaSMatthew G. Knepley }
33382764a2aaSMatthew G. Knepley 
3339194d53e6SMatthew G. Knepley /*@
3340194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3341194d53e6SMatthew G. Knepley 
334220f4b53cSBarry Smith   Not Collective
3343194d53e6SMatthew G. Knepley 
3344194d53e6SMatthew G. Knepley   Input Parameter:
3345dce8aebaSBarry Smith . prob - The `PetscDS` object
3346194d53e6SMatthew G. Knepley 
3347194d53e6SMatthew G. Knepley   Output Parameter:
3348194d53e6SMatthew G. Knepley . offsets - The offsets
3349194d53e6SMatthew G. Knepley 
3350194d53e6SMatthew G. Knepley   Level: beginner
3351194d53e6SMatthew G. Knepley 
3352dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3353194d53e6SMatthew G. Knepley @*/
3354d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3355d71ae5a4SJacob Faibussowitsch {
3356194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3357194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33584f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
33599566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3360194d53e6SMatthew G. Knepley   *offsets = prob->off;
33613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3362194d53e6SMatthew G. Knepley }
3363194d53e6SMatthew G. Knepley 
3364194d53e6SMatthew G. Knepley /*@
3365194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3366194d53e6SMatthew G. Knepley 
336720f4b53cSBarry Smith   Not Collective
3368194d53e6SMatthew G. Knepley 
3369194d53e6SMatthew G. Knepley   Input Parameter:
3370dce8aebaSBarry Smith . prob - The `PetscDS` object
3371194d53e6SMatthew G. Knepley 
3372194d53e6SMatthew G. Knepley   Output Parameter:
3373194d53e6SMatthew G. Knepley . offsets - The offsets
3374194d53e6SMatthew G. Knepley 
3375194d53e6SMatthew G. Knepley   Level: beginner
3376194d53e6SMatthew G. Knepley 
3377dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3378194d53e6SMatthew G. Knepley @*/
3379d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3380d71ae5a4SJacob Faibussowitsch {
3381194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3382194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33834f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
33849566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3385194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
33863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3387194d53e6SMatthew G. Knepley }
3388194d53e6SMatthew G. Knepley 
33899ee2af8cSMatthew G. Knepley /*@
33909ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
33919ee2af8cSMatthew G. Knepley 
339220f4b53cSBarry Smith   Not Collective
33939ee2af8cSMatthew G. Knepley 
33949ee2af8cSMatthew G. Knepley   Input Parameters:
3395dce8aebaSBarry Smith + ds - The `PetscDS` object
33969ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
33979ee2af8cSMatthew G. Knepley 
33989ee2af8cSMatthew G. Knepley   Output Parameter:
33999ee2af8cSMatthew G. Knepley . offsets - The offsets
34009ee2af8cSMatthew G. Knepley 
34019ee2af8cSMatthew G. Knepley   Level: beginner
34029ee2af8cSMatthew G. Knepley 
3403dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
34049ee2af8cSMatthew G. Knepley @*/
3405d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3406d71ae5a4SJacob Faibussowitsch {
34079ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
34089ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
34094f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
341028b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
341163a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
34129566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
34139ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
34143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34159ee2af8cSMatthew G. Knepley }
34169ee2af8cSMatthew G. Knepley 
34179ee2af8cSMatthew G. Knepley /*@
34189ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
34199ee2af8cSMatthew G. Knepley 
342020f4b53cSBarry Smith   Not Collective
34219ee2af8cSMatthew G. Knepley 
34229ee2af8cSMatthew G. Knepley   Input Parameters:
3423dce8aebaSBarry Smith + ds - The `PetscDS` object
34249ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
34259ee2af8cSMatthew G. Knepley 
34269ee2af8cSMatthew G. Knepley   Output Parameter:
34279ee2af8cSMatthew G. Knepley . offsets - The offsets
34289ee2af8cSMatthew G. Knepley 
34299ee2af8cSMatthew G. Knepley   Level: beginner
34309ee2af8cSMatthew G. Knepley 
3431dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
34329ee2af8cSMatthew G. Knepley @*/
3433d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3434d71ae5a4SJacob Faibussowitsch {
34359ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
34369ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
34374f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
343828b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
343963a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
34409566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
34419ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
34423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34439ee2af8cSMatthew G. Knepley }
34449ee2af8cSMatthew G. Knepley 
344568c9edb9SMatthew G. Knepley /*@C
344668c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
344768c9edb9SMatthew G. Knepley 
344820f4b53cSBarry Smith   Not Collective
344968c9edb9SMatthew G. Knepley 
345068c9edb9SMatthew G. Knepley   Input Parameter:
3451dce8aebaSBarry Smith . prob - The `PetscDS` object
345268c9edb9SMatthew G. Knepley 
3453ef0bb6c7SMatthew G. Knepley   Output Parameter:
3454ce78bad3SBarry Smith . T - The basis function and derivatives tabulation at quadrature points for each field, see `PetscTabulation` for its details
345568c9edb9SMatthew G. Knepley 
345668c9edb9SMatthew G. Knepley   Level: intermediate
345768c9edb9SMatthew G. Knepley 
3458ce78bad3SBarry Smith   Note:
3459ce78bad3SBarry Smith   The tabulation is only valid so long as the `PetscDS` has not be destroyed. There is no `PetscDSRestoreTabulation()` in C.
3460ce78bad3SBarry Smith 
3461ce78bad3SBarry Smith   Fortran Note:
3462ce78bad3SBarry Smith   Use the declaration
3463ce78bad3SBarry Smith .vb
3464ce78bad3SBarry Smith   PetscTabulation, pointer :: tab(:)
3465ce78bad3SBarry Smith .ve
3466ce78bad3SBarry Smith   and access the values using, for example,
3467ce78bad3SBarry Smith .vb
3468ce78bad3SBarry Smith   tab(i)%ptr%K
3469ce78bad3SBarry Smith   tab(i)%ptr%T(j)%ptr
3470ce78bad3SBarry Smith .ve
3471ce78bad3SBarry Smith   where $ i = 1, 2, ..., Nf $ and $ j = 1, 2, ..., tab(i)%ptr%K+1 $.
3472ce78bad3SBarry Smith 
3473ce78bad3SBarry Smith   Use `PetscDSRestoreTabulation()` to restore the array
3474ce78bad3SBarry Smith 
3475ce78bad3SBarry Smith   Developer Note:
3476ce78bad3SBarry Smith   The Fortran language syntax does not directly support arrays of pointers, the '%ptr' notation allows mimicking their use in Fortran.
3477ce78bad3SBarry Smith 
3478dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
347968c9edb9SMatthew G. Knepley @*/
3480ce78bad3SBarry Smith PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[]) PeNS
3481d71ae5a4SJacob Faibussowitsch {
34822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
34832764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
34844f572ea9SToby Isaac   PetscAssertPointer(T, 2);
34859566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3486ef0bb6c7SMatthew G. Knepley   *T = prob->T;
34873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34882764a2aaSMatthew G. Knepley }
34892764a2aaSMatthew G. Knepley 
349068c9edb9SMatthew G. Knepley /*@C
34914d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
349268c9edb9SMatthew G. Knepley 
349320f4b53cSBarry Smith   Not Collective
349468c9edb9SMatthew G. Knepley 
349568c9edb9SMatthew G. Knepley   Input Parameter:
3496dce8aebaSBarry Smith . prob - The `PetscDS` object
349768c9edb9SMatthew G. Knepley 
3498ef0bb6c7SMatthew G. Knepley   Output Parameter:
3499ce78bad3SBarry Smith . Tf - The basis function and derivative tabulation on each local face at quadrature points for each field
350068c9edb9SMatthew G. Knepley 
350168c9edb9SMatthew G. Knepley   Level: intermediate
350268c9edb9SMatthew G. Knepley 
3503ce78bad3SBarry Smith   Note:
3504ce78bad3SBarry Smith   The tabulation is only valid so long as the `PetscDS` has not be destroyed. There is no `PetscDSRestoreFaceTabulation()` in C.
3505ce78bad3SBarry Smith 
3506dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
350768c9edb9SMatthew G. Knepley @*/
3508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3509d71ae5a4SJacob Faibussowitsch {
35102764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35112764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35124f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
35139566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3514ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
35153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35162764a2aaSMatthew G. Knepley }
35172764a2aaSMatthew G. Knepley 
3518ce78bad3SBarry Smith PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar *u[], PetscScalar *u_t[], PetscScalar *u_x[])
3519d71ae5a4SJacob Faibussowitsch {
35202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35239371c9d4SSatish Balay   if (u) {
35244f572ea9SToby Isaac     PetscAssertPointer(u, 2);
35259371c9d4SSatish Balay     *u = prob->u;
35269371c9d4SSatish Balay   }
35279371c9d4SSatish Balay   if (u_t) {
35284f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
35299371c9d4SSatish Balay     *u_t = prob->u_t;
35309371c9d4SSatish Balay   }
35319371c9d4SSatish Balay   if (u_x) {
35324f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
35339371c9d4SSatish Balay     *u_x = prob->u_x;
35349371c9d4SSatish Balay   }
35353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35362764a2aaSMatthew G. Knepley }
35372764a2aaSMatthew G. Knepley 
3538ce78bad3SBarry Smith PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar *f0[], PetscScalar *f1[], PetscScalar *g0[], PetscScalar *g1[], PetscScalar *g2[], PetscScalar *g3[])
3539d71ae5a4SJacob Faibussowitsch {
35402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35412764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35429566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35439371c9d4SSatish Balay   if (f0) {
35444f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
35459371c9d4SSatish Balay     *f0 = prob->f0;
35469371c9d4SSatish Balay   }
35479371c9d4SSatish Balay   if (f1) {
35484f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
35499371c9d4SSatish Balay     *f1 = prob->f1;
35509371c9d4SSatish Balay   }
35519371c9d4SSatish Balay   if (g0) {
35524f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
35539371c9d4SSatish Balay     *g0 = prob->g0;
35549371c9d4SSatish Balay   }
35559371c9d4SSatish Balay   if (g1) {
35564f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
35579371c9d4SSatish Balay     *g1 = prob->g1;
35589371c9d4SSatish Balay   }
35599371c9d4SSatish Balay   if (g2) {
35604f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
35619371c9d4SSatish Balay     *g2 = prob->g2;
35629371c9d4SSatish Balay   }
35639371c9d4SSatish Balay   if (g3) {
35644f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
35659371c9d4SSatish Balay     *g3 = prob->g3;
35669371c9d4SSatish Balay   }
35673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35682764a2aaSMatthew G. Knepley }
35692764a2aaSMatthew G. Knepley 
3570d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3571d71ae5a4SJacob Faibussowitsch {
35722764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35732764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35749566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35759371c9d4SSatish Balay   if (x) {
35764f572ea9SToby Isaac     PetscAssertPointer(x, 2);
35779371c9d4SSatish Balay     *x = prob->x;
35789371c9d4SSatish Balay   }
35799371c9d4SSatish Balay   if (basisReal) {
35804f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
35819371c9d4SSatish Balay     *basisReal = prob->basisReal;
35829371c9d4SSatish Balay   }
35839371c9d4SSatish Balay   if (basisDerReal) {
35844f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
35859371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
35869371c9d4SSatish Balay   }
35879371c9d4SSatish Balay   if (testReal) {
35884f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
35899371c9d4SSatish Balay     *testReal = prob->testReal;
35909371c9d4SSatish Balay   }
35919371c9d4SSatish Balay   if (testDerReal) {
35924f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
35939371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
35949371c9d4SSatish Balay   }
35953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35962764a2aaSMatthew G. Knepley }
35972764a2aaSMatthew G. Knepley 
359858ebd649SToby Isaac /*@C
3599a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
360058ebd649SToby Isaac 
360120f4b53cSBarry Smith   Collective
3602783e2ec8SMatthew G. Knepley 
360358ebd649SToby Isaac   Input Parameters:
360458ebd649SToby Isaac + ds       - The PetscDS object
3605dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
360658ebd649SToby Isaac . name     - The BC name
360745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3608dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
360945480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
361058ebd649SToby Isaac . field    - The field to constrain
361145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
361258ebd649SToby Isaac . comps    - An array of constrained component numbers
361358ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3614b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3615b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
361658ebd649SToby Isaac 
36172fe279fdSBarry Smith   Output Parameter:
361860225df5SJacob Faibussowitsch . bd - The boundary number
361945480ffeSMatthew G. Knepley 
362058ebd649SToby Isaac   Options Database Keys:
362158ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
362258ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
362358ebd649SToby Isaac 
3624dce8aebaSBarry Smith   Level: developer
3625dce8aebaSBarry Smith 
362656cf3b9cSMatthew G. Knepley   Note:
3627a4e35b19SJacob Faibussowitsch   Both `bcFunc` and `bcFunc_t` will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, then the calling sequence is\:
3628b44f4de4SBarry Smith .vb
3629b44f4de4SBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3630b44f4de4SBarry Smith .ve
363156cf3b9cSMatthew G. Knepley 
3632a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3633dce8aebaSBarry Smith .vb
363420f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3635dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3636dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3637dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3638dce8aebaSBarry Smith .ve
3639ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
364056cf3b9cSMatthew G. Knepley . Nf           - the number of fields
364156cf3b9cSMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
364256cf3b9cSMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
364356cf3b9cSMatthew G. Knepley . u            - each field evaluated at the current point
364456cf3b9cSMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
364556cf3b9cSMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
364656cf3b9cSMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
364756cf3b9cSMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
364856cf3b9cSMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
364956cf3b9cSMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
365056cf3b9cSMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
365156cf3b9cSMatthew G. Knepley . t            - current time
365256cf3b9cSMatthew G. Knepley . x            - coordinates of the current point
365356cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
365456cf3b9cSMatthew G. Knepley . constants    - constant parameters
365556cf3b9cSMatthew G. Knepley - bcval        - output values at the current point
365656cf3b9cSMatthew G. Knepley 
3657a4e35b19SJacob Faibussowitsch   Notes:
3658a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3659a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3660a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3661a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3662a4e35b19SJacob Faibussowitsch 
3663dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
366458ebd649SToby Isaac @*/
3665d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddBoundary(PetscDS ds, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd)
3666d71ae5a4SJacob Faibussowitsch {
366745480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
366845480ffeSMatthew G. Knepley   PetscInt    n    = 0;
366945480ffeSMatthew G. Knepley   const char *lname;
367058ebd649SToby Isaac 
367158ebd649SToby Isaac   PetscFunctionBegin;
367258ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3673783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
36744f572ea9SToby Isaac   PetscAssertPointer(name, 3);
367545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
367645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
367745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
367845480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3679dce9da9cSMatthew G. Knepley   PetscCheck(field >= 0 && field < ds->Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_OUTOFRANGE, "Field %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", field, ds->Nf);
3680d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3681d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3682d57bb9dbSMatthew G. Knepley     PetscInt  c;
3683d57bb9dbSMatthew G. Knepley 
36849566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
368563a3b9bcSJacob Faibussowitsch     PetscCheck(Nc <= fcomps[field], PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_OUTOFRANGE, "Number of constrained components %" PetscInt_FMT " > %" PetscInt_FMT " components for field %" PetscInt_FMT, Nc, fcomps[field], field);
3686d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
36871dca8a05SBarry Smith       PetscCheck(comps[c] >= 0 && comps[c] < fcomps[field], PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_OUTOFRANGE, "Constrained component[%" PetscInt_FMT "] %" PetscInt_FMT " not in [0, %" PetscInt_FMT ") components for field %" PetscInt_FMT, c, comps[c], fcomps[field], field);
3688d57bb9dbSMatthew G. Knepley     }
3689d57bb9dbSMatthew G. Knepley   }
36909566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
36919566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
36929566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
36939566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
36949566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
36959566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
36969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
36979566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
36989566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
36999566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3700f971fd6bSMatthew G. Knepley   b->type   = type;
370145480ffeSMatthew G. Knepley   b->label  = label;
370245480ffeSMatthew G. Knepley   b->Nv     = Nv;
370358ebd649SToby Isaac   b->field  = field;
370445480ffeSMatthew G. Knepley   b->Nc     = Nc;
370558ebd649SToby Isaac   b->func   = bcFunc;
370656cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
370758ebd649SToby Isaac   b->ctx    = ctx;
370845480ffeSMatthew G. Knepley   b->next   = NULL;
370945480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
371045480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
371145480ffeSMatthew G. Knepley   while (head) {
371245480ffeSMatthew G. Knepley     if (!head->next) {
371345480ffeSMatthew G. Knepley       head->next = b;
371445480ffeSMatthew G. Knepley       head       = b;
371545480ffeSMatthew G. Knepley     }
371645480ffeSMatthew G. Knepley     head = head->next;
371745480ffeSMatthew G. Knepley     ++n;
371845480ffeSMatthew G. Knepley   }
37199371c9d4SSatish Balay   if (bd) {
37204f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
37219371c9d4SSatish Balay     *bd = n;
37229371c9d4SSatish Balay   }
37233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
372445480ffeSMatthew G. Knepley }
372545480ffeSMatthew G. Knepley 
3726a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
372745480ffeSMatthew G. Knepley /*@C
3728a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
372945480ffeSMatthew G. Knepley 
373020f4b53cSBarry Smith   Collective
373145480ffeSMatthew G. Knepley 
373245480ffeSMatthew G. Knepley   Input Parameters:
3733dce8aebaSBarry Smith + ds       - The `PetscDS` object
3734dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
373545480ffeSMatthew G. Knepley . name     - The BC name
373646091a0eSPierre Jolivet . lname    - The name of the label defining constrained points
3737dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
373845480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
373945480ffeSMatthew G. Knepley . field    - The field to constrain
374045480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
374145480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
374245480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3743b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3744b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
374545480ffeSMatthew G. Knepley 
37462fe279fdSBarry Smith   Output Parameter:
374760225df5SJacob Faibussowitsch . bd - The boundary number
374845480ffeSMatthew G. Knepley 
374945480ffeSMatthew G. Knepley   Options Database Keys:
375045480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
375145480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
375245480ffeSMatthew G. Knepley 
375320f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3754dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3755dce8aebaSBarry Smith .vb
375620f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3757dce8aebaSBarry Smith .ve
3758dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3759dce8aebaSBarry Smith .vb
376020f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3761dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3762dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3763dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3764dce8aebaSBarry Smith .ve
3765ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
376645480ffeSMatthew G. Knepley . Nf           - the number of fields
3767b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
3768b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
376945480ffeSMatthew G. Knepley . u            - each field evaluated at the current point
377045480ffeSMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
377145480ffeSMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
3772b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
3773b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
377445480ffeSMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
377545480ffeSMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
377645480ffeSMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
377745480ffeSMatthew G. Knepley . t            - current time
377845480ffeSMatthew G. Knepley . x            - coordinates of the current point
377945480ffeSMatthew G. Knepley . numConstants - number of constant parameters
378045480ffeSMatthew G. Knepley . constants    - constant parameters
378145480ffeSMatthew G. Knepley - bcval        - output values at the current point
378245480ffeSMatthew G. Knepley 
378345480ffeSMatthew G. Knepley   Level: developer
378445480ffeSMatthew G. Knepley 
3785a4e35b19SJacob Faibussowitsch   Notes:
3786a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3787a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3788a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3789a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3790a4e35b19SJacob Faibussowitsch 
3791dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3792dce8aebaSBarry Smith 
3793dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
379445480ffeSMatthew G. Knepley @*/
3795d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddBoundaryByName(PetscDS ds, DMBoundaryConditionType type, const char name[], const char lname[], PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd)
3796d71ae5a4SJacob Faibussowitsch {
379745480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
379845480ffeSMatthew G. Knepley   PetscInt   n    = 0;
379945480ffeSMatthew G. Knepley 
380045480ffeSMatthew G. Knepley   PetscFunctionBegin;
380145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
380245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
38034f572ea9SToby Isaac   PetscAssertPointer(name, 3);
38044f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
380545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
380645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
380745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
38089566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
38099566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
38109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
38119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
38129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
38139566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
38149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
38159566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
38169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
381745480ffeSMatthew G. Knepley   b->type   = type;
381845480ffeSMatthew G. Knepley   b->label  = NULL;
381945480ffeSMatthew G. Knepley   b->Nv     = Nv;
382045480ffeSMatthew G. Knepley   b->field  = field;
382145480ffeSMatthew G. Knepley   b->Nc     = Nc;
382245480ffeSMatthew G. Knepley   b->func   = bcFunc;
382345480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
382445480ffeSMatthew G. Knepley   b->ctx    = ctx;
382545480ffeSMatthew G. Knepley   b->next   = NULL;
382645480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
382745480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
382845480ffeSMatthew G. Knepley   while (head) {
382945480ffeSMatthew G. Knepley     if (!head->next) {
383045480ffeSMatthew G. Knepley       head->next = b;
383145480ffeSMatthew G. Knepley       head       = b;
383245480ffeSMatthew G. Knepley     }
383345480ffeSMatthew G. Knepley     head = head->next;
383445480ffeSMatthew G. Knepley     ++n;
383545480ffeSMatthew G. Knepley   }
38369371c9d4SSatish Balay   if (bd) {
38374f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
38389371c9d4SSatish Balay     *bd = n;
38399371c9d4SSatish Balay   }
38403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
384158ebd649SToby Isaac }
384258ebd649SToby Isaac 
3843b67eacb3SMatthew G. Knepley /*@C
3844a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3845b67eacb3SMatthew G. Knepley 
3846b67eacb3SMatthew G. Knepley   Input Parameters:
3847dce8aebaSBarry Smith + ds       - The `PetscDS` object
3848b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3849dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3850b44f4de4SBarry Smith . name     - The boundary condition name
385145480ffeSMatthew G. Knepley . label    - The label defining constrained points
3852dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
385345480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3854b67eacb3SMatthew G. Knepley . field    - The field to constrain
385545480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3856b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3857b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3858b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3859b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
3860b67eacb3SMatthew G. Knepley 
3861b67eacb3SMatthew G. Knepley   Level: developer
3862b67eacb3SMatthew G. Knepley 
3863a4e35b19SJacob Faibussowitsch   Notes:
3864a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3865a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3866a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3867a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3868a4e35b19SJacob Faibussowitsch 
3869dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3870dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3871dce8aebaSBarry Smith 
3872dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3873b67eacb3SMatthew G. Knepley @*/
3874d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUpdateBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx)
3875d71ae5a4SJacob Faibussowitsch {
3876b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3877b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3878b67eacb3SMatthew G. Knepley 
3879b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3880b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3881b67eacb3SMatthew G. Knepley   while (b) {
3882b67eacb3SMatthew G. Knepley     if (n == bd) break;
3883b67eacb3SMatthew G. Knepley     b = b->next;
3884b67eacb3SMatthew G. Knepley     ++n;
3885b67eacb3SMatthew G. Knepley   }
388663a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3887b67eacb3SMatthew G. Knepley   if (name) {
38889566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38899566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3890b67eacb3SMatthew G. Knepley   }
3891b67eacb3SMatthew G. Knepley   b->type = type;
389245480ffeSMatthew G. Knepley   if (label) {
389345480ffeSMatthew G. Knepley     const char *name;
389445480ffeSMatthew G. Knepley 
389545480ffeSMatthew G. Knepley     b->label = label;
38969566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38979566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
38989566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
389945480ffeSMatthew G. Knepley   }
390045480ffeSMatthew G. Knepley   if (Nv >= 0) {
390145480ffeSMatthew G. Knepley     b->Nv = Nv;
39029566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
39039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
39049566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
390545480ffeSMatthew G. Knepley   }
390645480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
390745480ffeSMatthew G. Knepley   if (Nc >= 0) {
390845480ffeSMatthew G. Knepley     b->Nc = Nc;
39099566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
39109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
39119566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
391245480ffeSMatthew G. Knepley   }
391345480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
391445480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
391545480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
39163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3917b67eacb3SMatthew G. Knepley }
3918b67eacb3SMatthew G. Knepley 
391958ebd649SToby Isaac /*@
392058ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
392158ebd649SToby Isaac 
39222fe279fdSBarry Smith   Input Parameter:
3923dce8aebaSBarry Smith . ds - The `PetscDS` object
392458ebd649SToby Isaac 
39252fe279fdSBarry Smith   Output Parameter:
392658ebd649SToby Isaac . numBd - The number of BC
392758ebd649SToby Isaac 
392858ebd649SToby Isaac   Level: intermediate
392958ebd649SToby Isaac 
3930dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
393158ebd649SToby Isaac @*/
3932d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3933d71ae5a4SJacob Faibussowitsch {
393458ebd649SToby Isaac   DSBoundary b = ds->boundary;
393558ebd649SToby Isaac 
393658ebd649SToby Isaac   PetscFunctionBegin;
393758ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
39384f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
393958ebd649SToby Isaac   *numBd = 0;
39409371c9d4SSatish Balay   while (b) {
39419371c9d4SSatish Balay     ++(*numBd);
39429371c9d4SSatish Balay     b = b->next;
39439371c9d4SSatish Balay   }
39443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
394558ebd649SToby Isaac }
394658ebd649SToby Isaac 
394758ebd649SToby Isaac /*@C
39489a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
394958ebd649SToby Isaac 
395058ebd649SToby Isaac   Input Parameters:
3951dce8aebaSBarry Smith + ds - The `PetscDS` object
395258ebd649SToby Isaac - bd - The BC number
395358ebd649SToby Isaac 
395458ebd649SToby Isaac   Output Parameters:
3955dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3956dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3957b44f4de4SBarry Smith . name   - The boundary condition name
395845480ffeSMatthew G. Knepley . label  - The label defining constrained points
3959dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
396045480ffeSMatthew G. Knepley . values - An array of ids for constrained points
396158ebd649SToby Isaac . field  - The field to constrain
396245480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
396358ebd649SToby Isaac . comps  - An array of constrained component numbers
396460225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
396560225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
3966b44f4de4SBarry Smith - ctx    - An optional user context for `bcFunc`
396758ebd649SToby Isaac 
396858ebd649SToby Isaac   Options Database Keys:
396958ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
397058ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
397158ebd649SToby Isaac 
397258ebd649SToby Isaac   Level: developer
397358ebd649SToby Isaac 
3974dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
397558ebd649SToby Isaac @*/
3976d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, PetscWeakForm *wf, DMBoundaryConditionType *type, const char *name[], DMLabel *label, PetscInt *Nv, const PetscInt *values[], PetscInt *field, PetscInt *Nc, const PetscInt *comps[], void (**func)(void), void (**func_t)(void), void **ctx)
3977d71ae5a4SJacob Faibussowitsch {
397858ebd649SToby Isaac   DSBoundary b = ds->boundary;
397958ebd649SToby Isaac   PetscInt   n = 0;
398058ebd649SToby Isaac 
398158ebd649SToby Isaac   PetscFunctionBegin;
398258ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
398358ebd649SToby Isaac   while (b) {
398458ebd649SToby Isaac     if (n == bd) break;
398558ebd649SToby Isaac     b = b->next;
398658ebd649SToby Isaac     ++n;
398758ebd649SToby Isaac   }
398863a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
398945480ffeSMatthew G. Knepley   if (wf) {
39904f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
399145480ffeSMatthew G. Knepley     *wf = b->wf;
399245480ffeSMatthew G. Knepley   }
3993f971fd6bSMatthew G. Knepley   if (type) {
39944f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3995f971fd6bSMatthew G. Knepley     *type = b->type;
399658ebd649SToby Isaac   }
399758ebd649SToby Isaac   if (name) {
39984f572ea9SToby Isaac     PetscAssertPointer(name, 5);
399958ebd649SToby Isaac     *name = b->name;
400058ebd649SToby Isaac   }
400145480ffeSMatthew G. Knepley   if (label) {
40024f572ea9SToby Isaac     PetscAssertPointer(label, 6);
400345480ffeSMatthew G. Knepley     *label = b->label;
400445480ffeSMatthew G. Knepley   }
400545480ffeSMatthew G. Knepley   if (Nv) {
40064f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
400745480ffeSMatthew G. Knepley     *Nv = b->Nv;
400845480ffeSMatthew G. Knepley   }
400945480ffeSMatthew G. Knepley   if (values) {
40104f572ea9SToby Isaac     PetscAssertPointer(values, 8);
401145480ffeSMatthew G. Knepley     *values = b->values;
401258ebd649SToby Isaac   }
401358ebd649SToby Isaac   if (field) {
40144f572ea9SToby Isaac     PetscAssertPointer(field, 9);
401558ebd649SToby Isaac     *field = b->field;
401658ebd649SToby Isaac   }
401745480ffeSMatthew G. Knepley   if (Nc) {
40184f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
401945480ffeSMatthew G. Knepley     *Nc = b->Nc;
402058ebd649SToby Isaac   }
402158ebd649SToby Isaac   if (comps) {
40224f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
402358ebd649SToby Isaac     *comps = b->comps;
402458ebd649SToby Isaac   }
402558ebd649SToby Isaac   if (func) {
40264f572ea9SToby Isaac     PetscAssertPointer(func, 12);
402758ebd649SToby Isaac     *func = b->func;
402858ebd649SToby Isaac   }
402956cf3b9cSMatthew G. Knepley   if (func_t) {
40304f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
403156cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
403256cf3b9cSMatthew G. Knepley   }
403358ebd649SToby Isaac   if (ctx) {
40344f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
403558ebd649SToby Isaac     *ctx = b->ctx;
403658ebd649SToby Isaac   }
40373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
403858ebd649SToby Isaac }
403958ebd649SToby Isaac 
404010af620dSMatthew G. Knepley /*@
404110af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
404210af620dSMatthew G. Knepley 
404310af620dSMatthew G. Knepley   Not Collective
404410af620dSMatthew G. Knepley 
404510af620dSMatthew G. Knepley   Input Parameters:
404610af620dSMatthew G. Knepley + ds - The source `PetscDS` object
404710af620dSMatthew G. Knepley - dm - The `DM` holding labels
404810af620dSMatthew G. Knepley 
404910af620dSMatthew G. Knepley   Level: intermediate
405010af620dSMatthew G. Knepley 
405110af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
405210af620dSMatthew G. Knepley @*/
405310af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
405410af620dSMatthew G. Knepley {
405510af620dSMatthew G. Knepley   DSBoundary b;
405610af620dSMatthew G. Knepley 
405710af620dSMatthew G. Knepley   PetscFunctionBegin;
405810af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
405910af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
406010af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
406110af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
406210af620dSMatthew G. Knepley   }
406310af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
406410af620dSMatthew G. Knepley }
406510af620dSMatthew G. Knepley 
4066d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
4067d71ae5a4SJacob Faibussowitsch {
406845480ffeSMatthew G. Knepley   PetscFunctionBegin;
40699566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
40709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
40719566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
40729566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
40739566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
407445480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
407545480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
407645480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
40779566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
40789566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
407945480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
408045480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
40819566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
40829566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
408345480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
408445480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
408545480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
40863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
408745480ffeSMatthew G. Knepley }
408845480ffeSMatthew G. Knepley 
40899252d075SMatthew G. Knepley /*@
40909252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
40919252d075SMatthew G. Knepley 
409220f4b53cSBarry Smith   Not Collective
40939252d075SMatthew G. Knepley 
409436951cb5SMatthew G. Knepley   Input Parameters:
4095dce8aebaSBarry Smith + ds        - The source `PetscDS` object
4096dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
4097b44f4de4SBarry Smith - fields    - The selected fields, or `NULL` for all fields
40989252d075SMatthew G. Knepley 
40999252d075SMatthew G. Knepley   Output Parameter:
4100dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
41019252d075SMatthew G. Knepley 
41029252d075SMatthew G. Knepley   Level: intermediate
41039252d075SMatthew G. Knepley 
4104dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
41059252d075SMatthew G. Knepley @*/
4106d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
4107d71ae5a4SJacob Faibussowitsch {
410845480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
4109dff059c6SToby Isaac 
4110dff059c6SToby Isaac   PetscFunctionBegin;
411136951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
411236951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
41133ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
41149566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
4115f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
411636951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
4117dff059c6SToby Isaac     DSBoundary bNew;
411836951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
4119dff059c6SToby Isaac 
412036951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
412136951cb5SMatthew G. Knepley       PetscInt f;
412236951cb5SMatthew G. Knepley 
41239371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
41249371c9d4SSatish Balay         if (b->field == fields[f]) break;
412536951cb5SMatthew G. Knepley       if (f == numFields) continue;
412636951cb5SMatthew G. Knepley       fieldNew = f;
412736951cb5SMatthew G. Knepley     }
41289566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
412936951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
4130dff059c6SToby Isaac     *lastnext   = bNew;
4131f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
4132dff059c6SToby Isaac   }
41333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4134dff059c6SToby Isaac }
4135dff059c6SToby Isaac 
41366c1eb96dSMatthew G. Knepley /*@
4137dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
413845480ffeSMatthew G. Knepley 
413920f4b53cSBarry Smith   Not Collective
414045480ffeSMatthew G. Knepley 
414145480ffeSMatthew G. Knepley   Input Parameter:
4142dce8aebaSBarry Smith . ds - The `PetscDS` object
414345480ffeSMatthew G. Knepley 
414445480ffeSMatthew G. Knepley   Level: intermediate
414545480ffeSMatthew G. Knepley 
4146dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
414745480ffeSMatthew G. Knepley @*/
4148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
4149d71ae5a4SJacob Faibussowitsch {
415045480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
415145480ffeSMatthew G. Knepley 
415245480ffeSMatthew G. Knepley   PetscFunctionBegin;
415345480ffeSMatthew G. Knepley   while (next) {
415445480ffeSMatthew G. Knepley     DSBoundary b = next;
415545480ffeSMatthew G. Knepley 
415645480ffeSMatthew G. Knepley     next = b->next;
41579566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
41589566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
41599566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
41609566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
41619566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
41629566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
416345480ffeSMatthew G. Knepley   }
41643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
416545480ffeSMatthew G. Knepley }
416645480ffeSMatthew G. Knepley 
416745480ffeSMatthew G. Knepley /*@
41686c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
41696c1eb96dSMatthew G. Knepley 
417020f4b53cSBarry Smith   Not Collective
41716c1eb96dSMatthew G. Knepley 
4172d8d19677SJose E. Roman   Input Parameters:
4173dce8aebaSBarry Smith + prob      - The `PetscDS` object
41746c1eb96dSMatthew G. Knepley . numFields - Number of new fields
4175bb4b53efSMatthew G. Knepley . fields    - Old field number for each new field
4176bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit
4177bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit
41786c1eb96dSMatthew G. Knepley 
41796c1eb96dSMatthew G. Knepley   Output Parameter:
4180dce8aebaSBarry Smith . newprob - The `PetscDS` copy
41816c1eb96dSMatthew G. Knepley 
41826c1eb96dSMatthew G. Knepley   Level: intermediate
41836c1eb96dSMatthew G. Knepley 
4184dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
41856c1eb96dSMatthew G. Knepley @*/
4186bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscInt minDegree, PetscInt maxDegree, PetscDS newprob)
4187d71ae5a4SJacob Faibussowitsch {
41886c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
41896c1eb96dSMatthew G. Knepley 
41906c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
41916c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41924f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
4193bb4b53efSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 6);
41949566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41959566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
419645480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
41976c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
41986c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
41996c1eb96dSMatthew G. Knepley     PetscObject    disc;
4200bb4b53efSMatthew G. Knepley     PetscClassId   id;
42016c1eb96dSMatthew G. Knepley 
42026c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
42039566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
4204bb4b53efSMatthew G. Knepley     PetscCallContinue(PetscObjectGetClassId(disc, &id));
4205bb4b53efSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
4206bb4b53efSMatthew G. Knepley       PetscFE fe;
4207bb4b53efSMatthew G. Knepley 
4208bb4b53efSMatthew G. Knepley       PetscCall(PetscFELimitDegree((PetscFE)disc, minDegree, maxDegree, &fe));
4209bb4b53efSMatthew G. Knepley       PetscCall(PetscDSSetDiscretization(newprob, fn, (PetscObject)fe));
4210bb4b53efSMatthew G. Knepley       PetscCall(PetscFEDestroy(&fe));
4211bb4b53efSMatthew G. Knepley     } else {
42129566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
42136c1eb96dSMatthew G. Knepley     }
4214bb4b53efSMatthew G. Knepley   }
42153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42166c1eb96dSMatthew G. Knepley }
42176c1eb96dSMatthew G. Knepley 
42186c1eb96dSMatthew G. Knepley /*@
42199252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
42209252d075SMatthew G. Knepley 
422120f4b53cSBarry Smith   Not Collective
42229252d075SMatthew G. Knepley 
4223d8d19677SJose E. Roman   Input Parameters:
4224dce8aebaSBarry Smith + prob      - The `PetscDS` object
42259252d075SMatthew G. Knepley . numFields - Number of new fields
42269252d075SMatthew G. Knepley - fields    - Old field number for each new field
42279252d075SMatthew G. Knepley 
42289252d075SMatthew G. Knepley   Output Parameter:
4229dce8aebaSBarry Smith . newprob - The `PetscDS` copy
42309252d075SMatthew G. Knepley 
42319252d075SMatthew G. Knepley   Level: intermediate
42329252d075SMatthew G. Knepley 
4233dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
42349252d075SMatthew G. Knepley @*/
4235d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
4236d71ae5a4SJacob Faibussowitsch {
42379252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
42389252d075SMatthew G. Knepley 
42399252d075SMatthew G. Knepley   PetscFunctionBegin;
42409252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
42414f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
42429252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
42439566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
42449566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
4245*e87b5d96SPierre Jolivet   PetscCheck(numFields <= Nfn, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields %" PetscInt_FMT " to transfer must not be greater than the total number of fields %" PetscInt_FMT, numFields, Nfn);
42469252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
42479252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
42489252d075SMatthew G. Knepley     PetscPointFunc   obj;
42499252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
42509252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
42519252d075SMatthew G. Knepley     PetscRiemannFunc r;
42529252d075SMatthew G. Knepley 
4253c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
42549566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
42559566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
42569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
42579566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
42589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
42599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
42609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
42619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
42629252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
42639252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
42649252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
42659252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
42669252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
42679252d075SMatthew G. Knepley 
4268c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
42699566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
42709566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
42719566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
42729566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
42739566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
42749566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
42759252d075SMatthew G. Knepley     }
42769252d075SMatthew G. Knepley   }
42773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42789252d075SMatthew G. Knepley }
42799252d075SMatthew G. Knepley 
4280da51fcedSMatthew G. Knepley /*@
4281dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
4282da51fcedSMatthew G. Knepley 
428320f4b53cSBarry Smith   Not Collective
4284da51fcedSMatthew G. Knepley 
4285da51fcedSMatthew G. Knepley   Input Parameter:
4286dce8aebaSBarry Smith . prob - The `PetscDS` object
4287da51fcedSMatthew G. Knepley 
4288da51fcedSMatthew G. Knepley   Output Parameter:
4289dce8aebaSBarry Smith . newprob - The `PetscDS` copy
4290da51fcedSMatthew G. Knepley 
4291da51fcedSMatthew G. Knepley   Level: intermediate
4292da51fcedSMatthew G. Knepley 
4293dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4294da51fcedSMatthew G. Knepley @*/
4295d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
4296d71ae5a4SJacob Faibussowitsch {
4297b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
42989252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4299da51fcedSMatthew G. Knepley 
4300da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4301da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4302da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
43039566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
43049566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
430563a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
43069566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
43079566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
43089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
43093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43109252d075SMatthew G. Knepley }
431145480ffeSMatthew G. Knepley 
43129252d075SMatthew G. Knepley /*@
4313dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4314da51fcedSMatthew G. Knepley 
431520f4b53cSBarry Smith   Not Collective
43169252d075SMatthew G. Knepley 
43179252d075SMatthew G. Knepley   Input Parameter:
4318dce8aebaSBarry Smith . prob - The `PetscDS` object
43199252d075SMatthew G. Knepley 
43209252d075SMatthew G. Knepley   Output Parameter:
4321dce8aebaSBarry Smith . newprob - The `PetscDS` copy
43229252d075SMatthew G. Knepley 
43239252d075SMatthew G. Knepley   Level: intermediate
43249252d075SMatthew G. Knepley 
4325dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
43269252d075SMatthew G. Knepley @*/
4327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4328d71ae5a4SJacob Faibussowitsch {
43299252d075SMatthew G. Knepley   PetscInt           Nc;
43309252d075SMatthew G. Knepley   const PetscScalar *constants;
43319252d075SMatthew G. Knepley 
43329252d075SMatthew G. Knepley   PetscFunctionBegin;
43339252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
43349252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
43359566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
43369566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
43373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4338da51fcedSMatthew G. Knepley }
4339da51fcedSMatthew G. Knepley 
434045480ffeSMatthew G. Knepley /*@
4341dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
434245480ffeSMatthew G. Knepley 
434320f4b53cSBarry Smith   Not Collective
434445480ffeSMatthew G. Knepley 
434545480ffeSMatthew G. Knepley   Input Parameter:
4346dce8aebaSBarry Smith . ds - The `PetscDS` object
434745480ffeSMatthew G. Knepley 
434845480ffeSMatthew G. Knepley   Output Parameter:
4349dce8aebaSBarry Smith . newds - The `PetscDS` copy
435045480ffeSMatthew G. Knepley 
435145480ffeSMatthew G. Knepley   Level: intermediate
435245480ffeSMatthew G. Knepley 
4353342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyBounds()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
435445480ffeSMatthew G. Knepley @*/
4355d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4356d71ae5a4SJacob Faibussowitsch {
43578434afd1SBarry Smith   PetscSimplePointFn *sol;
435845480ffeSMatthew G. Knepley   void               *ctx;
435945480ffeSMatthew G. Knepley   PetscInt            Nf, f;
436045480ffeSMatthew G. Knepley 
436145480ffeSMatthew G. Knepley   PetscFunctionBegin;
436245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
436345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
43649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
436545480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
43669566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
43679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
43689566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
43699566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
437045480ffeSMatthew G. Knepley   }
43713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
437245480ffeSMatthew G. Knepley }
437345480ffeSMatthew G. Knepley 
4374342bd5aaSMatthew G. Knepley /*@
4375342bd5aaSMatthew G. Knepley   PetscDSCopyBounds - Copy lower and upper solution bounds to another `PetscDS`
4376342bd5aaSMatthew G. Knepley 
4377342bd5aaSMatthew G. Knepley   Not Collective
4378342bd5aaSMatthew G. Knepley 
4379342bd5aaSMatthew G. Knepley   Input Parameter:
4380342bd5aaSMatthew G. Knepley . ds - The `PetscDS` object
4381342bd5aaSMatthew G. Knepley 
4382342bd5aaSMatthew G. Knepley   Output Parameter:
4383342bd5aaSMatthew G. Knepley . newds - The `PetscDS` copy
4384342bd5aaSMatthew G. Knepley 
4385342bd5aaSMatthew G. Knepley   Level: intermediate
4386342bd5aaSMatthew G. Knepley 
4387342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyExactSolutions()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4388342bd5aaSMatthew G. Knepley @*/
4389342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSCopyBounds(PetscDS ds, PetscDS newds)
4390342bd5aaSMatthew G. Knepley {
4391342bd5aaSMatthew G. Knepley   PetscSimplePointFn *bound;
4392342bd5aaSMatthew G. Knepley   void               *ctx;
4393342bd5aaSMatthew G. Knepley   PetscInt            Nf, f;
4394342bd5aaSMatthew G. Knepley 
4395342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
4396342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4397342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
4398342bd5aaSMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
4399342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4400342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetLowerBound(ds, f, &bound, &ctx));
4401342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetLowerBound(newds, f, bound, ctx));
4402342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetUpperBound(ds, f, &bound, &ctx));
4403342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetUpperBound(newds, f, bound, ctx));
4404342bd5aaSMatthew G. Knepley   }
4405342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
4406342bd5aaSMatthew G. Knepley }
4407342bd5aaSMatthew G. Knepley 
4408bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, PetscInt minDegree, PetscInt maxDegree, DM dmNew, PetscDS dsNew)
440907218a29SMatthew G. Knepley {
441007218a29SMatthew G. Knepley   DSBoundary b;
441107218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
441207218a29SMatthew G. Knepley   PetscBool  isCohesive;
441307218a29SMatthew G. Knepley   void      *ctx;
441407218a29SMatthew G. Knepley 
441507218a29SMatthew G. Knepley   PetscFunctionBegin;
441607218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
441707218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
4418342bd5aaSMatthew G. Knepley   PetscCall(PetscDSCopyBounds(ds, dsNew));
4419bb4b53efSMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, minDegree, maxDegree, dsNew));
442007218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
442107218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
442207218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
442307218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
442407218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
442507218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
442607218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
442707218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
442807218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
442907218a29SMatthew G. Knepley   }
443007218a29SMatthew G. Knepley   if (Nf) {
443107218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
443207218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
443307218a29SMatthew G. Knepley   }
443407218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
443507218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
443607218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
443707218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
443807218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
443907218a29SMatthew G. Knepley   }
444007218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
444107218a29SMatthew G. Knepley }
444207218a29SMatthew G. Knepley 
4443d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4444d71ae5a4SJacob Faibussowitsch {
4445df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4446b1353e8eSMatthew G. Knepley 
4447b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4448b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
44494f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
44509371c9d4SSatish Balay   if (height == 0) {
44519371c9d4SSatish Balay     *subprob = prob;
44523ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
44539371c9d4SSatish Balay   }
44549566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
44559566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
445663a3b9bcSJacob Faibussowitsch   PetscCheck(height <= dim, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_OUTOFRANGE, "DS can only handle height in [0, %" PetscInt_FMT "], not %" PetscInt_FMT, dim, height);
44579566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4458df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4459b1353e8eSMatthew G. Knepley     PetscInt cdim;
4460b1353e8eSMatthew G. Knepley 
44619566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
44629566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
44639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4464b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4465b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4466b1353e8eSMatthew G. Knepley       PetscObject  obj;
4467b1353e8eSMatthew G. Knepley       PetscClassId id;
4468b1353e8eSMatthew G. Knepley 
44699566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
44709566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
44719566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
447263a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
44739566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4474b1353e8eSMatthew G. Knepley     }
4475b1353e8eSMatthew G. Knepley   }
4476df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
44773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4478b1353e8eSMatthew G. Knepley }
4479b1353e8eSMatthew G. Knepley 
44804366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
44814366bac7SMatthew G. Knepley {
44824366bac7SMatthew G. Knepley   IS              permIS;
44834366bac7SMatthew G. Knepley   PetscQuadrature quad;
44844366bac7SMatthew G. Knepley   DMPolytopeType  ct;
44854366bac7SMatthew G. Knepley   const PetscInt *perm;
44864366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
44874366bac7SMatthew G. Knepley 
44884366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
44894366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
44904366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
44914366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
44924366bac7SMatthew G. Knepley   PetscCheck(q >= 0 && q < Nq, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Quadrature point %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", q, Nq);
449385036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
44944366bac7SMatthew G. Knepley   PetscCheck(ornt >= -Na && ornt < Na, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Orientation %" PetscInt_FMT " of %s is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", ornt, DMPolytopeTypes[ct], -Na, Na);
44954366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
44964366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
44974366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
44984366bac7SMatthew G. Knepley   *qperm = perm[q];
44994366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
45004366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
45014366bac7SMatthew G. Knepley }
45024366bac7SMatthew G. Knepley 
4503d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4504d71ae5a4SJacob Faibussowitsch {
4505c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4506c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4507c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4508c7bd5f0bSMatthew G. Knepley 
4509c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4510c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
45114f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4512665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
45139566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
451463a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
45159566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4516665f567fSMatthew G. Knepley   if (obj) {
45179566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4518665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4519665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4520665f567fSMatthew G. Knepley   }
45213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4522c7bd5f0bSMatthew G. Knepley }
4523c7bd5f0bSMatthew G. Knepley 
4524d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4525d71ae5a4SJacob Faibussowitsch {
45262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45279566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
45283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45292764a2aaSMatthew G. Knepley }
45302764a2aaSMatthew G. Knepley 
4531d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4532d71ae5a4SJacob Faibussowitsch {
45332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45346528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
45356528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
45366528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
45376528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
45383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45392764a2aaSMatthew G. Knepley }
45402764a2aaSMatthew G. Knepley 
45412764a2aaSMatthew G. Knepley /*MC
45422764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
45432764a2aaSMatthew G. Knepley 
45442764a2aaSMatthew G. Knepley   Level: intermediate
45452764a2aaSMatthew G. Knepley 
4546db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
45472764a2aaSMatthew G. Knepley M*/
45482764a2aaSMatthew G. Knepley 
4549d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4550d71ae5a4SJacob Faibussowitsch {
45512764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
45522764a2aaSMatthew G. Knepley 
45532764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45546528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
45554dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
45566528b96dSMatthew G. Knepley   ds->data = b;
45572764a2aaSMatthew G. Knepley 
45589566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
45593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45602764a2aaSMatthew G. Knepley }
4561