xref: /petsc/src/dm/dt/interface/dtds.c (revision 1702e18101f69472d8d0ca93bed43db6367b4f22)
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;
5588434afd1SBarry Smith   PetscSimplePointFn **tmpexactSol, **tmpexactSol_t;
559f2cacb80SMatthew G. Knepley   void               **tmpexactCtx, **tmpexactCtx_t;
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));
595c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59695cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
597f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
598f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
599c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
60095cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
601f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
602f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
6039566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
604c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60595cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
606f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
607f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6092764a2aaSMatthew G. Knepley }
6102764a2aaSMatthew G. Knepley 
6112764a2aaSMatthew G. Knepley /*@
61220f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6132764a2aaSMatthew G. Knepley 
61420f4b53cSBarry Smith   Collective
6152764a2aaSMatthew G. Knepley 
6162764a2aaSMatthew G. Knepley   Input Parameter:
61760225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6182764a2aaSMatthew G. Knepley 
6192764a2aaSMatthew G. Knepley   Level: developer
6202764a2aaSMatthew G. Knepley 
621dce8aebaSBarry Smith .seealso: `PetscDSView()`
6222764a2aaSMatthew G. Knepley @*/
623d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
624d71ae5a4SJacob Faibussowitsch {
6252764a2aaSMatthew G. Knepley   PetscInt f;
6262764a2aaSMatthew G. Knepley 
6272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6283ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
629f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6302764a2aaSMatthew G. Knepley 
631f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6329371c9d4SSatish Balay     *ds = NULL;
6333ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6349371c9d4SSatish Balay   }
635f4f49eeaSPierre Jolivet   ((PetscObject)*ds)->refct = 0;
6366528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
637df3a45bdSMatthew G. Knepley     PetscInt dim, d;
638df3a45bdSMatthew G. Knepley 
6399566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6409566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
641df3a45bdSMatthew G. Knepley   }
6429566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6439566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64448a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6459566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6479566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6489566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
649f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ds, destroy);
6509566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6519566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6524366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
65385036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((DMPolytopeType)c);
6544366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6554366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6564366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6574366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6584366bac7SMatthew G. Knepley   }
6599566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6612764a2aaSMatthew G. Knepley }
6622764a2aaSMatthew G. Knepley 
6632764a2aaSMatthew G. Knepley /*@
664dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6652764a2aaSMatthew G. Knepley 
666d083f849SBarry Smith   Collective
6672764a2aaSMatthew G. Knepley 
6682764a2aaSMatthew G. Knepley   Input Parameter:
669dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6702764a2aaSMatthew G. Knepley 
6712764a2aaSMatthew G. Knepley   Output Parameter:
672dce8aebaSBarry Smith . ds - The `PetscDS` object
6732764a2aaSMatthew G. Knepley 
6742764a2aaSMatthew G. Knepley   Level: beginner
6752764a2aaSMatthew G. Knepley 
676dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6772764a2aaSMatthew G. Knepley @*/
678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
679d71ae5a4SJacob Faibussowitsch {
6802764a2aaSMatthew G. Knepley   PetscDS p;
6812764a2aaSMatthew G. Knepley 
6822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6834f572ea9SToby Isaac   PetscAssertPointer(ds, 2);
6849566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6852764a2aaSMatthew G. Knepley 
6869566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6872764a2aaSMatthew G. Knepley   p->Nf               = 0;
6882764a2aaSMatthew G. Knepley   p->setup            = PETSC_FALSE;
68997b6e6e8SMatthew G. Knepley   p->numConstants     = 0;
69087510d7dSMatthew G. Knepley   p->numFuncConstants = 3; // Row and col fields, cell size
691a859676bSMatthew G. Knepley   p->dimEmbed         = -1;
69255c1f793SMatthew G. Knepley   p->useJacPre        = PETSC_TRUE;
69312fc5b22SMatthew G. Knepley   p->forceQuad        = PETSC_TRUE;
694a102dd69SStefano Zampini   PetscCall(PetscMalloc1(p->numConstants + p->numFuncConstants, &p->constants));
6959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6964366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
6976528b96dSMatthew G. Knepley   *ds = p;
6983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6992764a2aaSMatthew G. Knepley }
7002764a2aaSMatthew G. Knepley 
701bc4ae4beSMatthew G. Knepley /*@
702dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
703bc4ae4beSMatthew G. Knepley 
70420f4b53cSBarry Smith   Not Collective
705bc4ae4beSMatthew G. Knepley 
706bc4ae4beSMatthew G. Knepley   Input Parameter:
70720f4b53cSBarry Smith . prob - The `PetscDS` object
708bc4ae4beSMatthew G. Knepley 
709bc4ae4beSMatthew G. Knepley   Output Parameter:
710bc4ae4beSMatthew G. Knepley . Nf - The number of fields
711bc4ae4beSMatthew G. Knepley 
712bc4ae4beSMatthew G. Knepley   Level: beginner
713bc4ae4beSMatthew G. Knepley 
714dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
715bc4ae4beSMatthew G. Knepley @*/
716d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
717d71ae5a4SJacob Faibussowitsch {
7182764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7192764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7204f572ea9SToby Isaac   PetscAssertPointer(Nf, 2);
7212764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7232764a2aaSMatthew G. Knepley }
7242764a2aaSMatthew G. Knepley 
725bc4ae4beSMatthew G. Knepley /*@
726dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
727bc4ae4beSMatthew G. Knepley 
72820f4b53cSBarry Smith   Not Collective
729bc4ae4beSMatthew G. Knepley 
730bc4ae4beSMatthew G. Knepley   Input Parameter:
731dce8aebaSBarry Smith . prob - The `PetscDS` object
732bc4ae4beSMatthew G. Knepley 
733bc4ae4beSMatthew G. Knepley   Output Parameter:
734bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
735bc4ae4beSMatthew G. Knepley 
736bc4ae4beSMatthew G. Knepley   Level: beginner
737bc4ae4beSMatthew G. Knepley 
738dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
739bc4ae4beSMatthew G. Knepley @*/
740d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
741d71ae5a4SJacob Faibussowitsch {
7422764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7432764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7444f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
7452764a2aaSMatthew G. Knepley   *dim = 0;
7469de99aefSMatthew G. Knepley   if (prob->Nf) {
7479de99aefSMatthew G. Knepley     PetscObject  obj;
7489de99aefSMatthew G. Knepley     PetscClassId id;
7499de99aefSMatthew G. Knepley 
7509566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
751665f567fSMatthew G. Knepley     if (obj) {
7529566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7539566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7549566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
75598921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7569de99aefSMatthew G. Knepley     }
757665f567fSMatthew G. Knepley   }
7583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7592764a2aaSMatthew G. Knepley }
7602764a2aaSMatthew G. Knepley 
761bc4ae4beSMatthew G. Knepley /*@
762dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
763a859676bSMatthew G. Knepley 
76420f4b53cSBarry Smith   Not Collective
765a859676bSMatthew G. Knepley 
766a859676bSMatthew G. Knepley   Input Parameter:
767dce8aebaSBarry Smith . prob - The `PetscDS` object
768a859676bSMatthew G. Knepley 
769a859676bSMatthew G. Knepley   Output Parameter:
770a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
771a859676bSMatthew G. Knepley 
772a859676bSMatthew G. Knepley   Level: beginner
773a859676bSMatthew G. Knepley 
774dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
775a859676bSMatthew G. Knepley @*/
776d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
777d71ae5a4SJacob Faibussowitsch {
778a859676bSMatthew G. Knepley   PetscFunctionBegin;
779a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7804f572ea9SToby Isaac   PetscAssertPointer(dimEmbed, 2);
78108401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
782a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
784a859676bSMatthew G. Knepley }
785a859676bSMatthew G. Knepley 
786a859676bSMatthew G. Knepley /*@
787dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
788a859676bSMatthew G. Knepley 
78920f4b53cSBarry Smith   Logically Collective
790a859676bSMatthew G. Knepley 
791a859676bSMatthew G. Knepley   Input Parameters:
792dce8aebaSBarry Smith + prob     - The `PetscDS` object
793a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
794a859676bSMatthew G. Knepley 
795a859676bSMatthew G. Knepley   Level: beginner
796a859676bSMatthew G. Knepley 
797dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
798a859676bSMatthew G. Knepley @*/
799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
800d71ae5a4SJacob Faibussowitsch {
801a859676bSMatthew G. Knepley   PetscFunctionBegin;
802a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
80363a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
804a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
806a859676bSMatthew G. Knepley }
807a859676bSMatthew G. Knepley 
808a859676bSMatthew G. Knepley /*@
80912fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
81012fc5b22SMatthew G. Knepley 
81112fc5b22SMatthew G. Knepley   Not collective
81212fc5b22SMatthew G. Knepley 
81312fc5b22SMatthew G. Knepley   Input Parameter:
81460225df5SJacob Faibussowitsch . ds - The `PetscDS` object
81512fc5b22SMatthew G. Knepley 
81612fc5b22SMatthew G. Knepley   Output Parameter:
81712fc5b22SMatthew G. Knepley . forceQuad - The flag
81812fc5b22SMatthew G. Knepley 
81912fc5b22SMatthew G. Knepley   Level: intermediate
82012fc5b22SMatthew G. Knepley 
82112fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82212fc5b22SMatthew G. Knepley @*/
82312fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
82412fc5b22SMatthew G. Knepley {
82512fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82612fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8274f572ea9SToby Isaac   PetscAssertPointer(forceQuad, 2);
82812fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
82912fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83012fc5b22SMatthew G. Knepley }
83112fc5b22SMatthew G. Knepley 
83212fc5b22SMatthew G. Knepley /*@
83312fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
83412fc5b22SMatthew G. Knepley 
83512fc5b22SMatthew G. Knepley   Logically collective on ds
83612fc5b22SMatthew G. Knepley 
83712fc5b22SMatthew G. Knepley   Input Parameters:
83812fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
83912fc5b22SMatthew G. Knepley - forceQuad - The flag
84012fc5b22SMatthew G. Knepley 
84112fc5b22SMatthew G. Knepley   Level: intermediate
84212fc5b22SMatthew G. Knepley 
84312fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
84412fc5b22SMatthew G. Knepley @*/
84512fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
84612fc5b22SMatthew G. Knepley {
84712fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84812fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
84912fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
85012fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
85112fc5b22SMatthew G. Knepley }
85212fc5b22SMatthew G. Knepley 
85312fc5b22SMatthew G. Knepley /*@
854dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8558edf6225SMatthew G. Knepley 
85620f4b53cSBarry Smith   Not Collective
8578edf6225SMatthew G. Knepley 
8588edf6225SMatthew G. Knepley   Input Parameter:
859dce8aebaSBarry Smith . ds - The `PetscDS` object
8608edf6225SMatthew G. Knepley 
8618edf6225SMatthew G. Knepley   Output Parameter:
8625fedec97SMatthew G. Knepley . isCohesive - The flag
8638edf6225SMatthew G. Knepley 
8648edf6225SMatthew G. Knepley   Level: developer
8658edf6225SMatthew G. Knepley 
866dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8678edf6225SMatthew G. Knepley @*/
868d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
869d71ae5a4SJacob Faibussowitsch {
8708edf6225SMatthew G. Knepley   PetscFunctionBegin;
8715fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8724f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 2);
8735fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8758edf6225SMatthew G. Knepley }
8768edf6225SMatthew G. Knepley 
8778edf6225SMatthew G. Knepley /*@
878be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8795fedec97SMatthew G. Knepley 
88020f4b53cSBarry Smith   Not Collective
8815fedec97SMatthew G. Knepley 
8825fedec97SMatthew G. Knepley   Input Parameter:
883dce8aebaSBarry Smith . ds - The `PetscDS` object
8845fedec97SMatthew G. Knepley 
8855fedec97SMatthew G. Knepley   Output Parameter:
8865fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8875fedec97SMatthew G. Knepley 
8885fedec97SMatthew G. Knepley   Level: developer
8895fedec97SMatthew G. Knepley 
890dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8915fedec97SMatthew G. Knepley @*/
892d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
893d71ae5a4SJacob Faibussowitsch {
8945fedec97SMatthew G. Knepley   PetscInt f;
8955fedec97SMatthew G. Knepley 
8965fedec97SMatthew G. Knepley   PetscFunctionBegin;
8975fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8984f572ea9SToby Isaac   PetscAssertPointer(numCohesive, 2);
8995fedec97SMatthew G. Knepley   *numCohesive = 0;
9005fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9025fedec97SMatthew G. Knepley }
9035fedec97SMatthew G. Knepley 
9045fedec97SMatthew G. Knepley /*@
9055fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9065fedec97SMatthew G. Knepley 
90720f4b53cSBarry Smith   Not Collective
9085fedec97SMatthew G. Knepley 
909f1a722f8SMatthew G. Knepley   Input Parameters:
910dce8aebaSBarry Smith + ds - The `PetscDS` object
9115fedec97SMatthew G. Knepley - f  - The field index
9125fedec97SMatthew G. Knepley 
9135fedec97SMatthew G. Knepley   Output Parameter:
9145fedec97SMatthew G. Knepley . isCohesive - The flag
9155fedec97SMatthew G. Knepley 
9165fedec97SMatthew G. Knepley   Level: developer
9175fedec97SMatthew G. Knepley 
918dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9195fedec97SMatthew G. Knepley @*/
920d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
921d71ae5a4SJacob Faibussowitsch {
9225fedec97SMatthew G. Knepley   PetscFunctionBegin;
9235fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9244f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 3);
92563a3b9bcSJacob 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);
9265fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9285fedec97SMatthew G. Knepley }
9295fedec97SMatthew G. Knepley 
9305fedec97SMatthew G. Knepley /*@
9315fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9328edf6225SMatthew G. Knepley 
93320f4b53cSBarry Smith   Not Collective
9348edf6225SMatthew G. Knepley 
9358edf6225SMatthew G. Knepley   Input Parameters:
936dce8aebaSBarry Smith + ds         - The `PetscDS` object
9375fedec97SMatthew G. Knepley . f          - The field index
9385fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9398edf6225SMatthew G. Knepley 
9408edf6225SMatthew G. Knepley   Level: developer
9418edf6225SMatthew G. Knepley 
942dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9438edf6225SMatthew G. Knepley @*/
944d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
945d71ae5a4SJacob Faibussowitsch {
9465fedec97SMatthew G. Knepley   PetscInt i;
9475fedec97SMatthew G. Knepley 
9488edf6225SMatthew G. Knepley   PetscFunctionBegin;
9495fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
95063a3b9bcSJacob 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);
9515fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9525fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9535fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9558edf6225SMatthew G. Knepley }
9568edf6225SMatthew G. Knepley 
9578edf6225SMatthew G. Knepley /*@
958bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
959bc4ae4beSMatthew G. Knepley 
96020f4b53cSBarry Smith   Not Collective
961bc4ae4beSMatthew G. Knepley 
962bc4ae4beSMatthew G. Knepley   Input Parameter:
963dce8aebaSBarry Smith . prob - The `PetscDS` object
964bc4ae4beSMatthew G. Knepley 
965bc4ae4beSMatthew G. Knepley   Output Parameter:
966bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
967bc4ae4beSMatthew G. Knepley 
968bc4ae4beSMatthew G. Knepley   Level: beginner
969bc4ae4beSMatthew G. Knepley 
970dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
971bc4ae4beSMatthew G. Knepley @*/
972d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
973d71ae5a4SJacob Faibussowitsch {
9742764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9752764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9769566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
9774f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
9782764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9802764a2aaSMatthew G. Knepley }
9812764a2aaSMatthew G. Knepley 
982bc4ae4beSMatthew G. Knepley /*@
983bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
984bc4ae4beSMatthew G. Knepley 
98520f4b53cSBarry Smith   Not Collective
986bc4ae4beSMatthew G. Knepley 
987bc4ae4beSMatthew G. Knepley   Input Parameter:
988dce8aebaSBarry Smith . prob - The `PetscDS` object
989bc4ae4beSMatthew G. Knepley 
990bc4ae4beSMatthew G. Knepley   Output Parameter:
99160225df5SJacob Faibussowitsch . Nc - The total number of components
992bc4ae4beSMatthew G. Knepley 
993bc4ae4beSMatthew G. Knepley   Level: beginner
994bc4ae4beSMatthew G. Knepley 
995dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
996bc4ae4beSMatthew G. Knepley @*/
997d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
998d71ae5a4SJacob Faibussowitsch {
9992764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10002764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10019566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
10024f572ea9SToby Isaac   PetscAssertPointer(Nc, 2);
10032764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10052764a2aaSMatthew G. Knepley }
10062764a2aaSMatthew G. Knepley 
1007bc4ae4beSMatthew G. Knepley /*@
1008bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1009bc4ae4beSMatthew G. Knepley 
101020f4b53cSBarry Smith   Not Collective
1011bc4ae4beSMatthew G. Knepley 
1012bc4ae4beSMatthew G. Knepley   Input Parameters:
1013dce8aebaSBarry Smith + prob - The `PetscDS` object
1014bc4ae4beSMatthew G. Knepley - f    - The field number
1015bc4ae4beSMatthew G. Knepley 
1016bc4ae4beSMatthew G. Knepley   Output Parameter:
1017bc4ae4beSMatthew G. Knepley . disc - The discretization object
1018bc4ae4beSMatthew G. Knepley 
1019bc4ae4beSMatthew G. Knepley   Level: beginner
1020bc4ae4beSMatthew G. Knepley 
1021dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1022bc4ae4beSMatthew G. Knepley @*/
1023d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1024d71ae5a4SJacob Faibussowitsch {
10256528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10262764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10274f572ea9SToby Isaac   PetscAssertPointer(disc, 3);
102863a3b9bcSJacob 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);
10292764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10312764a2aaSMatthew G. Knepley }
10322764a2aaSMatthew G. Knepley 
1033bc4ae4beSMatthew G. Knepley /*@
1034bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1035bc4ae4beSMatthew G. Knepley 
103620f4b53cSBarry Smith   Not Collective
1037bc4ae4beSMatthew G. Knepley 
1038bc4ae4beSMatthew G. Knepley   Input Parameters:
1039dce8aebaSBarry Smith + prob - The `PetscDS` object
1040bc4ae4beSMatthew G. Knepley . f    - The field number
1041bc4ae4beSMatthew G. Knepley - disc - The discretization object
1042bc4ae4beSMatthew G. Knepley 
1043bc4ae4beSMatthew G. Knepley   Level: beginner
1044bc4ae4beSMatthew G. Knepley 
1045dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1046bc4ae4beSMatthew G. Knepley @*/
1047d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1048d71ae5a4SJacob Faibussowitsch {
10492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10502764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10514f572ea9SToby Isaac   if (disc) PetscAssertPointer(disc, 3);
105263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10539566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10549566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10552764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10569566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1057665f567fSMatthew G. Knepley   if (disc) {
1058249df284SMatthew G. Knepley     PetscClassId id;
1059249df284SMatthew G. Knepley 
10609566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10611cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10629566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10631cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10649566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1065a6cbbb48SMatthew G. Knepley     }
10669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1067249df284SMatthew G. Knepley   }
10683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10692764a2aaSMatthew G. Knepley }
10702764a2aaSMatthew G. Knepley 
1071bc4ae4beSMatthew G. Knepley /*@
10726528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10736528b96dSMatthew G. Knepley 
107420f4b53cSBarry Smith   Not Collective
10756528b96dSMatthew G. Knepley 
10766528b96dSMatthew G. Knepley   Input Parameter:
1077dce8aebaSBarry Smith . ds - The `PetscDS` object
10786528b96dSMatthew G. Knepley 
10796528b96dSMatthew G. Knepley   Output Parameter:
10806528b96dSMatthew G. Knepley . wf - The weak form object
10816528b96dSMatthew G. Knepley 
10826528b96dSMatthew G. Knepley   Level: beginner
10836528b96dSMatthew G. Knepley 
1084dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10856528b96dSMatthew G. Knepley @*/
1086d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1087d71ae5a4SJacob Faibussowitsch {
10886528b96dSMatthew G. Knepley   PetscFunctionBegin;
10896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10904f572ea9SToby Isaac   PetscAssertPointer(wf, 2);
10916528b96dSMatthew G. Knepley   *wf = ds->wf;
10923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10936528b96dSMatthew G. Knepley }
10946528b96dSMatthew G. Knepley 
10956528b96dSMatthew G. Knepley /*@
10966528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10976528b96dSMatthew G. Knepley 
109820f4b53cSBarry Smith   Not Collective
10996528b96dSMatthew G. Knepley 
11006528b96dSMatthew G. Knepley   Input Parameters:
1101dce8aebaSBarry Smith + ds - The `PetscDS` object
11026528b96dSMatthew G. Knepley - wf - The weak form object
11036528b96dSMatthew G. Knepley 
11046528b96dSMatthew G. Knepley   Level: beginner
11056528b96dSMatthew G. Knepley 
1106dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11076528b96dSMatthew G. Knepley @*/
1108d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1109d71ae5a4SJacob Faibussowitsch {
11106528b96dSMatthew G. Knepley   PetscFunctionBegin;
11116528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11126528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11139566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11146528b96dSMatthew G. Knepley   ds->wf = wf;
11159566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11186528b96dSMatthew G. Knepley }
11196528b96dSMatthew G. Knepley 
11206528b96dSMatthew G. Knepley /*@
1121bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1122bc4ae4beSMatthew G. Knepley 
112320f4b53cSBarry Smith   Not Collective
1124bc4ae4beSMatthew G. Knepley 
1125bc4ae4beSMatthew G. Knepley   Input Parameters:
1126dce8aebaSBarry Smith + prob - The `PetscDS` object
1127bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1128bc4ae4beSMatthew G. Knepley 
1129bc4ae4beSMatthew G. Knepley   Level: beginner
1130bc4ae4beSMatthew G. Knepley 
1131dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1132bc4ae4beSMatthew G. Knepley @*/
1133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1134d71ae5a4SJacob Faibussowitsch {
11352764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11369566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11382764a2aaSMatthew G. Knepley }
11392764a2aaSMatthew G. Knepley 
1140249df284SMatthew G. Knepley /*@
1141dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1142083401c6SMatthew G. Knepley 
114320f4b53cSBarry Smith   Not Collective
1144083401c6SMatthew G. Knepley 
1145083401c6SMatthew G. Knepley   Input Parameter:
1146dce8aebaSBarry Smith . prob - The `PetscDS` object
1147083401c6SMatthew G. Knepley 
1148083401c6SMatthew G. Knepley   Output Parameter:
1149083401c6SMatthew G. Knepley . q - The quadrature object
1150083401c6SMatthew G. Knepley 
1151083401c6SMatthew G. Knepley   Level: intermediate
1152083401c6SMatthew G. Knepley 
1153dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1154083401c6SMatthew G. Knepley @*/
1155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1156d71ae5a4SJacob Faibussowitsch {
1157083401c6SMatthew G. Knepley   PetscObject  obj;
1158083401c6SMatthew G. Knepley   PetscClassId id;
1159083401c6SMatthew G. Knepley 
1160083401c6SMatthew G. Knepley   PetscFunctionBegin;
1161083401c6SMatthew G. Knepley   *q = NULL;
11623ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11639566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11649566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11659566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11669566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116798921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1169083401c6SMatthew G. Knepley }
1170083401c6SMatthew G. Knepley 
1171083401c6SMatthew G. Knepley /*@
11723dddbd81SStefano Zampini   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1173249df284SMatthew G. Knepley 
117420f4b53cSBarry Smith   Not Collective
1175249df284SMatthew G. Knepley 
1176249df284SMatthew G. Knepley   Input Parameters:
1177dce8aebaSBarry Smith + prob - The `PetscDS` object
1178249df284SMatthew G. Knepley - f    - The field number
1179249df284SMatthew G. Knepley 
1180249df284SMatthew G. Knepley   Output Parameter:
1181249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1182249df284SMatthew G. Knepley 
1183249df284SMatthew G. Knepley   Level: developer
1184249df284SMatthew G. Knepley 
11853dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1186249df284SMatthew G. Knepley @*/
1187d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1188d71ae5a4SJacob Faibussowitsch {
1189249df284SMatthew G. Knepley   PetscFunctionBegin;
1190249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
11914f572ea9SToby Isaac   PetscAssertPointer(implicit, 3);
119263a3b9bcSJacob 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);
1193249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1195249df284SMatthew G. Knepley }
1196249df284SMatthew G. Knepley 
1197249df284SMatthew G. Knepley /*@
11983dddbd81SStefano Zampini   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1199249df284SMatthew G. Knepley 
120020f4b53cSBarry Smith   Not Collective
1201249df284SMatthew G. Knepley 
1202249df284SMatthew G. Knepley   Input Parameters:
1203dce8aebaSBarry Smith + prob     - The `PetscDS` object
1204249df284SMatthew G. Knepley . f        - The field number
1205249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1206249df284SMatthew G. Knepley 
1207249df284SMatthew G. Knepley   Level: developer
1208249df284SMatthew G. Knepley 
12093dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1210249df284SMatthew G. Knepley @*/
1211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1212d71ae5a4SJacob Faibussowitsch {
1213249df284SMatthew G. Knepley   PetscFunctionBegin;
1214249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
121563a3b9bcSJacob 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);
1216249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1218249df284SMatthew G. Knepley }
1219249df284SMatthew G. Knepley 
1220f9244615SMatthew G. Knepley /*@
1221f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1222f9244615SMatthew G. Knepley 
122320f4b53cSBarry Smith   Not Collective
1224f9244615SMatthew G. Knepley 
1225f9244615SMatthew G. Knepley   Input Parameters:
1226dce8aebaSBarry Smith + ds - The `PetscDS` object
1227f9244615SMatthew G. Knepley - f  - The field number
1228f9244615SMatthew G. Knepley 
1229f9244615SMatthew G. Knepley   Output Parameter:
1230f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1231f9244615SMatthew G. Knepley 
1232f9244615SMatthew G. Knepley   Level: developer
1233f9244615SMatthew G. Knepley 
1234dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1235f9244615SMatthew G. Knepley @*/
1236d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1237d71ae5a4SJacob Faibussowitsch {
1238f9244615SMatthew G. Knepley   PetscFunctionBegin;
1239f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12404f572ea9SToby Isaac   PetscAssertPointer(k, 3);
124163a3b9bcSJacob 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);
1242f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1244f9244615SMatthew G. Knepley }
1245f9244615SMatthew G. Knepley 
1246f9244615SMatthew G. Knepley /*@
1247f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1248f9244615SMatthew G. Knepley 
124920f4b53cSBarry Smith   Not Collective
1250f9244615SMatthew G. Knepley 
1251f9244615SMatthew G. Knepley   Input Parameters:
1252dce8aebaSBarry Smith + ds - The `PetscDS` object
1253f9244615SMatthew G. Knepley . f  - The field number
1254f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1255f9244615SMatthew G. Knepley 
1256f9244615SMatthew G. Knepley   Level: developer
1257f9244615SMatthew G. Knepley 
1258a94f484eSPierre Jolivet .seealso: `PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1259f9244615SMatthew G. Knepley @*/
1260d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1261d71ae5a4SJacob Faibussowitsch {
1262f9244615SMatthew G. Knepley   PetscFunctionBegin;
1263f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
126463a3b9bcSJacob 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);
1265f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1267f9244615SMatthew G. Knepley }
1268f9244615SMatthew G. Knepley 
1269c8943706SMatthew G. Knepley /*@C
1270c8943706SMatthew G. Knepley   PetscDSGetObjective - Get the pointwise objective function for a given test field
1271c8943706SMatthew G. Knepley 
1272c8943706SMatthew G. Knepley   Not Collective
1273c8943706SMatthew G. Knepley 
1274c8943706SMatthew G. Knepley   Input Parameters:
1275c8943706SMatthew G. Knepley + ds - The `PetscDS`
1276c8943706SMatthew G. Knepley - f  - The test field number
1277c8943706SMatthew G. Knepley 
1278a4e35b19SJacob Faibussowitsch   Output Parameter:
1279c8943706SMatthew G. Knepley . obj - integrand for the test function term
1280c8943706SMatthew G. Knepley 
1281c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1282c8943706SMatthew G. Knepley + dim          - the spatial dimension
1283c8943706SMatthew G. Knepley . Nf           - the number of fields
1284a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1285c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1286c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1287c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1288c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1289c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1290c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1291c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1292c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1293c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1294c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1295c8943706SMatthew G. Knepley . t            - current time
1296c8943706SMatthew G. Knepley . x            - coordinates of the current point
1297c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1298c8943706SMatthew G. Knepley . constants    - constant parameters
1299c8943706SMatthew G. Knepley - obj          - output values at the current point
1300c8943706SMatthew G. Knepley 
1301c8943706SMatthew G. Knepley   Level: intermediate
1302c8943706SMatthew G. Knepley 
1303c8943706SMatthew G. Knepley   Note:
1304*1702e181SMatthew 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)$
1305c8943706SMatthew G. Knepley 
1306c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1307c8943706SMatthew G. Knepley @*/
1308d71ae5a4SJacob 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[]))
1309d71ae5a4SJacob Faibussowitsch {
13106528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13116528b96dSMatthew G. Knepley   PetscInt        n;
13126528b96dSMatthew G. Knepley 
13132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13154f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
131663a3b9bcSJacob 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);
13179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13186528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13202764a2aaSMatthew G. Knepley }
13212764a2aaSMatthew G. Knepley 
1322c8943706SMatthew G. Knepley /*@C
1323c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1324c8943706SMatthew G. Knepley 
1325c8943706SMatthew G. Knepley   Not Collective
1326c8943706SMatthew G. Knepley 
1327c8943706SMatthew G. Knepley   Input Parameters:
1328c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1329c8943706SMatthew G. Knepley . f   - The test field number
1330c8943706SMatthew G. Knepley - obj - integrand for the test function term
1331c8943706SMatthew G. Knepley 
1332c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1333c8943706SMatthew G. Knepley + dim          - the spatial dimension
1334c8943706SMatthew G. Knepley . Nf           - the number of fields
1335a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1336c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1337c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1338c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1339c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1340c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1341c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1342c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1343c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1344c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1345c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1346c8943706SMatthew G. Knepley . t            - current time
1347c8943706SMatthew G. Knepley . x            - coordinates of the current point
1348c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1349c8943706SMatthew G. Knepley . constants    - constant parameters
1350c8943706SMatthew G. Knepley - obj          - output values at the current point
1351c8943706SMatthew G. Knepley 
1352c8943706SMatthew G. Knepley   Level: intermediate
1353c8943706SMatthew G. Knepley 
1354c8943706SMatthew G. Knepley   Note:
1355*1702e181SMatthew 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)$
1356c8943706SMatthew G. Knepley 
1357c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1358c8943706SMatthew G. Knepley @*/
1359d71ae5a4SJacob 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[]))
1360d71ae5a4SJacob Faibussowitsch {
13612764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13626528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13636528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
136463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13659566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13672764a2aaSMatthew G. Knepley }
13682764a2aaSMatthew G. Knepley 
1369194d53e6SMatthew G. Knepley /*@C
1370194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1371194d53e6SMatthew G. Knepley 
137220f4b53cSBarry Smith   Not Collective
1373194d53e6SMatthew G. Knepley 
1374194d53e6SMatthew G. Knepley   Input Parameters:
1375dce8aebaSBarry Smith + ds - The `PetscDS`
1376194d53e6SMatthew G. Knepley - f  - The test field number
1377194d53e6SMatthew G. Knepley 
1378194d53e6SMatthew G. Knepley   Output Parameters:
1379194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1380194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1381194d53e6SMatthew G. Knepley 
1382a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1383194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1384194d53e6SMatthew G. Knepley . Nf           - the number of fields
1385a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1386194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1387194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1388194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1389194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1390194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1391194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1392194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1393194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1394194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1395194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1396194d53e6SMatthew G. Knepley . t            - current time
1397194d53e6SMatthew G. Knepley . x            - coordinates of the current point
139897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
139997b6e6e8SMatthew G. Knepley . constants    - constant parameters
1400194d53e6SMatthew G. Knepley - f0           - output values at the current point
1401194d53e6SMatthew G. Knepley 
1402194d53e6SMatthew G. Knepley   Level: intermediate
1403194d53e6SMatthew G. Knepley 
1404dce8aebaSBarry Smith   Note:
1405a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1406a4e35b19SJacob Faibussowitsch 
14071d27aa22SBarry 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)$
1408dce8aebaSBarry Smith 
1409dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1410194d53e6SMatthew G. Knepley @*/
1411a4e35b19SJacob 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[]))
1412d71ae5a4SJacob Faibussowitsch {
14136528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14146528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14156528b96dSMatthew G. Knepley 
14162764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14176528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
141863a3b9bcSJacob 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);
14199566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14206528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14216528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14232764a2aaSMatthew G. Knepley }
14242764a2aaSMatthew G. Knepley 
1425194d53e6SMatthew G. Knepley /*@C
1426194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1427194d53e6SMatthew G. Knepley 
142820f4b53cSBarry Smith   Not Collective
1429194d53e6SMatthew G. Knepley 
1430194d53e6SMatthew G. Knepley   Input Parameters:
1431dce8aebaSBarry Smith + ds - The `PetscDS`
1432194d53e6SMatthew G. Knepley . f  - The test field number
1433194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1434194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1435194d53e6SMatthew G. Knepley 
1436a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1437194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1438194d53e6SMatthew G. Knepley . Nf           - the number of fields
1439a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1440194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1441194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1442194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1443194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1444194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1445194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1446194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1447194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1448194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1449194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1450194d53e6SMatthew G. Knepley . t            - current time
1451194d53e6SMatthew G. Knepley . x            - coordinates of the current point
145297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
145397b6e6e8SMatthew G. Knepley . constants    - constant parameters
1454194d53e6SMatthew G. Knepley - f0           - output values at the current point
1455194d53e6SMatthew G. Knepley 
1456194d53e6SMatthew G. Knepley   Level: intermediate
1457194d53e6SMatthew G. Knepley 
1458dce8aebaSBarry Smith   Note:
1459a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1460a4e35b19SJacob Faibussowitsch 
14611d27aa22SBarry 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)$
1462dce8aebaSBarry Smith 
1463dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1464194d53e6SMatthew G. Knepley @*/
1465a4e35b19SJacob 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[]))
1466d71ae5a4SJacob Faibussowitsch {
14672764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1469f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1470f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
147163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14729566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14742764a2aaSMatthew G. Knepley }
14752764a2aaSMatthew G. Knepley 
14763e75805dSMatthew G. Knepley /*@C
1477cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1478cb36c0f9SMatthew G. Knepley 
147920f4b53cSBarry Smith   Not Collective
1480cb36c0f9SMatthew G. Knepley 
1481cb36c0f9SMatthew G. Knepley   Input Parameters:
1482dce8aebaSBarry Smith + ds - The `PetscDS`
1483cb36c0f9SMatthew G. Knepley - f  - The test field number
1484cb36c0f9SMatthew G. Knepley 
1485cb36c0f9SMatthew G. Knepley   Output Parameters:
1486cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1487cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1488cb36c0f9SMatthew G. Knepley 
1489a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1490cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1491cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1492a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1493cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1494cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1495cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1496cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1497cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1498cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1499cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1500cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1501cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1502cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1503cb36c0f9SMatthew G. Knepley . t            - current time
1504cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1505cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1506cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1507cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1508cb36c0f9SMatthew G. Knepley 
1509cb36c0f9SMatthew G. Knepley   Level: intermediate
1510cb36c0f9SMatthew G. Knepley 
1511dce8aebaSBarry Smith   Note:
1512a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1513a4e35b19SJacob Faibussowitsch 
15141d27aa22SBarry 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)$
1515dce8aebaSBarry Smith 
1516dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1517cb36c0f9SMatthew G. Knepley @*/
1518a4e35b19SJacob 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[]))
1519d71ae5a4SJacob Faibussowitsch {
1520cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1521cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1522cb36c0f9SMatthew G. Knepley 
1523cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1524cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
152563a3b9bcSJacob 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);
15269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1527cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1528cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1530cb36c0f9SMatthew G. Knepley }
1531cb36c0f9SMatthew G. Knepley 
1532cb36c0f9SMatthew G. Knepley /*@C
1533cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1534cb36c0f9SMatthew G. Knepley 
153520f4b53cSBarry Smith   Not Collective
1536cb36c0f9SMatthew G. Knepley 
1537cb36c0f9SMatthew G. Knepley   Input Parameters:
1538dce8aebaSBarry Smith + ds - The `PetscDS`
1539cb36c0f9SMatthew G. Knepley . f  - The test field number
1540cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1541cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1542cb36c0f9SMatthew G. Knepley 
1543a4e35b19SJacob Faibussowitsch   Calling sequence for the callbacks `f0`:
1544cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1545cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1546a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1547cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1548cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1549cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1550cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1551cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1552cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1553cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1554cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1555cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1556cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1557cb36c0f9SMatthew G. Knepley . t            - current time
1558cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1559cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1560cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1561cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1562cb36c0f9SMatthew G. Knepley 
1563cb36c0f9SMatthew G. Knepley   Level: intermediate
1564cb36c0f9SMatthew G. Knepley 
1565dce8aebaSBarry Smith   Note:
1566a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1567a4e35b19SJacob Faibussowitsch 
15681d27aa22SBarry 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)$
1569dce8aebaSBarry Smith 
1570dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1571cb36c0f9SMatthew G. Knepley @*/
1572a4e35b19SJacob 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[]))
1573d71ae5a4SJacob Faibussowitsch {
1574cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1575cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1576cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1577cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
157863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1581cb36c0f9SMatthew G. Knepley }
1582cb36c0f9SMatthew G. Knepley 
1583cc4c1da9SBarry Smith /*@
1584dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15853e75805dSMatthew G. Knepley 
158620f4b53cSBarry Smith   Not Collective
15873e75805dSMatthew G. Knepley 
15883e75805dSMatthew G. Knepley   Input Parameter:
158960225df5SJacob Faibussowitsch . ds - The `PetscDS`
15903e75805dSMatthew G. Knepley 
15913e75805dSMatthew G. Knepley   Output Parameter:
15923e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15933e75805dSMatthew G. Knepley 
15943e75805dSMatthew G. Knepley   Level: intermediate
15953e75805dSMatthew G. Knepley 
1596dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15973e75805dSMatthew G. Knepley @*/
1598d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1599d71ae5a4SJacob Faibussowitsch {
16003e75805dSMatthew G. Knepley   PetscFunctionBegin;
16016528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16043e75805dSMatthew G. Knepley }
16053e75805dSMatthew G. Knepley 
1606194d53e6SMatthew G. Knepley /*@C
1607194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1608194d53e6SMatthew G. Knepley 
160920f4b53cSBarry Smith   Not Collective
1610194d53e6SMatthew G. Knepley 
1611194d53e6SMatthew G. Knepley   Input Parameters:
1612dce8aebaSBarry Smith + ds - The `PetscDS`
1613194d53e6SMatthew G. Knepley . f  - The test field number
1614194d53e6SMatthew G. Knepley - g  - The field number
1615194d53e6SMatthew G. Knepley 
1616194d53e6SMatthew G. Knepley   Output Parameters:
1617194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1618194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1619194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1620194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1621194d53e6SMatthew G. Knepley 
1622a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1623194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1624194d53e6SMatthew G. Knepley . Nf           - the number of fields
1625a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1626194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1627194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1628194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1629194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1630194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1631194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1632194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1633194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1634194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1635194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1636194d53e6SMatthew G. Knepley . t            - current time
16372aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1638194d53e6SMatthew G. Knepley . x            - coordinates of the current point
163997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
164097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1641194d53e6SMatthew G. Knepley - g0           - output values at the current point
1642194d53e6SMatthew G. Knepley 
1643194d53e6SMatthew G. Knepley   Level: intermediate
1644194d53e6SMatthew G. Knepley 
1645dce8aebaSBarry Smith   Note:
1646a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
164760225df5SJacob Faibussowitsch 
1648a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16491d27aa22SBarry Smith 
16501d27aa22SBarry Smith   $$
1651*1702e181SMatthew 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
1652*1702e181SMatthew 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
16531d27aa22SBarry Smith   $$
1654dce8aebaSBarry Smith 
1655dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1656194d53e6SMatthew G. Knepley @*/
1657a4e35b19SJacob 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[]))
1658d71ae5a4SJacob Faibussowitsch {
16596528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16606528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16616528b96dSMatthew G. Knepley 
16622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16636528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
166463a3b9bcSJacob 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);
166563a3b9bcSJacob 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);
16669566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16676528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16686528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16696528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16706528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16722764a2aaSMatthew G. Knepley }
16732764a2aaSMatthew G. Knepley 
1674194d53e6SMatthew G. Knepley /*@C
1675194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1676194d53e6SMatthew G. Knepley 
167720f4b53cSBarry Smith   Not Collective
1678194d53e6SMatthew G. Knepley 
1679194d53e6SMatthew G. Knepley   Input Parameters:
1680dce8aebaSBarry Smith + ds - The `PetscDS`
1681194d53e6SMatthew G. Knepley . f  - The test field number
1682194d53e6SMatthew G. Knepley . g  - The field number
1683194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1684194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1685194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1686194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1687194d53e6SMatthew G. Knepley 
1688a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1689194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1690194d53e6SMatthew G. Knepley . Nf           - the number of fields
1691a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1692194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1693194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1694194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1695194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1696194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1697194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1698194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1699194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1700194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1701194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1702194d53e6SMatthew G. Knepley . t            - current time
17032aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1704194d53e6SMatthew G. Knepley . x            - coordinates of the current point
170597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
170697b6e6e8SMatthew G. Knepley . constants    - constant parameters
1707194d53e6SMatthew G. Knepley - g0           - output values at the current point
1708194d53e6SMatthew G. Knepley 
1709194d53e6SMatthew G. Knepley   Level: intermediate
1710194d53e6SMatthew G. Knepley 
1711dce8aebaSBarry Smith   Note:
1712a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
171360225df5SJacob Faibussowitsch 
1714a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1715*1702e181SMatthew Knepley 
1716*1702e181SMatthew Knepley   $$
1717*1702e181SMatthew 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
1718*1702e181SMatthew 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
1719*1702e181SMatthew Knepley   $$
1720dce8aebaSBarry Smith 
1721dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1722194d53e6SMatthew G. Knepley @*/
1723a4e35b19SJacob 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[]))
1724d71ae5a4SJacob Faibussowitsch {
17252764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17266528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17272764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17282764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17292764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17302764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
173163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
173263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17352764a2aaSMatthew G. Knepley }
17362764a2aaSMatthew G. Knepley 
1737cc4c1da9SBarry Smith /*@
1738dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
173955c1f793SMatthew G. Knepley 
174020f4b53cSBarry Smith   Not Collective
174155c1f793SMatthew G. Knepley 
174255c1f793SMatthew G. Knepley   Input Parameters:
1743dce8aebaSBarry Smith + prob      - The `PetscDS`
174455c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
174555c1f793SMatthew G. Knepley 
174655c1f793SMatthew G. Knepley   Level: intermediate
174755c1f793SMatthew G. Knepley 
1748cc4c1da9SBarry Smith   Developer Note:
1749cc4c1da9SBarry Smith   Should be called `PetscDSSetUseJacobianPreconditioner()`
1750cc4c1da9SBarry Smith 
1751dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
175255c1f793SMatthew G. Knepley @*/
1753d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1754d71ae5a4SJacob Faibussowitsch {
175555c1f793SMatthew G. Knepley   PetscFunctionBegin;
175655c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
175755c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
175955c1f793SMatthew G. Knepley }
176055c1f793SMatthew G. Knepley 
1761cc4c1da9SBarry Smith /*@
1762dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1763475e0ac9SMatthew G. Knepley 
176420f4b53cSBarry Smith   Not Collective
1765475e0ac9SMatthew G. Knepley 
1766475e0ac9SMatthew G. Knepley   Input Parameter:
176760225df5SJacob Faibussowitsch . ds - The `PetscDS`
1768475e0ac9SMatthew G. Knepley 
1769475e0ac9SMatthew G. Knepley   Output Parameter:
1770475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1771475e0ac9SMatthew G. Knepley 
1772475e0ac9SMatthew G. Knepley   Level: intermediate
1773475e0ac9SMatthew G. Knepley 
1774dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1775475e0ac9SMatthew G. Knepley @*/
1776d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1777d71ae5a4SJacob Faibussowitsch {
1778475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1780475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17813ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1784475e0ac9SMatthew G. Knepley }
1785475e0ac9SMatthew G. Knepley 
1786475e0ac9SMatthew G. Knepley /*@C
1787dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1788dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1789475e0ac9SMatthew G. Knepley 
179020f4b53cSBarry Smith   Not Collective
1791475e0ac9SMatthew G. Knepley 
1792475e0ac9SMatthew G. Knepley   Input Parameters:
1793dce8aebaSBarry Smith + ds - The `PetscDS`
1794475e0ac9SMatthew G. Knepley . f  - The test field number
1795475e0ac9SMatthew G. Knepley - g  - The field number
1796475e0ac9SMatthew G. Knepley 
1797475e0ac9SMatthew G. Knepley   Output Parameters:
1798475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1799475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1800475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1801475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1802475e0ac9SMatthew G. Knepley 
1803a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1804475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1805475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1806a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1807475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1808475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1809475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1810475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1811475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1812475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1813475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1814475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1815475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1816475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1817475e0ac9SMatthew G. Knepley . t            - current time
1818475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1819475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
182097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
182197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1822475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1823475e0ac9SMatthew G. Knepley 
1824475e0ac9SMatthew G. Knepley   Level: intermediate
1825475e0ac9SMatthew G. Knepley 
1826dce8aebaSBarry Smith   Note:
1827a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1828a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1829*1702e181SMatthew Knepley 
1830*1702e181SMatthew Knepley   $$
1831*1702e181SMatthew 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
1832*1702e181SMatthew 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
1833*1702e181SMatthew Knepley   $$
1834dce8aebaSBarry Smith 
1835dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1836475e0ac9SMatthew G. Knepley @*/
1837a4e35b19SJacob 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[]))
1838d71ae5a4SJacob Faibussowitsch {
18396528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18406528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18416528b96dSMatthew G. Knepley 
1842475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18436528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
184463a3b9bcSJacob 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);
184563a3b9bcSJacob 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);
18469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18476528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18486528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18496528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18506528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1852475e0ac9SMatthew G. Knepley }
1853475e0ac9SMatthew G. Knepley 
1854475e0ac9SMatthew G. Knepley /*@C
1855dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1856dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1857475e0ac9SMatthew G. Knepley 
185820f4b53cSBarry Smith   Not Collective
1859475e0ac9SMatthew G. Knepley 
1860475e0ac9SMatthew G. Knepley   Input Parameters:
1861dce8aebaSBarry Smith + ds - The `PetscDS`
1862475e0ac9SMatthew G. Knepley . f  - The test field number
1863475e0ac9SMatthew G. Knepley . g  - The field number
1864475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1865475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1866475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1867475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1868475e0ac9SMatthew G. Knepley 
1869a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1870475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1871475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1872a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1873475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1874475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1875475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1876475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1877475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1878475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1879475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1880475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1881475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1882475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1883475e0ac9SMatthew G. Knepley . t            - current time
1884475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1885475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
188697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
188797b6e6e8SMatthew G. Knepley . constants    - constant parameters
1888475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1889475e0ac9SMatthew G. Knepley 
1890475e0ac9SMatthew G. Knepley   Level: intermediate
1891475e0ac9SMatthew G. Knepley 
1892dce8aebaSBarry Smith   Note:
1893a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
189460225df5SJacob Faibussowitsch 
1895a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1896*1702e181SMatthew Knepley 
1897*1702e181SMatthew Knepley   $$
1898*1702e181SMatthew 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
1899*1702e181SMatthew 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
1900*1702e181SMatthew Knepley   $$
1901dce8aebaSBarry Smith 
1902dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1903475e0ac9SMatthew G. Knepley @*/
1904a4e35b19SJacob 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[]))
1905d71ae5a4SJacob Faibussowitsch {
1906475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
19076528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1908475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1909475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1910475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1911475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
191263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
191363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19149566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1916475e0ac9SMatthew G. Knepley }
1917475e0ac9SMatthew G. Knepley 
1918cc4c1da9SBarry Smith /*@
1919b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1920b7e05686SMatthew G. Knepley 
192120f4b53cSBarry Smith   Not Collective
1922b7e05686SMatthew G. Knepley 
1923b7e05686SMatthew G. Knepley   Input Parameter:
1924dce8aebaSBarry Smith . ds - The `PetscDS`
1925b7e05686SMatthew G. Knepley 
1926b7e05686SMatthew G. Knepley   Output Parameter:
1927b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1928b7e05686SMatthew G. Knepley 
1929b7e05686SMatthew G. Knepley   Level: intermediate
1930b7e05686SMatthew G. Knepley 
1931dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1932b7e05686SMatthew G. Knepley @*/
1933d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1934d71ae5a4SJacob Faibussowitsch {
1935b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19366528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19379566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1939b7e05686SMatthew G. Knepley }
1940b7e05686SMatthew G. Knepley 
1941b7e05686SMatthew G. Knepley /*@C
1942b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1943b7e05686SMatthew G. Knepley 
194420f4b53cSBarry Smith   Not Collective
1945b7e05686SMatthew G. Knepley 
1946b7e05686SMatthew G. Knepley   Input Parameters:
1947dce8aebaSBarry Smith + ds - The `PetscDS`
1948b7e05686SMatthew G. Knepley . f  - The test field number
1949b7e05686SMatthew G. Knepley - g  - The field number
1950b7e05686SMatthew G. Knepley 
1951b7e05686SMatthew G. Knepley   Output Parameters:
1952b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1953b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1954b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1955b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1956b7e05686SMatthew G. Knepley 
1957a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1958b7e05686SMatthew G. Knepley + dim          - the spatial dimension
1959b7e05686SMatthew G. Knepley . Nf           - the number of fields
1960a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1961b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1962b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1963b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1964b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1965b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1966b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1967b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1968b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1969b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1970b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1971b7e05686SMatthew G. Knepley . t            - current time
1972b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1973b7e05686SMatthew G. Knepley . x            - coordinates of the current point
197497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
197597b6e6e8SMatthew G. Knepley . constants    - constant parameters
1976b7e05686SMatthew G. Knepley - g0           - output values at the current point
1977b7e05686SMatthew G. Knepley 
1978b7e05686SMatthew G. Knepley   Level: intermediate
1979b7e05686SMatthew G. Knepley 
1980dce8aebaSBarry Smith   Note:
1981a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
198260225df5SJacob Faibussowitsch 
1983a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1984*1702e181SMatthew Knepley 
1985*1702e181SMatthew Knepley   $$
1986*1702e181SMatthew 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
1987*1702e181SMatthew 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
1988*1702e181SMatthew Knepley   $$
1989dce8aebaSBarry Smith 
1990dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1991b7e05686SMatthew G. Knepley @*/
1992a4e35b19SJacob 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[]))
1993d71ae5a4SJacob Faibussowitsch {
19946528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19956528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19966528b96dSMatthew G. Knepley 
1997b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19986528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
199963a3b9bcSJacob 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);
200063a3b9bcSJacob 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);
20019566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
20026528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
20036528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
20046528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
20056528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
20063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2007b7e05686SMatthew G. Knepley }
2008b7e05686SMatthew G. Knepley 
2009b7e05686SMatthew G. Knepley /*@C
2010b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
2011b7e05686SMatthew G. Knepley 
201220f4b53cSBarry Smith   Not Collective
2013b7e05686SMatthew G. Knepley 
2014b7e05686SMatthew G. Knepley   Input Parameters:
2015dce8aebaSBarry Smith + ds - The `PetscDS`
2016b7e05686SMatthew G. Knepley . f  - The test field number
2017b7e05686SMatthew G. Knepley . g  - The field number
2018b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2019b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2020b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2021b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2022b7e05686SMatthew G. Knepley 
2023a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2024b7e05686SMatthew G. Knepley + dim          - the spatial dimension
2025b7e05686SMatthew G. Knepley . Nf           - the number of fields
2026a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2027b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2028b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2029b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2030b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2031b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2032b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2033b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2034b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2035b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2036b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2037b7e05686SMatthew G. Knepley . t            - current time
2038b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2039b7e05686SMatthew G. Knepley . x            - coordinates of the current point
204097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
204197b6e6e8SMatthew G. Knepley . constants    - constant parameters
2042b7e05686SMatthew G. Knepley - g0           - output values at the current point
2043b7e05686SMatthew G. Knepley 
2044b7e05686SMatthew G. Knepley   Level: intermediate
2045b7e05686SMatthew G. Knepley 
2046dce8aebaSBarry Smith   Note:
2047a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
204860225df5SJacob Faibussowitsch 
2049a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2050*1702e181SMatthew Knepley 
2051*1702e181SMatthew Knepley   $$
2052*1702e181SMatthew 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
2053*1702e181SMatthew 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
2054*1702e181SMatthew Knepley   $$
2055dce8aebaSBarry Smith 
2056dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2057b7e05686SMatthew G. Knepley @*/
2058a4e35b19SJacob 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[]))
2059d71ae5a4SJacob Faibussowitsch {
2060b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20616528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2062b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2063b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2064b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2065b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
206663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
206763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2070b7e05686SMatthew G. Knepley }
2071b7e05686SMatthew G. Knepley 
20720c2f2876SMatthew G. Knepley /*@C
20730c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20740c2f2876SMatthew G. Knepley 
207520f4b53cSBarry Smith   Not Collective
20760c2f2876SMatthew G. Knepley 
20774165533cSJose E. Roman   Input Parameters:
2078dce8aebaSBarry Smith + ds - The `PetscDS` object
20790c2f2876SMatthew G. Knepley - f  - The field number
20800c2f2876SMatthew G. Knepley 
20814165533cSJose E. Roman   Output Parameter:
20820c2f2876SMatthew G. Knepley . r - Riemann solver
20830c2f2876SMatthew G. Knepley 
208420f4b53cSBarry Smith   Calling sequence of `r`:
20855db36cf9SMatthew G. Knepley + dim          - The spatial dimension
20865db36cf9SMatthew G. Knepley . Nf           - The number of fields
20875db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
20880c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
20890c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
20900c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
20910c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
209297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
209397b6e6e8SMatthew G. Knepley . constants    - constant parameters
20940c2f2876SMatthew G. Knepley - ctx          - optional user context
20950c2f2876SMatthew G. Knepley 
20960c2f2876SMatthew G. Knepley   Level: intermediate
20970c2f2876SMatthew G. Knepley 
2098dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20990c2f2876SMatthew G. Knepley @*/
2100d71ae5a4SJacob 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))
2101d71ae5a4SJacob Faibussowitsch {
21026528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
21036528b96dSMatthew G. Knepley   PetscInt          n;
21046528b96dSMatthew G. Knepley 
21050c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21066528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21074f572ea9SToby Isaac   PetscAssertPointer(r, 3);
210863a3b9bcSJacob 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);
21099566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
21106528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
21113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21120c2f2876SMatthew G. Knepley }
21130c2f2876SMatthew G. Knepley 
21140c2f2876SMatthew G. Knepley /*@C
21150c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
21160c2f2876SMatthew G. Knepley 
211720f4b53cSBarry Smith   Not Collective
21180c2f2876SMatthew G. Knepley 
21194165533cSJose E. Roman   Input Parameters:
2120dce8aebaSBarry Smith + ds - The `PetscDS` object
21210c2f2876SMatthew G. Knepley . f  - The field number
21220c2f2876SMatthew G. Knepley - r  - Riemann solver
21230c2f2876SMatthew G. Knepley 
212420f4b53cSBarry Smith   Calling sequence of `r`:
21255db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21265db36cf9SMatthew G. Knepley . Nf           - The number of fields
21275db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21280c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21290c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21300c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21310c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
213297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
213397b6e6e8SMatthew G. Knepley . constants    - constant parameters
21340c2f2876SMatthew G. Knepley - ctx          - optional user context
21350c2f2876SMatthew G. Knepley 
21360c2f2876SMatthew G. Knepley   Level: intermediate
21370c2f2876SMatthew G. Knepley 
2138dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21390c2f2876SMatthew G. Knepley @*/
2140d71ae5a4SJacob 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))
2141d71ae5a4SJacob Faibussowitsch {
21420c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21436528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2144de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
214563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21480c2f2876SMatthew G. Knepley }
21490c2f2876SMatthew G. Knepley 
215032d2bbc9SMatthew G. Knepley /*@C
215132d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
215232d2bbc9SMatthew G. Knepley 
215320f4b53cSBarry Smith   Not Collective
215432d2bbc9SMatthew G. Knepley 
215532d2bbc9SMatthew G. Knepley   Input Parameters:
2156dce8aebaSBarry Smith + ds - The `PetscDS`
215732d2bbc9SMatthew G. Knepley - f  - The field number
215832d2bbc9SMatthew G. Knepley 
2159f899ff85SJose E. Roman   Output Parameter:
2160a2b725a8SWilliam Gropp . update - update function
216132d2bbc9SMatthew G. Knepley 
216220f4b53cSBarry Smith   Calling sequence of `update`:
216332d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
216432d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2165a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
216632d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
216732d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
216832d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
216932d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
217032d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
217132d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
217232d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
217332d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
217432d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
217532d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
217632d2bbc9SMatthew G. Knepley . t            - current time
217732d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2178a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2179a4e35b19SJacob Faibussowitsch . constants    - constant parameters
218032d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
218132d2bbc9SMatthew G. Knepley 
218232d2bbc9SMatthew G. Knepley   Level: intermediate
218332d2bbc9SMatthew G. Knepley 
2184dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
218532d2bbc9SMatthew G. Knepley @*/
2186d71ae5a4SJacob 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[]))
2187d71ae5a4SJacob Faibussowitsch {
218832d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
219063a3b9bcSJacob 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);
21919371c9d4SSatish Balay   if (update) {
21924f572ea9SToby Isaac     PetscAssertPointer(update, 3);
21939371c9d4SSatish Balay     *update = ds->update[f];
21949371c9d4SSatish Balay   }
21953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
219632d2bbc9SMatthew G. Knepley }
219732d2bbc9SMatthew G. Knepley 
219832d2bbc9SMatthew G. Knepley /*@C
21993fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
220032d2bbc9SMatthew G. Knepley 
220120f4b53cSBarry Smith   Not Collective
220232d2bbc9SMatthew G. Knepley 
220332d2bbc9SMatthew G. Knepley   Input Parameters:
2204dce8aebaSBarry Smith + ds     - The `PetscDS`
220532d2bbc9SMatthew G. Knepley . f      - The field number
220632d2bbc9SMatthew G. Knepley - update - update function
220732d2bbc9SMatthew G. Knepley 
220820f4b53cSBarry Smith   Calling sequence of `update`:
220932d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
221032d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2211a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
221232d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
221332d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
221432d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
221532d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
221632d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
221732d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
221832d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
221932d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
222032d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
222132d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
222232d2bbc9SMatthew G. Knepley . t            - current time
222332d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2224a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2225a4e35b19SJacob Faibussowitsch . constants    - constant parameters
222632d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
222732d2bbc9SMatthew G. Knepley 
222832d2bbc9SMatthew G. Knepley   Level: intermediate
222932d2bbc9SMatthew G. Knepley 
2230dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
223132d2bbc9SMatthew G. Knepley @*/
2232d71ae5a4SJacob 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[]))
2233d71ae5a4SJacob Faibussowitsch {
223432d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22356528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223632d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
223763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22389566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22396528b96dSMatthew G. Knepley   ds->update[f] = update;
22403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
224132d2bbc9SMatthew G. Knepley }
224232d2bbc9SMatthew G. Knepley 
2243d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2244d71ae5a4SJacob Faibussowitsch {
22450c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22466528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
224763a3b9bcSJacob 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);
22484f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22493ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22510c2f2876SMatthew G. Knepley }
22520c2f2876SMatthew G. Knepley 
2253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2254d71ae5a4SJacob Faibussowitsch {
22550c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22566528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22589566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22596528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22610c2f2876SMatthew G. Knepley }
22620c2f2876SMatthew G. Knepley 
2263194d53e6SMatthew G. Knepley /*@C
2264194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2265194d53e6SMatthew G. Knepley 
226620f4b53cSBarry Smith   Not Collective
2267194d53e6SMatthew G. Knepley 
2268194d53e6SMatthew G. Knepley   Input Parameters:
22696528b96dSMatthew G. Knepley + ds - The PetscDS
2270194d53e6SMatthew G. Knepley - f  - The test field number
2271194d53e6SMatthew G. Knepley 
2272194d53e6SMatthew G. Knepley   Output Parameters:
2273194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2274194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2275194d53e6SMatthew G. Knepley 
2276a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2277194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2278194d53e6SMatthew G. Knepley . Nf           - the number of fields
2279a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2280194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2281194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2282194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2283194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2284194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2285194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2286194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2287194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2288194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2289194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2290194d53e6SMatthew G. Knepley . t            - current time
2291194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2292194d53e6SMatthew G. Knepley . n            - unit normal at the current point
229397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
229497b6e6e8SMatthew G. Knepley . constants    - constant parameters
2295194d53e6SMatthew G. Knepley - f0           - output values at the current point
2296194d53e6SMatthew G. Knepley 
2297194d53e6SMatthew G. Knepley   Level: intermediate
2298194d53e6SMatthew G. Knepley 
2299dce8aebaSBarry Smith   Note:
2300a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
230160225df5SJacob Faibussowitsch 
2302a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2303*1702e181SMatthew Knepley 
2304*1702e181SMatthew Knepley   $$
2305dce8aebaSBarry 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
2306*1702e181SMatthew Knepley   $$
2307dce8aebaSBarry Smith 
2308dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2309194d53e6SMatthew G. Knepley @*/
2310a4e35b19SJacob 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[]))
2311d71ae5a4SJacob Faibussowitsch {
23126528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
23136528b96dSMatthew G. Knepley   PetscInt          n0, n1;
23146528b96dSMatthew G. Knepley 
23152764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
231763a3b9bcSJacob 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);
23189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
23196528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
23206528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
23213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23222764a2aaSMatthew G. Knepley }
23232764a2aaSMatthew G. Knepley 
2324194d53e6SMatthew G. Knepley /*@C
2325194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2326194d53e6SMatthew G. Knepley 
232720f4b53cSBarry Smith   Not Collective
2328194d53e6SMatthew G. Knepley 
2329194d53e6SMatthew G. Knepley   Input Parameters:
2330dce8aebaSBarry Smith + ds - The `PetscDS`
2331194d53e6SMatthew G. Knepley . f  - The test field number
2332194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2333194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2334194d53e6SMatthew G. Knepley 
2335a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2336194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2337194d53e6SMatthew G. Knepley . Nf           - the number of fields
2338a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2339194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2340194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2341194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2342194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2343194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2344194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2345194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2346194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2347194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2348194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2349194d53e6SMatthew G. Knepley . t            - current time
2350194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2351194d53e6SMatthew G. Knepley . n            - unit normal at the current point
235297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
235397b6e6e8SMatthew G. Knepley . constants    - constant parameters
2354194d53e6SMatthew G. Knepley - f0           - output values at the current point
2355194d53e6SMatthew G. Knepley 
2356194d53e6SMatthew G. Knepley   Level: intermediate
2357194d53e6SMatthew G. Knepley 
2358dce8aebaSBarry Smith   Note:
2359a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
236060225df5SJacob Faibussowitsch 
2361a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2362*1702e181SMatthew Knepley 
2363*1702e181SMatthew Knepley   $$
2364dce8aebaSBarry 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
2365*1702e181SMatthew Knepley   $$
2366dce8aebaSBarry Smith 
2367dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2368194d53e6SMatthew G. Knepley @*/
2369a4e35b19SJacob 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[]))
2370d71ae5a4SJacob Faibussowitsch {
23712764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23726528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
237363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23749566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23762764a2aaSMatthew G. Knepley }
23772764a2aaSMatthew G. Knepley 
237827f02ce8SMatthew G. Knepley /*@
2379dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
238027f02ce8SMatthew G. Knepley 
238120f4b53cSBarry Smith   Not Collective
238227f02ce8SMatthew G. Knepley 
238327f02ce8SMatthew G. Knepley   Input Parameter:
2384dce8aebaSBarry Smith . ds - The `PetscDS`
238527f02ce8SMatthew G. Knepley 
238627f02ce8SMatthew G. Knepley   Output Parameter:
238727f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
238827f02ce8SMatthew G. Knepley 
238927f02ce8SMatthew G. Knepley   Level: intermediate
239027f02ce8SMatthew G. Knepley 
2391dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
239227f02ce8SMatthew G. Knepley @*/
2393d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2394d71ae5a4SJacob Faibussowitsch {
239527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23974f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
23989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
240027f02ce8SMatthew G. Knepley }
240127f02ce8SMatthew G. Knepley 
2402194d53e6SMatthew G. Knepley /*@C
2403194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2404194d53e6SMatthew G. Knepley 
240520f4b53cSBarry Smith   Not Collective
2406194d53e6SMatthew G. Knepley 
2407194d53e6SMatthew G. Knepley   Input Parameters:
2408dce8aebaSBarry Smith + ds - The `PetscDS`
2409194d53e6SMatthew G. Knepley . f  - The test field number
2410194d53e6SMatthew G. Knepley - g  - The field number
2411194d53e6SMatthew G. Knepley 
2412194d53e6SMatthew G. Knepley   Output Parameters:
2413194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2414194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2415194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2416194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2417194d53e6SMatthew G. Knepley 
2418a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2419194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2420194d53e6SMatthew G. Knepley . Nf           - the number of fields
2421a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2422194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2423194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2424194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2425194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2426194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2427194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2428194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2429194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2430194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2431194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2432194d53e6SMatthew G. Knepley . t            - current time
24332aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2434194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2435194d53e6SMatthew G. Knepley . n            - normal at the current point
243697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
243797b6e6e8SMatthew G. Knepley . constants    - constant parameters
2438194d53e6SMatthew G. Knepley - g0           - output values at the current point
2439194d53e6SMatthew G. Knepley 
2440194d53e6SMatthew G. Knepley   Level: intermediate
2441194d53e6SMatthew G. Knepley 
2442dce8aebaSBarry Smith   Note:
2443a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
244460225df5SJacob Faibussowitsch 
2445a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2446*1702e181SMatthew Knepley 
2447*1702e181SMatthew Knepley   $$
2448*1702e181SMatthew 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
2449*1702e181SMatthew 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
2450*1702e181SMatthew Knepley   $$
2451dce8aebaSBarry Smith 
2452dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2453194d53e6SMatthew G. Knepley @*/
2454a4e35b19SJacob 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[]))
2455d71ae5a4SJacob Faibussowitsch {
24566528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24576528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24586528b96dSMatthew G. Knepley 
24592764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24606528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
246163a3b9bcSJacob 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);
246263a3b9bcSJacob 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);
24639566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24646528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24656528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24666528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24676528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24692764a2aaSMatthew G. Knepley }
24702764a2aaSMatthew G. Knepley 
2471194d53e6SMatthew G. Knepley /*@C
2472194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2473194d53e6SMatthew G. Knepley 
247420f4b53cSBarry Smith   Not Collective
2475194d53e6SMatthew G. Knepley 
2476194d53e6SMatthew G. Knepley   Input Parameters:
24776528b96dSMatthew G. Knepley + ds - The PetscDS
2478194d53e6SMatthew G. Knepley . f  - The test field number
2479194d53e6SMatthew G. Knepley . g  - The field number
2480194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2481194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2482194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2483194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2484194d53e6SMatthew G. Knepley 
2485a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2486194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2487194d53e6SMatthew G. Knepley . Nf           - the number of fields
2488a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2489194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2490194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2491194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2492194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2493194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2494194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2495194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2496194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2497194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2498194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2499194d53e6SMatthew G. Knepley . t            - current time
25002aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2501194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2502194d53e6SMatthew G. Knepley . n            - normal at the current point
250397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
250497b6e6e8SMatthew G. Knepley . constants    - constant parameters
2505194d53e6SMatthew G. Knepley - g0           - output values at the current point
2506194d53e6SMatthew G. Knepley 
2507194d53e6SMatthew G. Knepley   Level: intermediate
2508194d53e6SMatthew G. Knepley 
2509dce8aebaSBarry Smith   Note:
2510a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
251160225df5SJacob Faibussowitsch 
2512a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2513*1702e181SMatthew Knepley 
2514*1702e181SMatthew Knepley   $$
2515*1702e181SMatthew 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
2516*1702e181SMatthew 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
2517*1702e181SMatthew Knepley   $$
2518dce8aebaSBarry Smith 
2519dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2520194d53e6SMatthew G. Knepley @*/
2521a4e35b19SJacob 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[]))
2522d71ae5a4SJacob Faibussowitsch {
25232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
25246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25252764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
25262764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
25272764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
25282764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
252963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
253063a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
25319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
25323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25332764a2aaSMatthew G. Knepley }
25342764a2aaSMatthew G. Knepley 
253527f02ce8SMatthew G. Knepley /*@
253627f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
253727f02ce8SMatthew G. Knepley 
253820f4b53cSBarry Smith   Not Collective
253927f02ce8SMatthew G. Knepley 
254027f02ce8SMatthew G. Knepley   Input Parameter:
2541dce8aebaSBarry Smith . ds - The `PetscDS`
254227f02ce8SMatthew G. Knepley 
254327f02ce8SMatthew G. Knepley   Output Parameter:
254460225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
254527f02ce8SMatthew G. Knepley 
254627f02ce8SMatthew G. Knepley   Level: intermediate
254727f02ce8SMatthew G. Knepley 
2548dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
254927f02ce8SMatthew G. Knepley @*/
2550d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2551d71ae5a4SJacob Faibussowitsch {
255227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25544f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25559566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
255727f02ce8SMatthew G. Knepley }
255827f02ce8SMatthew G. Knepley 
255927f02ce8SMatthew G. Knepley /*@C
256027f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
256127f02ce8SMatthew G. Knepley 
256220f4b53cSBarry Smith   Not Collective; No Fortran Support
256327f02ce8SMatthew G. Knepley 
256427f02ce8SMatthew G. Knepley   Input Parameters:
2565dce8aebaSBarry Smith + ds - The `PetscDS`
256627f02ce8SMatthew G. Knepley . f  - The test field number
256727f02ce8SMatthew G. Knepley - g  - The field number
256827f02ce8SMatthew G. Knepley 
256927f02ce8SMatthew G. Knepley   Output Parameters:
257027f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
257127f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
257227f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
257327f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
257427f02ce8SMatthew G. Knepley 
2575a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
257627f02ce8SMatthew G. Knepley + dim          - the spatial dimension
257727f02ce8SMatthew G. Knepley . Nf           - the number of fields
257827f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
257927f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
258027f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
258127f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
258227f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
258327f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
258427f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
258527f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
258627f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
258727f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
258827f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
258927f02ce8SMatthew G. Knepley . t            - current time
259027f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
259127f02ce8SMatthew G. Knepley . x            - coordinates of the current point
259227f02ce8SMatthew G. Knepley . n            - normal at the current point
259327f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
259427f02ce8SMatthew G. Knepley . constants    - constant parameters
259527f02ce8SMatthew G. Knepley - g0           - output values at the current point
259627f02ce8SMatthew G. Knepley 
259727f02ce8SMatthew G. Knepley   Level: intermediate
259827f02ce8SMatthew G. Knepley 
2599dce8aebaSBarry Smith   Note:
2600a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
260160225df5SJacob Faibussowitsch 
2602a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2603*1702e181SMatthew Knepley 
2604*1702e181SMatthew Knepley   $$
2605*1702e181SMatthew 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
2606*1702e181SMatthew 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
2607*1702e181SMatthew Knepley   $$
2608dce8aebaSBarry Smith 
2609dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
261027f02ce8SMatthew G. Knepley @*/
2611a4e35b19SJacob 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[]))
2612d71ae5a4SJacob Faibussowitsch {
26136528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
26146528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
26156528b96dSMatthew G. Knepley 
261627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26176528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
261863a3b9bcSJacob 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);
261963a3b9bcSJacob 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);
26209566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
26216528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
26226528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
26236528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
26246528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
26253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262627f02ce8SMatthew G. Knepley }
262727f02ce8SMatthew G. Knepley 
262827f02ce8SMatthew G. Knepley /*@C
262927f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
263027f02ce8SMatthew G. Knepley 
263120f4b53cSBarry Smith   Not Collective; No Fortran Support
263227f02ce8SMatthew G. Knepley 
263327f02ce8SMatthew G. Knepley   Input Parameters:
2634dce8aebaSBarry Smith + ds - The `PetscDS`
263527f02ce8SMatthew G. Knepley . f  - The test field number
263627f02ce8SMatthew G. Knepley . g  - The field number
263727f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
263827f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
263927f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
264027f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
264127f02ce8SMatthew G. Knepley 
2642a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
264327f02ce8SMatthew G. Knepley + dim          - the spatial dimension
264427f02ce8SMatthew G. Knepley . Nf           - the number of fields
264527f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
264627f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
264727f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
264827f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
264927f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
265027f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
265127f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
265227f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
265327f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
265427f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
265527f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
265627f02ce8SMatthew G. Knepley . t            - current time
265727f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
265827f02ce8SMatthew G. Knepley . x            - coordinates of the current point
265927f02ce8SMatthew G. Knepley . n            - normal at the current point
266027f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
266127f02ce8SMatthew G. Knepley . constants    - constant parameters
266227f02ce8SMatthew G. Knepley - g0           - output values at the current point
266327f02ce8SMatthew G. Knepley 
266427f02ce8SMatthew G. Knepley   Level: intermediate
266527f02ce8SMatthew G. Knepley 
2666dce8aebaSBarry Smith   Note:
2667a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
266860225df5SJacob Faibussowitsch 
2669a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2670*1702e181SMatthew Knepley 
2671*1702e181SMatthew Knepley   $$
2672*1702e181SMatthew 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
2673*1702e181SMatthew 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
2674*1702e181SMatthew Knepley   $$
2675dce8aebaSBarry Smith 
2676dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
267727f02ce8SMatthew G. Knepley @*/
2678a4e35b19SJacob 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[]))
2679d71ae5a4SJacob Faibussowitsch {
268027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26816528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
268227f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
268327f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
268427f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
268527f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
268663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
268763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26889566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
269027f02ce8SMatthew G. Knepley }
269127f02ce8SMatthew G. Knepley 
26920d3e9b51SMatthew G. Knepley /*@C
2693c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2694c371a6d1SMatthew G. Knepley 
269520f4b53cSBarry Smith   Not Collective
2696c371a6d1SMatthew G. Knepley 
2697c371a6d1SMatthew G. Knepley   Input Parameters:
2698c371a6d1SMatthew G. Knepley + prob - The PetscDS
2699c371a6d1SMatthew G. Knepley - f    - The test field number
2700c371a6d1SMatthew G. Knepley 
2701d8d19677SJose E. Roman   Output Parameters:
2702a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2703a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2704c371a6d1SMatthew G. Knepley 
270520f4b53cSBarry Smith   Calling sequence of `exactSol`:
2706c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2707c371a6d1SMatthew G. Knepley . t   - current time
2708c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2709c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2710a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2711c371a6d1SMatthew G. Knepley - ctx - a user context
2712c371a6d1SMatthew G. Knepley 
2713c371a6d1SMatthew G. Knepley   Level: intermediate
2714c371a6d1SMatthew G. Knepley 
2715dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2716c371a6d1SMatthew G. Knepley @*/
2717d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2718d71ae5a4SJacob Faibussowitsch {
2719c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2720c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
272163a3b9bcSJacob 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);
27229371c9d4SSatish Balay   if (sol) {
27234f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27249371c9d4SSatish Balay     *sol = prob->exactSol[f];
27259371c9d4SSatish Balay   }
27269371c9d4SSatish Balay   if (ctx) {
27274f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27289371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
27299371c9d4SSatish Balay   }
27303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2731c371a6d1SMatthew G. Knepley }
2732c371a6d1SMatthew G. Knepley 
2733c371a6d1SMatthew G. Knepley /*@C
2734578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2735c371a6d1SMatthew G. Knepley 
273620f4b53cSBarry Smith   Not Collective
2737c371a6d1SMatthew G. Knepley 
2738c371a6d1SMatthew G. Knepley   Input Parameters:
2739dce8aebaSBarry Smith + prob - The `PetscDS`
2740c371a6d1SMatthew G. Knepley . f    - The test field number
274195cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
274220f4b53cSBarry Smith - ctx  - solution context or `NULL`
2743c371a6d1SMatthew G. Knepley 
274420f4b53cSBarry Smith   Calling sequence of `sol`:
2745c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2746c371a6d1SMatthew G. Knepley . t   - current time
2747c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2748c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2749c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2750c371a6d1SMatthew G. Knepley - ctx - a user context
2751c371a6d1SMatthew G. Knepley 
2752c371a6d1SMatthew G. Knepley   Level: intermediate
2753c371a6d1SMatthew G. Knepley 
2754dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2755c371a6d1SMatthew G. Knepley @*/
2756d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2757d71ae5a4SJacob Faibussowitsch {
2758c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2759c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
276063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27619566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27629371c9d4SSatish Balay   if (sol) {
27639371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27649371c9d4SSatish Balay     prob->exactSol[f] = sol;
27659371c9d4SSatish Balay   }
27669371c9d4SSatish Balay   if (ctx) {
27679371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27689371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27699371c9d4SSatish Balay   }
27703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2771c371a6d1SMatthew G. Knepley }
2772c371a6d1SMatthew G. Knepley 
27735638fd0eSMatthew G. Knepley /*@C
2774f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2775f2cacb80SMatthew G. Knepley 
277620f4b53cSBarry Smith   Not Collective
2777f2cacb80SMatthew G. Knepley 
2778f2cacb80SMatthew G. Knepley   Input Parameters:
2779dce8aebaSBarry Smith + prob - The `PetscDS`
2780f2cacb80SMatthew G. Knepley - f    - The test field number
2781f2cacb80SMatthew G. Knepley 
2782d8d19677SJose E. Roman   Output Parameters:
2783a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2784a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2785f2cacb80SMatthew G. Knepley 
278620f4b53cSBarry Smith   Calling sequence of `exactSol`:
2787f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2788f2cacb80SMatthew G. Knepley . t   - current time
2789f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2790f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2791a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2792f2cacb80SMatthew G. Knepley - ctx - a user context
2793f2cacb80SMatthew G. Knepley 
2794f2cacb80SMatthew G. Knepley   Level: intermediate
2795f2cacb80SMatthew G. Knepley 
2796dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2797f2cacb80SMatthew G. Knepley @*/
2798d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2799d71ae5a4SJacob Faibussowitsch {
2800f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2801f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
280263a3b9bcSJacob 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);
28039371c9d4SSatish Balay   if (sol) {
28044f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
28059371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
28069371c9d4SSatish Balay   }
28079371c9d4SSatish Balay   if (ctx) {
28084f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
28099371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
28109371c9d4SSatish Balay   }
28113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2812f2cacb80SMatthew G. Knepley }
2813f2cacb80SMatthew G. Knepley 
2814f2cacb80SMatthew G. Knepley /*@C
2815f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2816f2cacb80SMatthew G. Knepley 
281720f4b53cSBarry Smith   Not Collective
2818f2cacb80SMatthew G. Knepley 
2819f2cacb80SMatthew G. Knepley   Input Parameters:
2820dce8aebaSBarry Smith + prob - The `PetscDS`
2821f2cacb80SMatthew G. Knepley . f    - The test field number
2822f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
282320f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2824f2cacb80SMatthew G. Knepley 
282520f4b53cSBarry Smith   Calling sequence of `sol`:
2826f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2827f2cacb80SMatthew G. Knepley . t   - current time
2828f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2829f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2830f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2831f2cacb80SMatthew G. Knepley - ctx - a user context
2832f2cacb80SMatthew G. Knepley 
2833f2cacb80SMatthew G. Knepley   Level: intermediate
2834f2cacb80SMatthew G. Knepley 
2835dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2836f2cacb80SMatthew G. Knepley @*/
2837d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2838d71ae5a4SJacob Faibussowitsch {
2839f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2840f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
284163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28429566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28439371c9d4SSatish Balay   if (sol) {
28449371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28459371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28469371c9d4SSatish Balay   }
28479371c9d4SSatish Balay   if (ctx) {
28489371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28499371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28509371c9d4SSatish Balay   }
28513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2852f2cacb80SMatthew G. Knepley }
2853f2cacb80SMatthew G. Knepley 
2854f2cacb80SMatthew G. Knepley /*@C
285597b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
285697b6e6e8SMatthew G. Knepley 
285720f4b53cSBarry Smith   Not Collective
285897b6e6e8SMatthew G. Knepley 
285997b6e6e8SMatthew G. Knepley   Input Parameter:
2860a102dd69SStefano Zampini . ds - The `PetscDS` object
286197b6e6e8SMatthew G. Knepley 
286297b6e6e8SMatthew G. Knepley   Output Parameters:
286397b6e6e8SMatthew G. Knepley + numConstants - The number of constants
286497b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
286597b6e6e8SMatthew G. Knepley 
286697b6e6e8SMatthew G. Knepley   Level: intermediate
286797b6e6e8SMatthew G. Knepley 
2868dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
286997b6e6e8SMatthew G. Knepley @*/
2870a102dd69SStefano Zampini PetscErrorCode PetscDSGetConstants(PetscDS ds, PetscInt *numConstants, const PetscScalar *constants[])
2871d71ae5a4SJacob Faibussowitsch {
287297b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
2873a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
28749371c9d4SSatish Balay   if (numConstants) {
28754f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
2876a102dd69SStefano Zampini     *numConstants = ds->numConstants;
28779371c9d4SSatish Balay   }
28789371c9d4SSatish Balay   if (constants) {
28794f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
2880a102dd69SStefano Zampini     *constants = ds->constants;
28819371c9d4SSatish Balay   }
28823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
288397b6e6e8SMatthew G. Knepley }
288497b6e6e8SMatthew G. Knepley 
28850d3e9b51SMatthew G. Knepley /*@C
288697b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
288797b6e6e8SMatthew G. Knepley 
288820f4b53cSBarry Smith   Not Collective
288997b6e6e8SMatthew G. Knepley 
289097b6e6e8SMatthew G. Knepley   Input Parameters:
2891a102dd69SStefano Zampini + ds           - The `PetscDS` object
289297b6e6e8SMatthew G. Knepley . numConstants - The number of constants
2893a3b724e8SBarry Smith - constants    - The array of constants, `NULL` if there are none
289497b6e6e8SMatthew G. Knepley 
289597b6e6e8SMatthew G. Knepley   Level: intermediate
289697b6e6e8SMatthew G. Knepley 
2897dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
289897b6e6e8SMatthew G. Knepley @*/
2899a102dd69SStefano Zampini PetscErrorCode PetscDSSetConstants(PetscDS ds, PetscInt numConstants, PetscScalar constants[])
2900d71ae5a4SJacob Faibussowitsch {
290197b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
2902a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2903a102dd69SStefano Zampini   if (numConstants != ds->numConstants) {
2904a102dd69SStefano Zampini     PetscCall(PetscFree(ds->constants));
2905a102dd69SStefano Zampini     ds->numConstants = numConstants;
2906a102dd69SStefano Zampini     PetscCall(PetscMalloc1(ds->numConstants + ds->numFuncConstants, &ds->constants));
290720be0f5bSMatthew G. Knepley   }
2908a102dd69SStefano Zampini   if (ds->numConstants) {
29094f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
2910a102dd69SStefano Zampini     PetscCall(PetscArraycpy(ds->constants, constants, ds->numConstants));
291197b6e6e8SMatthew G. Knepley   }
29123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
291397b6e6e8SMatthew G. Knepley }
291497b6e6e8SMatthew G. Knepley 
2915a102dd69SStefano Zampini /*@C
2916a102dd69SStefano Zampini   PetscDSSetIntegrationParameters - Set the parameters for a particular integration
2917a102dd69SStefano Zampini 
2918a102dd69SStefano Zampini   Not Collective
2919a102dd69SStefano Zampini 
2920a102dd69SStefano Zampini   Input Parameters:
2921a102dd69SStefano Zampini + ds     - The `PetscDS` object
2922a102dd69SStefano Zampini . fieldI - The test field for a given point function, or PETSC_DETERMINE
2923a102dd69SStefano Zampini - fieldJ - The basis field for a given point function, or PETSC_DETERMINE
2924a102dd69SStefano Zampini 
2925a102dd69SStefano Zampini   Level: intermediate
2926a102dd69SStefano Zampini 
2927a102dd69SStefano Zampini .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
2928a102dd69SStefano Zampini @*/
2929a102dd69SStefano Zampini PetscErrorCode PetscDSSetIntegrationParameters(PetscDS ds, PetscInt fieldI, PetscInt fieldJ)
2930a102dd69SStefano Zampini {
2931a102dd69SStefano Zampini   PetscFunctionBegin;
2932a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2933a102dd69SStefano Zampini   ds->constants[ds->numConstants]     = fieldI;
2934a102dd69SStefano Zampini   ds->constants[ds->numConstants + 1] = fieldJ;
2935a102dd69SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
2936a102dd69SStefano Zampini }
2937a102dd69SStefano Zampini 
293887510d7dSMatthew G. Knepley /*@C
293987510d7dSMatthew G. Knepley   PetscDSSetCellParameters - Set the parameters for a particular cell
294087510d7dSMatthew G. Knepley 
294187510d7dSMatthew G. Knepley   Not Collective
294287510d7dSMatthew G. Knepley 
294387510d7dSMatthew G. Knepley   Input Parameters:
294487510d7dSMatthew G. Knepley + ds     - The `PetscDS` object
294587510d7dSMatthew G. Knepley - volume - The cell volume
294687510d7dSMatthew G. Knepley 
294787510d7dSMatthew G. Knepley   Level: intermediate
294887510d7dSMatthew G. Knepley 
294987510d7dSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
295087510d7dSMatthew G. Knepley @*/
295187510d7dSMatthew G. Knepley PetscErrorCode PetscDSSetCellParameters(PetscDS ds, PetscReal volume)
295287510d7dSMatthew G. Knepley {
295387510d7dSMatthew G. Knepley   PetscFunctionBegin;
295487510d7dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
295587510d7dSMatthew G. Knepley   ds->constants[ds->numConstants + 2] = volume;
295687510d7dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
295787510d7dSMatthew G. Knepley }
295887510d7dSMatthew G. Knepley 
29594cd1e086SMatthew G. Knepley /*@
29604cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
29614cd1e086SMatthew G. Knepley 
296220f4b53cSBarry Smith   Not Collective
29634cd1e086SMatthew G. Knepley 
29644cd1e086SMatthew G. Knepley   Input Parameters:
2965dce8aebaSBarry Smith + prob - The `PetscDS` object
29664cd1e086SMatthew G. Knepley - disc - The discretization object
29674cd1e086SMatthew G. Knepley 
29684cd1e086SMatthew G. Knepley   Output Parameter:
29694cd1e086SMatthew G. Knepley . f - The field number
29704cd1e086SMatthew G. Knepley 
29714cd1e086SMatthew G. Knepley   Level: beginner
29724cd1e086SMatthew G. Knepley 
2973dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29744cd1e086SMatthew G. Knepley @*/
2975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2976d71ae5a4SJacob Faibussowitsch {
29774cd1e086SMatthew G. Knepley   PetscInt g;
29784cd1e086SMatthew G. Knepley 
29794cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29804cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29814f572ea9SToby Isaac   PetscAssertPointer(f, 3);
29824cd1e086SMatthew G. Knepley   *f = -1;
29839371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
29849371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
29859371c9d4SSatish Balay   }
298608401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
29874cd1e086SMatthew G. Knepley   *f = g;
29883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29894cd1e086SMatthew G. Knepley }
29904cd1e086SMatthew G. Knepley 
29914cd1e086SMatthew G. Knepley /*@
29924cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29934cd1e086SMatthew G. Knepley 
299420f4b53cSBarry Smith   Not Collective
29954cd1e086SMatthew G. Knepley 
29964cd1e086SMatthew G. Knepley   Input Parameters:
2997dce8aebaSBarry Smith + prob - The `PetscDS` object
29984cd1e086SMatthew G. Knepley - f    - The field number
29994cd1e086SMatthew G. Knepley 
30004cd1e086SMatthew G. Knepley   Output Parameter:
30014cd1e086SMatthew G. Knepley . size - The size
30024cd1e086SMatthew G. Knepley 
30034cd1e086SMatthew G. Knepley   Level: beginner
30044cd1e086SMatthew G. Knepley 
3005dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30064cd1e086SMatthew G. Knepley @*/
3007d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
3008d71ae5a4SJacob Faibussowitsch {
30094cd1e086SMatthew G. Knepley   PetscFunctionBegin;
30104cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30114f572ea9SToby Isaac   PetscAssertPointer(size, 3);
301263a3b9bcSJacob 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);
30139566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3014d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
30153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30164cd1e086SMatthew G. Knepley }
30174cd1e086SMatthew G. Knepley 
3018bc4ae4beSMatthew G. Knepley /*@
3019bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
3020bc4ae4beSMatthew G. Knepley 
302120f4b53cSBarry Smith   Not Collective
3022bc4ae4beSMatthew G. Knepley 
3023bc4ae4beSMatthew G. Knepley   Input Parameters:
3024dce8aebaSBarry Smith + prob - The `PetscDS` object
3025bc4ae4beSMatthew G. Knepley - f    - The field number
3026bc4ae4beSMatthew G. Knepley 
3027bc4ae4beSMatthew G. Knepley   Output Parameter:
3028bc4ae4beSMatthew G. Knepley . off - The offset
3029bc4ae4beSMatthew G. Knepley 
3030bc4ae4beSMatthew G. Knepley   Level: beginner
3031bc4ae4beSMatthew G. Knepley 
3032dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3033bc4ae4beSMatthew G. Knepley @*/
3034d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
3035d71ae5a4SJacob Faibussowitsch {
30364cd1e086SMatthew G. Knepley   PetscInt size, g;
30372764a2aaSMatthew G. Knepley 
30382764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30392764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30404f572ea9SToby Isaac   PetscAssertPointer(off, 3);
304163a3b9bcSJacob 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);
30422764a2aaSMatthew G. Knepley   *off = 0;
30432764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
30449566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
30454cd1e086SMatthew G. Knepley     *off += size;
30462764a2aaSMatthew G. Knepley   }
30473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30482764a2aaSMatthew G. Knepley }
30492764a2aaSMatthew G. Knepley 
3050bc4ae4beSMatthew G. Knepley /*@
30515fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
30525fedec97SMatthew G. Knepley 
305320f4b53cSBarry Smith   Not Collective
30545fedec97SMatthew G. Knepley 
30555fedec97SMatthew G. Knepley   Input Parameters:
305660225df5SJacob Faibussowitsch + ds - The `PetscDS` object
30575fedec97SMatthew G. Knepley - f  - The field number
30585fedec97SMatthew G. Knepley 
30595fedec97SMatthew G. Knepley   Output Parameter:
30605fedec97SMatthew G. Knepley . off - The offset
30615fedec97SMatthew G. Knepley 
30625fedec97SMatthew G. Knepley   Level: beginner
30635fedec97SMatthew G. Knepley 
3064dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30655fedec97SMatthew G. Knepley @*/
3066d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
3067d71ae5a4SJacob Faibussowitsch {
30685fedec97SMatthew G. Knepley   PetscInt size, g;
30695fedec97SMatthew G. Knepley 
30705fedec97SMatthew G. Knepley   PetscFunctionBegin;
30715fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
30724f572ea9SToby Isaac   PetscAssertPointer(off, 3);
307363a3b9bcSJacob 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);
30745fedec97SMatthew G. Knepley   *off = 0;
30755fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
30765fedec97SMatthew G. Knepley     PetscBool cohesive;
30775fedec97SMatthew G. Knepley 
30789566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
30799566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
30805fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
30815fedec97SMatthew G. Knepley   }
30823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30835fedec97SMatthew G. Knepley }
30845fedec97SMatthew G. Knepley 
30855fedec97SMatthew G. Knepley /*@
308647e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3087bc4ae4beSMatthew G. Knepley 
308820f4b53cSBarry Smith   Not Collective
3089bc4ae4beSMatthew G. Knepley 
309047e57110SSander Arens   Input Parameter:
3091dce8aebaSBarry Smith . prob - The `PetscDS` object
3092bc4ae4beSMatthew G. Knepley 
3093bc4ae4beSMatthew G. Knepley   Output Parameter:
309447e57110SSander Arens . dimensions - The number of dimensions
3095bc4ae4beSMatthew G. Knepley 
3096bc4ae4beSMatthew G. Knepley   Level: beginner
3097bc4ae4beSMatthew G. Knepley 
3098dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3099bc4ae4beSMatthew G. Knepley @*/
3100d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3101d71ae5a4SJacob Faibussowitsch {
31022764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31032764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31049566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
31054f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
310647e57110SSander Arens   *dimensions = prob->Nb;
31073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31086ce16762SMatthew G. Knepley }
310947e57110SSander Arens 
311047e57110SSander Arens /*@
311147e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
311247e57110SSander Arens 
311320f4b53cSBarry Smith   Not Collective
311447e57110SSander Arens 
311547e57110SSander Arens   Input Parameter:
3116dce8aebaSBarry Smith . prob - The `PetscDS` object
311747e57110SSander Arens 
311847e57110SSander Arens   Output Parameter:
311947e57110SSander Arens . components - The number of components
312047e57110SSander Arens 
312147e57110SSander Arens   Level: beginner
312247e57110SSander Arens 
3123dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
312447e57110SSander Arens @*/
3125d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3126d71ae5a4SJacob Faibussowitsch {
312747e57110SSander Arens   PetscFunctionBegin;
312847e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
31304f572ea9SToby Isaac   PetscAssertPointer(components, 2);
313147e57110SSander Arens   *components = prob->Nc;
31323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31336ce16762SMatthew G. Knepley }
31346ce16762SMatthew G. Knepley 
31356ce16762SMatthew G. Knepley /*@
31366ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
31376ce16762SMatthew G. Knepley 
313820f4b53cSBarry Smith   Not Collective
31396ce16762SMatthew G. Knepley 
31406ce16762SMatthew G. Knepley   Input Parameters:
3141dce8aebaSBarry Smith + prob - The `PetscDS` object
31426ce16762SMatthew G. Knepley - f    - The field number
31436ce16762SMatthew G. Knepley 
31446ce16762SMatthew G. Knepley   Output Parameter:
31456ce16762SMatthew G. Knepley . off - The offset
31466ce16762SMatthew G. Knepley 
31476ce16762SMatthew G. Knepley   Level: beginner
31486ce16762SMatthew G. Knepley 
3149dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31506ce16762SMatthew G. Knepley @*/
3151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3152d71ae5a4SJacob Faibussowitsch {
31536ce16762SMatthew G. Knepley   PetscFunctionBegin;
31546ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31554f572ea9SToby Isaac   PetscAssertPointer(off, 3);
315663a3b9bcSJacob 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);
31579566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
315847e57110SSander Arens   *off = prob->off[f];
31593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31602764a2aaSMatthew G. Knepley }
31612764a2aaSMatthew G. Knepley 
3162194d53e6SMatthew G. Knepley /*@
3163194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3164194d53e6SMatthew G. Knepley 
316520f4b53cSBarry Smith   Not Collective
3166194d53e6SMatthew G. Knepley 
3167194d53e6SMatthew G. Knepley   Input Parameter:
3168dce8aebaSBarry Smith . prob - The `PetscDS` object
3169194d53e6SMatthew G. Knepley 
3170194d53e6SMatthew G. Knepley   Output Parameter:
3171194d53e6SMatthew G. Knepley . offsets - The offsets
3172194d53e6SMatthew G. Knepley 
3173194d53e6SMatthew G. Knepley   Level: beginner
3174194d53e6SMatthew G. Knepley 
3175dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3176194d53e6SMatthew G. Knepley @*/
3177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3178d71ae5a4SJacob Faibussowitsch {
3179194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3180194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31814f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
31829566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3183194d53e6SMatthew G. Knepley   *offsets = prob->off;
31843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3185194d53e6SMatthew G. Knepley }
3186194d53e6SMatthew G. Knepley 
3187194d53e6SMatthew G. Knepley /*@
3188194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3189194d53e6SMatthew G. Knepley 
319020f4b53cSBarry Smith   Not Collective
3191194d53e6SMatthew G. Knepley 
3192194d53e6SMatthew G. Knepley   Input Parameter:
3193dce8aebaSBarry Smith . prob - The `PetscDS` object
3194194d53e6SMatthew G. Knepley 
3195194d53e6SMatthew G. Knepley   Output Parameter:
3196194d53e6SMatthew G. Knepley . offsets - The offsets
3197194d53e6SMatthew G. Knepley 
3198194d53e6SMatthew G. Knepley   Level: beginner
3199194d53e6SMatthew G. Knepley 
3200dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3201194d53e6SMatthew G. Knepley @*/
3202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3203d71ae5a4SJacob Faibussowitsch {
3204194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3205194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32064f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
32079566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3208194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
32093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3210194d53e6SMatthew G. Knepley }
3211194d53e6SMatthew G. Knepley 
32129ee2af8cSMatthew G. Knepley /*@
32139ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
32149ee2af8cSMatthew G. Knepley 
321520f4b53cSBarry Smith   Not Collective
32169ee2af8cSMatthew G. Knepley 
32179ee2af8cSMatthew G. Knepley   Input Parameters:
3218dce8aebaSBarry Smith + ds - The `PetscDS` object
32199ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
32209ee2af8cSMatthew G. Knepley 
32219ee2af8cSMatthew G. Knepley   Output Parameter:
32229ee2af8cSMatthew G. Knepley . offsets - The offsets
32239ee2af8cSMatthew G. Knepley 
32249ee2af8cSMatthew G. Knepley   Level: beginner
32259ee2af8cSMatthew G. Knepley 
3226dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32279ee2af8cSMatthew G. Knepley @*/
3228d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3229d71ae5a4SJacob Faibussowitsch {
32309ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
32319ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32324f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
323328b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
323463a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
32359566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
32369ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
32373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32389ee2af8cSMatthew G. Knepley }
32399ee2af8cSMatthew G. Knepley 
32409ee2af8cSMatthew G. Knepley /*@
32419ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
32429ee2af8cSMatthew G. Knepley 
324320f4b53cSBarry Smith   Not Collective
32449ee2af8cSMatthew G. Knepley 
32459ee2af8cSMatthew G. Knepley   Input Parameters:
3246dce8aebaSBarry Smith + ds - The `PetscDS` object
32479ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
32489ee2af8cSMatthew G. Knepley 
32499ee2af8cSMatthew G. Knepley   Output Parameter:
32509ee2af8cSMatthew G. Knepley . offsets - The offsets
32519ee2af8cSMatthew G. Knepley 
32529ee2af8cSMatthew G. Knepley   Level: beginner
32539ee2af8cSMatthew G. Knepley 
3254dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32559ee2af8cSMatthew G. Knepley @*/
3256d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3257d71ae5a4SJacob Faibussowitsch {
32589ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
32599ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32604f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
326128b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
326263a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
32639566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
32649ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
32653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32669ee2af8cSMatthew G. Knepley }
32679ee2af8cSMatthew G. Knepley 
326868c9edb9SMatthew G. Knepley /*@C
326968c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
327068c9edb9SMatthew G. Knepley 
327120f4b53cSBarry Smith   Not Collective
327268c9edb9SMatthew G. Knepley 
327368c9edb9SMatthew G. Knepley   Input Parameter:
3274dce8aebaSBarry Smith . prob - The `PetscDS` object
327568c9edb9SMatthew G. Knepley 
3276ef0bb6c7SMatthew G. Knepley   Output Parameter:
3277ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
327868c9edb9SMatthew G. Knepley 
327968c9edb9SMatthew G. Knepley   Level: intermediate
328068c9edb9SMatthew G. Knepley 
3281dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
328268c9edb9SMatthew G. Knepley @*/
3283d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3284d71ae5a4SJacob Faibussowitsch {
32852764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32862764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32874f572ea9SToby Isaac   PetscAssertPointer(T, 2);
32889566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3289ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32912764a2aaSMatthew G. Knepley }
32922764a2aaSMatthew G. Knepley 
329368c9edb9SMatthew G. Knepley /*@C
32944d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
329568c9edb9SMatthew G. Knepley 
329620f4b53cSBarry Smith   Not Collective
329768c9edb9SMatthew G. Knepley 
329868c9edb9SMatthew G. Knepley   Input Parameter:
3299dce8aebaSBarry Smith . prob - The `PetscDS` object
330068c9edb9SMatthew G. Knepley 
3301ef0bb6c7SMatthew G. Knepley   Output Parameter:
3302a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
330368c9edb9SMatthew G. Knepley 
330468c9edb9SMatthew G. Knepley   Level: intermediate
330568c9edb9SMatthew G. Knepley 
3306dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
330768c9edb9SMatthew G. Knepley @*/
3308d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3309d71ae5a4SJacob Faibussowitsch {
33102764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33112764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33124f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
33139566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3314ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
33153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33162764a2aaSMatthew G. Knepley }
33172764a2aaSMatthew G. Knepley 
3318d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3319d71ae5a4SJacob Faibussowitsch {
33202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33239371c9d4SSatish Balay   if (u) {
33244f572ea9SToby Isaac     PetscAssertPointer(u, 2);
33259371c9d4SSatish Balay     *u = prob->u;
33269371c9d4SSatish Balay   }
33279371c9d4SSatish Balay   if (u_t) {
33284f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
33299371c9d4SSatish Balay     *u_t = prob->u_t;
33309371c9d4SSatish Balay   }
33319371c9d4SSatish Balay   if (u_x) {
33324f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
33339371c9d4SSatish Balay     *u_x = prob->u_x;
33349371c9d4SSatish Balay   }
33353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33362764a2aaSMatthew G. Knepley }
33372764a2aaSMatthew G. Knepley 
3338d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3339d71ae5a4SJacob Faibussowitsch {
33402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33412764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33429566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33439371c9d4SSatish Balay   if (f0) {
33444f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
33459371c9d4SSatish Balay     *f0 = prob->f0;
33469371c9d4SSatish Balay   }
33479371c9d4SSatish Balay   if (f1) {
33484f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
33499371c9d4SSatish Balay     *f1 = prob->f1;
33509371c9d4SSatish Balay   }
33519371c9d4SSatish Balay   if (g0) {
33524f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
33539371c9d4SSatish Balay     *g0 = prob->g0;
33549371c9d4SSatish Balay   }
33559371c9d4SSatish Balay   if (g1) {
33564f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
33579371c9d4SSatish Balay     *g1 = prob->g1;
33589371c9d4SSatish Balay   }
33599371c9d4SSatish Balay   if (g2) {
33604f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
33619371c9d4SSatish Balay     *g2 = prob->g2;
33629371c9d4SSatish Balay   }
33639371c9d4SSatish Balay   if (g3) {
33644f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
33659371c9d4SSatish Balay     *g3 = prob->g3;
33669371c9d4SSatish Balay   }
33673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33682764a2aaSMatthew G. Knepley }
33692764a2aaSMatthew G. Knepley 
3370d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3371d71ae5a4SJacob Faibussowitsch {
33722764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33732764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33749566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33759371c9d4SSatish Balay   if (x) {
33764f572ea9SToby Isaac     PetscAssertPointer(x, 2);
33779371c9d4SSatish Balay     *x = prob->x;
33789371c9d4SSatish Balay   }
33799371c9d4SSatish Balay   if (basisReal) {
33804f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
33819371c9d4SSatish Balay     *basisReal = prob->basisReal;
33829371c9d4SSatish Balay   }
33839371c9d4SSatish Balay   if (basisDerReal) {
33844f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
33859371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
33869371c9d4SSatish Balay   }
33879371c9d4SSatish Balay   if (testReal) {
33884f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
33899371c9d4SSatish Balay     *testReal = prob->testReal;
33909371c9d4SSatish Balay   }
33919371c9d4SSatish Balay   if (testDerReal) {
33924f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
33939371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33949371c9d4SSatish Balay   }
33953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33962764a2aaSMatthew G. Knepley }
33972764a2aaSMatthew G. Knepley 
339858ebd649SToby Isaac /*@C
3399a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
340058ebd649SToby Isaac 
340120f4b53cSBarry Smith   Collective
3402783e2ec8SMatthew G. Knepley 
340358ebd649SToby Isaac   Input Parameters:
340458ebd649SToby Isaac + ds       - The PetscDS object
3405dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
340658ebd649SToby Isaac . name     - The BC name
340745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3408dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
340945480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
341058ebd649SToby Isaac . field    - The field to constrain
341145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
341258ebd649SToby Isaac . comps    - An array of constrained component numbers
341358ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3414a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
341558ebd649SToby Isaac - ctx      - An optional user context for bcFunc
341658ebd649SToby Isaac 
34172fe279fdSBarry Smith   Output Parameter:
341860225df5SJacob Faibussowitsch . bd - The boundary number
341945480ffeSMatthew G. Knepley 
342058ebd649SToby Isaac   Options Database Keys:
342158ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
342258ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
342358ebd649SToby Isaac 
3424dce8aebaSBarry Smith   Level: developer
3425dce8aebaSBarry Smith 
342656cf3b9cSMatthew G. Knepley   Note:
3427a4e35b19SJacob 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\:
342856cf3b9cSMatthew G. Knepley 
342920f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
343056cf3b9cSMatthew G. Knepley 
3431a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3432dce8aebaSBarry Smith .vb
343320f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3434dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3435dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3436dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3437dce8aebaSBarry Smith .ve
343856cf3b9cSMatthew G. Knepley + dim - the spatial dimension
343956cf3b9cSMatthew G. Knepley . Nf - the number of fields
344056cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
344156cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
344256cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
344356cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
344456cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
344556cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
344656cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
344756cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
344856cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
344956cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
345056cf3b9cSMatthew G. Knepley . t - current time
345156cf3b9cSMatthew G. Knepley . x - coordinates of the current point
345256cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
345356cf3b9cSMatthew G. Knepley . constants - constant parameters
345456cf3b9cSMatthew G. Knepley - bcval - output values at the current point
345556cf3b9cSMatthew G. Knepley 
3456a4e35b19SJacob Faibussowitsch   Notes:
3457a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3458a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3459a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3460a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3461a4e35b19SJacob Faibussowitsch 
3462dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
346358ebd649SToby Isaac @*/
3464d71ae5a4SJacob 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)
3465d71ae5a4SJacob Faibussowitsch {
346645480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
346745480ffeSMatthew G. Knepley   PetscInt    n    = 0;
346845480ffeSMatthew G. Knepley   const char *lname;
346958ebd649SToby Isaac 
347058ebd649SToby Isaac   PetscFunctionBegin;
347158ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3472783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
34734f572ea9SToby Isaac   PetscAssertPointer(name, 3);
347445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
347545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
347645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
347745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3478dce9da9cSMatthew 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);
3479d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3480d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3481d57bb9dbSMatthew G. Knepley     PetscInt  c;
3482d57bb9dbSMatthew G. Knepley 
34839566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
348463a3b9bcSJacob 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);
3485d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
34861dca8a05SBarry 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);
3487d57bb9dbSMatthew G. Knepley     }
3488d57bb9dbSMatthew G. Knepley   }
34899566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34909566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34919566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34929566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34949566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34959566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34969566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34979566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34989566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3499f971fd6bSMatthew G. Knepley   b->type   = type;
350045480ffeSMatthew G. Knepley   b->label  = label;
350145480ffeSMatthew G. Knepley   b->Nv     = Nv;
350258ebd649SToby Isaac   b->field  = field;
350345480ffeSMatthew G. Knepley   b->Nc     = Nc;
350458ebd649SToby Isaac   b->func   = bcFunc;
350556cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
350658ebd649SToby Isaac   b->ctx    = ctx;
350745480ffeSMatthew G. Knepley   b->next   = NULL;
350845480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
350945480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
351045480ffeSMatthew G. Knepley   while (head) {
351145480ffeSMatthew G. Knepley     if (!head->next) {
351245480ffeSMatthew G. Knepley       head->next = b;
351345480ffeSMatthew G. Knepley       head       = b;
351445480ffeSMatthew G. Knepley     }
351545480ffeSMatthew G. Knepley     head = head->next;
351645480ffeSMatthew G. Knepley     ++n;
351745480ffeSMatthew G. Knepley   }
35189371c9d4SSatish Balay   if (bd) {
35194f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
35209371c9d4SSatish Balay     *bd = n;
35219371c9d4SSatish Balay   }
35223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352345480ffeSMatthew G. Knepley }
352445480ffeSMatthew G. Knepley 
3525a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
352645480ffeSMatthew G. Knepley /*@C
3527a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
352845480ffeSMatthew G. Knepley 
352920f4b53cSBarry Smith   Collective
353045480ffeSMatthew G. Knepley 
353145480ffeSMatthew G. Knepley   Input Parameters:
3532dce8aebaSBarry Smith + ds       - The `PetscDS` object
3533dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
353445480ffeSMatthew G. Knepley . name     - The BC name
353545480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3536dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
353745480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
353845480ffeSMatthew G. Knepley . field    - The field to constrain
353945480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
354045480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
354145480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3542a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
354345480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
354445480ffeSMatthew G. Knepley 
35452fe279fdSBarry Smith   Output Parameter:
354660225df5SJacob Faibussowitsch . bd - The boundary number
354745480ffeSMatthew G. Knepley 
354845480ffeSMatthew G. Knepley   Options Database Keys:
354945480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
355045480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
355145480ffeSMatthew G. Knepley 
355220f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3553dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3554dce8aebaSBarry Smith .vb
355520f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3556dce8aebaSBarry Smith .ve
3557dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3558dce8aebaSBarry Smith .vb
355920f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3560dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3561dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3562dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3563dce8aebaSBarry Smith .ve
356445480ffeSMatthew G. Knepley + dim - the spatial dimension
356545480ffeSMatthew G. Knepley . Nf - the number of fields
356645480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
356745480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
356845480ffeSMatthew G. Knepley . u - each field evaluated at the current point
356945480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
357045480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
357145480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
357245480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
357345480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
357445480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
357545480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
357645480ffeSMatthew G. Knepley . t - current time
357745480ffeSMatthew G. Knepley . x - coordinates of the current point
357845480ffeSMatthew G. Knepley . numConstants - number of constant parameters
357945480ffeSMatthew G. Knepley . constants - constant parameters
358045480ffeSMatthew G. Knepley - bcval - output values at the current point
358145480ffeSMatthew G. Knepley 
358245480ffeSMatthew G. Knepley   Level: developer
358345480ffeSMatthew G. Knepley 
3584a4e35b19SJacob Faibussowitsch   Notes:
3585a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3586a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3587a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3588a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3589a4e35b19SJacob Faibussowitsch 
3590dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3591dce8aebaSBarry Smith 
3592dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
359345480ffeSMatthew G. Knepley @*/
3594d71ae5a4SJacob 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)
3595d71ae5a4SJacob Faibussowitsch {
359645480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
359745480ffeSMatthew G. Knepley   PetscInt   n    = 0;
359845480ffeSMatthew G. Knepley 
359945480ffeSMatthew G. Knepley   PetscFunctionBegin;
360045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
360145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
36024f572ea9SToby Isaac   PetscAssertPointer(name, 3);
36034f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
360445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
360545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
360645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
36079566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
36089566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
36099566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
36109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
36119566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
36129566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
36139566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
36149566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
36159566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
361645480ffeSMatthew G. Knepley   b->type   = type;
361745480ffeSMatthew G. Knepley   b->label  = NULL;
361845480ffeSMatthew G. Knepley   b->Nv     = Nv;
361945480ffeSMatthew G. Knepley   b->field  = field;
362045480ffeSMatthew G. Knepley   b->Nc     = Nc;
362145480ffeSMatthew G. Knepley   b->func   = bcFunc;
362245480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
362345480ffeSMatthew G. Knepley   b->ctx    = ctx;
362445480ffeSMatthew G. Knepley   b->next   = NULL;
362545480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
362645480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
362745480ffeSMatthew G. Knepley   while (head) {
362845480ffeSMatthew G. Knepley     if (!head->next) {
362945480ffeSMatthew G. Knepley       head->next = b;
363045480ffeSMatthew G. Knepley       head       = b;
363145480ffeSMatthew G. Knepley     }
363245480ffeSMatthew G. Knepley     head = head->next;
363345480ffeSMatthew G. Knepley     ++n;
363445480ffeSMatthew G. Knepley   }
36359371c9d4SSatish Balay   if (bd) {
36364f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
36379371c9d4SSatish Balay     *bd = n;
36389371c9d4SSatish Balay   }
36393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364058ebd649SToby Isaac }
364158ebd649SToby Isaac 
3642b67eacb3SMatthew G. Knepley /*@C
3643a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3644b67eacb3SMatthew G. Knepley 
3645b67eacb3SMatthew G. Knepley   Input Parameters:
3646dce8aebaSBarry Smith + ds       - The `PetscDS` object
3647b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3648dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3649b67eacb3SMatthew G. Knepley . name     - The BC name
365045480ffeSMatthew G. Knepley . label    - The label defining constrained points
3651dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
365245480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3653b67eacb3SMatthew G. Knepley . field    - The field to constrain
365445480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3655b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3656b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3657a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3658b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3659b67eacb3SMatthew G. Knepley 
3660b67eacb3SMatthew G. Knepley   Level: developer
3661b67eacb3SMatthew G. Knepley 
3662a4e35b19SJacob Faibussowitsch   Notes:
3663a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3664a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3665a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3666a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3667a4e35b19SJacob Faibussowitsch 
3668dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3669dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3670dce8aebaSBarry Smith 
3671dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3672b67eacb3SMatthew G. Knepley @*/
3673d71ae5a4SJacob 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)
3674d71ae5a4SJacob Faibussowitsch {
3675b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3676b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3677b67eacb3SMatthew G. Knepley 
3678b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3679b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3680b67eacb3SMatthew G. Knepley   while (b) {
3681b67eacb3SMatthew G. Knepley     if (n == bd) break;
3682b67eacb3SMatthew G. Knepley     b = b->next;
3683b67eacb3SMatthew G. Knepley     ++n;
3684b67eacb3SMatthew G. Knepley   }
368563a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3686b67eacb3SMatthew G. Knepley   if (name) {
36879566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36889566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3689b67eacb3SMatthew G. Knepley   }
3690b67eacb3SMatthew G. Knepley   b->type = type;
369145480ffeSMatthew G. Knepley   if (label) {
369245480ffeSMatthew G. Knepley     const char *name;
369345480ffeSMatthew G. Knepley 
369445480ffeSMatthew G. Knepley     b->label = label;
36959566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36969566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
36979566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
369845480ffeSMatthew G. Knepley   }
369945480ffeSMatthew G. Knepley   if (Nv >= 0) {
370045480ffeSMatthew G. Knepley     b->Nv = Nv;
37019566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
37029566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
37039566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
370445480ffeSMatthew G. Knepley   }
370545480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
370645480ffeSMatthew G. Knepley   if (Nc >= 0) {
370745480ffeSMatthew G. Knepley     b->Nc = Nc;
37089566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
37099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
37109566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
371145480ffeSMatthew G. Knepley   }
371245480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
371345480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
371445480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
37153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3716b67eacb3SMatthew G. Knepley }
3717b67eacb3SMatthew G. Knepley 
371858ebd649SToby Isaac /*@
371958ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
372058ebd649SToby Isaac 
37212fe279fdSBarry Smith   Input Parameter:
3722dce8aebaSBarry Smith . ds - The `PetscDS` object
372358ebd649SToby Isaac 
37242fe279fdSBarry Smith   Output Parameter:
372558ebd649SToby Isaac . numBd - The number of BC
372658ebd649SToby Isaac 
372758ebd649SToby Isaac   Level: intermediate
372858ebd649SToby Isaac 
3729dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
373058ebd649SToby Isaac @*/
3731d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3732d71ae5a4SJacob Faibussowitsch {
373358ebd649SToby Isaac   DSBoundary b = ds->boundary;
373458ebd649SToby Isaac 
373558ebd649SToby Isaac   PetscFunctionBegin;
373658ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
37374f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
373858ebd649SToby Isaac   *numBd = 0;
37399371c9d4SSatish Balay   while (b) {
37409371c9d4SSatish Balay     ++(*numBd);
37419371c9d4SSatish Balay     b = b->next;
37429371c9d4SSatish Balay   }
37433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
374458ebd649SToby Isaac }
374558ebd649SToby Isaac 
374658ebd649SToby Isaac /*@C
37479a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
374858ebd649SToby Isaac 
374958ebd649SToby Isaac   Input Parameters:
3750dce8aebaSBarry Smith + ds - The `PetscDS` object
375158ebd649SToby Isaac - bd - The BC number
375258ebd649SToby Isaac 
375358ebd649SToby Isaac   Output Parameters:
3754dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3755dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
375658ebd649SToby Isaac . name   - The BC name
375745480ffeSMatthew G. Knepley . label  - The label defining constrained points
3758dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
375945480ffeSMatthew G. Knepley . values - An array of ids for constrained points
376058ebd649SToby Isaac . field  - The field to constrain
376145480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
376258ebd649SToby Isaac . comps  - An array of constrained component numbers
376360225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
376460225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
376558ebd649SToby Isaac - ctx    - An optional user context for bcFunc
376658ebd649SToby Isaac 
376758ebd649SToby Isaac   Options Database Keys:
376858ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
376958ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
377058ebd649SToby Isaac 
377158ebd649SToby Isaac   Level: developer
377258ebd649SToby Isaac 
3773dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
377458ebd649SToby Isaac @*/
3775d71ae5a4SJacob 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)
3776d71ae5a4SJacob Faibussowitsch {
377758ebd649SToby Isaac   DSBoundary b = ds->boundary;
377858ebd649SToby Isaac   PetscInt   n = 0;
377958ebd649SToby Isaac 
378058ebd649SToby Isaac   PetscFunctionBegin;
378158ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
378258ebd649SToby Isaac   while (b) {
378358ebd649SToby Isaac     if (n == bd) break;
378458ebd649SToby Isaac     b = b->next;
378558ebd649SToby Isaac     ++n;
378658ebd649SToby Isaac   }
378763a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
378845480ffeSMatthew G. Knepley   if (wf) {
37894f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
379045480ffeSMatthew G. Knepley     *wf = b->wf;
379145480ffeSMatthew G. Knepley   }
3792f971fd6bSMatthew G. Knepley   if (type) {
37934f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3794f971fd6bSMatthew G. Knepley     *type = b->type;
379558ebd649SToby Isaac   }
379658ebd649SToby Isaac   if (name) {
37974f572ea9SToby Isaac     PetscAssertPointer(name, 5);
379858ebd649SToby Isaac     *name = b->name;
379958ebd649SToby Isaac   }
380045480ffeSMatthew G. Knepley   if (label) {
38014f572ea9SToby Isaac     PetscAssertPointer(label, 6);
380245480ffeSMatthew G. Knepley     *label = b->label;
380345480ffeSMatthew G. Knepley   }
380445480ffeSMatthew G. Knepley   if (Nv) {
38054f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
380645480ffeSMatthew G. Knepley     *Nv = b->Nv;
380745480ffeSMatthew G. Knepley   }
380845480ffeSMatthew G. Knepley   if (values) {
38094f572ea9SToby Isaac     PetscAssertPointer(values, 8);
381045480ffeSMatthew G. Knepley     *values = b->values;
381158ebd649SToby Isaac   }
381258ebd649SToby Isaac   if (field) {
38134f572ea9SToby Isaac     PetscAssertPointer(field, 9);
381458ebd649SToby Isaac     *field = b->field;
381558ebd649SToby Isaac   }
381645480ffeSMatthew G. Knepley   if (Nc) {
38174f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
381845480ffeSMatthew G. Knepley     *Nc = b->Nc;
381958ebd649SToby Isaac   }
382058ebd649SToby Isaac   if (comps) {
38214f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
382258ebd649SToby Isaac     *comps = b->comps;
382358ebd649SToby Isaac   }
382458ebd649SToby Isaac   if (func) {
38254f572ea9SToby Isaac     PetscAssertPointer(func, 12);
382658ebd649SToby Isaac     *func = b->func;
382758ebd649SToby Isaac   }
382856cf3b9cSMatthew G. Knepley   if (func_t) {
38294f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
383056cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
383156cf3b9cSMatthew G. Knepley   }
383258ebd649SToby Isaac   if (ctx) {
38334f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
383458ebd649SToby Isaac     *ctx = b->ctx;
383558ebd649SToby Isaac   }
38363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
383758ebd649SToby Isaac }
383858ebd649SToby Isaac 
383910af620dSMatthew G. Knepley /*@
384010af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
384110af620dSMatthew G. Knepley 
384210af620dSMatthew G. Knepley   Not Collective
384310af620dSMatthew G. Knepley 
384410af620dSMatthew G. Knepley   Input Parameters:
384510af620dSMatthew G. Knepley + ds - The source `PetscDS` object
384610af620dSMatthew G. Knepley - dm - The `DM` holding labels
384710af620dSMatthew G. Knepley 
384810af620dSMatthew G. Knepley   Level: intermediate
384910af620dSMatthew G. Knepley 
385010af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
385110af620dSMatthew G. Knepley @*/
385210af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
385310af620dSMatthew G. Knepley {
385410af620dSMatthew G. Knepley   DSBoundary b;
385510af620dSMatthew G. Knepley 
385610af620dSMatthew G. Knepley   PetscFunctionBegin;
385710af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
385810af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
385910af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
386010af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
386110af620dSMatthew G. Knepley   }
386210af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
386310af620dSMatthew G. Knepley }
386410af620dSMatthew G. Knepley 
3865d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3866d71ae5a4SJacob Faibussowitsch {
386745480ffeSMatthew G. Knepley   PetscFunctionBegin;
38689566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
38699566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
38709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
38719566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
38729566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
387345480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
387445480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
387545480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
38769566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
38779566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
387845480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
387945480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
38809566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
38819566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
388245480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
388345480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
388445480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
38853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
388645480ffeSMatthew G. Knepley }
388745480ffeSMatthew G. Knepley 
38889252d075SMatthew G. Knepley /*@
38899252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
38909252d075SMatthew G. Knepley 
389120f4b53cSBarry Smith   Not Collective
38929252d075SMatthew G. Knepley 
389336951cb5SMatthew G. Knepley   Input Parameters:
3894dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3895dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
389636951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
38979252d075SMatthew G. Knepley 
38989252d075SMatthew G. Knepley   Output Parameter:
3899dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
39009252d075SMatthew G. Knepley 
39019252d075SMatthew G. Knepley   Level: intermediate
39029252d075SMatthew G. Knepley 
3903dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39049252d075SMatthew G. Knepley @*/
3905d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3906d71ae5a4SJacob Faibussowitsch {
390745480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3908dff059c6SToby Isaac 
3909dff059c6SToby Isaac   PetscFunctionBegin;
391036951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
391136951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
39123ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
39139566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
3914f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
391536951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3916dff059c6SToby Isaac     DSBoundary bNew;
391736951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3918dff059c6SToby Isaac 
391936951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
392036951cb5SMatthew G. Knepley       PetscInt f;
392136951cb5SMatthew G. Knepley 
39229371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
39239371c9d4SSatish Balay         if (b->field == fields[f]) break;
392436951cb5SMatthew G. Knepley       if (f == numFields) continue;
392536951cb5SMatthew G. Knepley       fieldNew = f;
392636951cb5SMatthew G. Knepley     }
39279566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
392836951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3929dff059c6SToby Isaac     *lastnext   = bNew;
3930f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
3931dff059c6SToby Isaac   }
39323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3933dff059c6SToby Isaac }
3934dff059c6SToby Isaac 
39356c1eb96dSMatthew G. Knepley /*@
3936dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
393745480ffeSMatthew G. Knepley 
393820f4b53cSBarry Smith   Not Collective
393945480ffeSMatthew G. Knepley 
394045480ffeSMatthew G. Knepley   Input Parameter:
3941dce8aebaSBarry Smith . ds - The `PetscDS` object
394245480ffeSMatthew G. Knepley 
394345480ffeSMatthew G. Knepley   Level: intermediate
394445480ffeSMatthew G. Knepley 
3945dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
394645480ffeSMatthew G. Knepley @*/
3947d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3948d71ae5a4SJacob Faibussowitsch {
394945480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
395045480ffeSMatthew G. Knepley 
395145480ffeSMatthew G. Knepley   PetscFunctionBegin;
395245480ffeSMatthew G. Knepley   while (next) {
395345480ffeSMatthew G. Knepley     DSBoundary b = next;
395445480ffeSMatthew G. Knepley 
395545480ffeSMatthew G. Knepley     next = b->next;
39569566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
39579566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
39589566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
39599566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
39609566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
39619566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
396245480ffeSMatthew G. Knepley   }
39633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
396445480ffeSMatthew G. Knepley }
396545480ffeSMatthew G. Knepley 
396645480ffeSMatthew G. Knepley /*@
39676c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
39686c1eb96dSMatthew G. Knepley 
396920f4b53cSBarry Smith   Not Collective
39706c1eb96dSMatthew G. Knepley 
3971d8d19677SJose E. Roman   Input Parameters:
3972dce8aebaSBarry Smith + prob      - The `PetscDS` object
39736c1eb96dSMatthew G. Knepley . numFields - Number of new fields
3974bb4b53efSMatthew G. Knepley . fields    - Old field number for each new field
3975bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit
3976bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit
39776c1eb96dSMatthew G. Knepley 
39786c1eb96dSMatthew G. Knepley   Output Parameter:
3979dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39806c1eb96dSMatthew G. Knepley 
39816c1eb96dSMatthew G. Knepley   Level: intermediate
39826c1eb96dSMatthew G. Knepley 
3983dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39846c1eb96dSMatthew G. Knepley @*/
3985bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscInt minDegree, PetscInt maxDegree, PetscDS newprob)
3986d71ae5a4SJacob Faibussowitsch {
39876c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
39886c1eb96dSMatthew G. Knepley 
39896c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
39906c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39914f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
3992bb4b53efSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 6);
39939566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39949566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
399545480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
39966c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39976c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
39986c1eb96dSMatthew G. Knepley     PetscObject    disc;
3999bb4b53efSMatthew G. Knepley     PetscClassId   id;
40006c1eb96dSMatthew G. Knepley 
40016c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
40029566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
4003bb4b53efSMatthew G. Knepley     PetscCallContinue(PetscObjectGetClassId(disc, &id));
4004bb4b53efSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
4005bb4b53efSMatthew G. Knepley       PetscFE fe;
4006bb4b53efSMatthew G. Knepley 
4007bb4b53efSMatthew G. Knepley       PetscCall(PetscFELimitDegree((PetscFE)disc, minDegree, maxDegree, &fe));
4008bb4b53efSMatthew G. Knepley       PetscCall(PetscDSSetDiscretization(newprob, fn, (PetscObject)fe));
4009bb4b53efSMatthew G. Knepley       PetscCall(PetscFEDestroy(&fe));
4010bb4b53efSMatthew G. Knepley     } else {
40119566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
40126c1eb96dSMatthew G. Knepley     }
4013bb4b53efSMatthew G. Knepley   }
40143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40156c1eb96dSMatthew G. Knepley }
40166c1eb96dSMatthew G. Knepley 
40176c1eb96dSMatthew G. Knepley /*@
40189252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
40199252d075SMatthew G. Knepley 
402020f4b53cSBarry Smith   Not Collective
40219252d075SMatthew G. Knepley 
4022d8d19677SJose E. Roman   Input Parameters:
4023dce8aebaSBarry Smith + prob      - The `PetscDS` object
40249252d075SMatthew G. Knepley . numFields - Number of new fields
40259252d075SMatthew G. Knepley - fields    - Old field number for each new field
40269252d075SMatthew G. Knepley 
40279252d075SMatthew G. Knepley   Output Parameter:
4028dce8aebaSBarry Smith . newprob - The `PetscDS` copy
40299252d075SMatthew G. Knepley 
40309252d075SMatthew G. Knepley   Level: intermediate
40319252d075SMatthew G. Knepley 
4032dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40339252d075SMatthew G. Knepley @*/
4034d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
4035d71ae5a4SJacob Faibussowitsch {
40369252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
40379252d075SMatthew G. Knepley 
40389252d075SMatthew G. Knepley   PetscFunctionBegin;
40399252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
40404f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
40419252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
40429566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40439566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
404463a3b9bcSJacob Faibussowitsch   PetscCheck(numFields <= Nfn, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields %" PetscInt_FMT " to transfer must not be greater then the total number of fields %" PetscInt_FMT, numFields, Nfn);
40459252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
40469252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
40479252d075SMatthew G. Knepley     PetscPointFunc   obj;
40489252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
40499252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
40509252d075SMatthew G. Knepley     PetscRiemannFunc r;
40519252d075SMatthew G. Knepley 
4052c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
40539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
40549566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
40559566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
40569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
40579566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
40589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
40599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
40609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
40619252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
40629252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
40639252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
40649252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
40659252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
40669252d075SMatthew G. Knepley 
4067c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
40689566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
40699566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
40709566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
40719566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
40729566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
40739566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
40749252d075SMatthew G. Knepley     }
40759252d075SMatthew G. Knepley   }
40763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40779252d075SMatthew G. Knepley }
40789252d075SMatthew G. Knepley 
4079da51fcedSMatthew G. Knepley /*@
4080dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
4081da51fcedSMatthew G. Knepley 
408220f4b53cSBarry Smith   Not Collective
4083da51fcedSMatthew G. Knepley 
4084da51fcedSMatthew G. Knepley   Input Parameter:
4085dce8aebaSBarry Smith . prob - The `PetscDS` object
4086da51fcedSMatthew G. Knepley 
4087da51fcedSMatthew G. Knepley   Output Parameter:
4088dce8aebaSBarry Smith . newprob - The `PetscDS` copy
4089da51fcedSMatthew G. Knepley 
4090da51fcedSMatthew G. Knepley   Level: intermediate
4091da51fcedSMatthew G. Knepley 
4092dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4093da51fcedSMatthew G. Knepley @*/
4094d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
4095d71ae5a4SJacob Faibussowitsch {
4096b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
40979252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4098da51fcedSMatthew G. Knepley 
4099da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4100da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4101da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
41029566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41039566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
410463a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
41059566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
41069566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
41079566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
41083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41099252d075SMatthew G. Knepley }
411045480ffeSMatthew G. Knepley 
41119252d075SMatthew G. Knepley /*@
4112dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4113da51fcedSMatthew G. Knepley 
411420f4b53cSBarry Smith   Not Collective
41159252d075SMatthew G. Knepley 
41169252d075SMatthew G. Knepley   Input Parameter:
4117dce8aebaSBarry Smith . prob - The `PetscDS` object
41189252d075SMatthew G. Knepley 
41199252d075SMatthew G. Knepley   Output Parameter:
4120dce8aebaSBarry Smith . newprob - The `PetscDS` copy
41219252d075SMatthew G. Knepley 
41229252d075SMatthew G. Knepley   Level: intermediate
41239252d075SMatthew G. Knepley 
4124dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
41259252d075SMatthew G. Knepley @*/
4126d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4127d71ae5a4SJacob Faibussowitsch {
41289252d075SMatthew G. Knepley   PetscInt           Nc;
41299252d075SMatthew G. Knepley   const PetscScalar *constants;
41309252d075SMatthew G. Knepley 
41319252d075SMatthew G. Knepley   PetscFunctionBegin;
41329252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41339252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
41349566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
41359566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
41363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4137da51fcedSMatthew G. Knepley }
4138da51fcedSMatthew G. Knepley 
413945480ffeSMatthew G. Knepley /*@
4140dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
414145480ffeSMatthew G. Knepley 
414220f4b53cSBarry Smith   Not Collective
414345480ffeSMatthew G. Knepley 
414445480ffeSMatthew G. Knepley   Input Parameter:
4145dce8aebaSBarry Smith . ds - The `PetscDS` object
414645480ffeSMatthew G. Knepley 
414745480ffeSMatthew G. Knepley   Output Parameter:
4148dce8aebaSBarry Smith . newds - The `PetscDS` copy
414945480ffeSMatthew G. Knepley 
415045480ffeSMatthew G. Knepley   Level: intermediate
415145480ffeSMatthew G. Knepley 
4152dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
415345480ffeSMatthew G. Knepley @*/
4154d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4155d71ae5a4SJacob Faibussowitsch {
41568434afd1SBarry Smith   PetscSimplePointFn *sol;
415745480ffeSMatthew G. Knepley   void               *ctx;
415845480ffeSMatthew G. Knepley   PetscInt            Nf, f;
415945480ffeSMatthew G. Knepley 
416045480ffeSMatthew G. Knepley   PetscFunctionBegin;
416145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
416245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
41639566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
416445480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
41659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
41669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
41679566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
41689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
416945480ffeSMatthew G. Knepley   }
41703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
417145480ffeSMatthew G. Knepley }
417245480ffeSMatthew G. Knepley 
4173bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, PetscInt minDegree, PetscInt maxDegree, DM dmNew, PetscDS dsNew)
417407218a29SMatthew G. Knepley {
417507218a29SMatthew G. Knepley   DSBoundary b;
417607218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
417707218a29SMatthew G. Knepley   PetscBool  isCohesive;
417807218a29SMatthew G. Knepley   void      *ctx;
417907218a29SMatthew G. Knepley 
418007218a29SMatthew G. Knepley   PetscFunctionBegin;
418107218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
418207218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
4183bb4b53efSMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, minDegree, maxDegree, dsNew));
418407218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
418507218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
418607218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
418707218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
418807218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
418907218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
419007218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
419107218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
419207218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
419307218a29SMatthew G. Knepley   }
419407218a29SMatthew G. Knepley   if (Nf) {
419507218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
419607218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
419707218a29SMatthew G. Knepley   }
419807218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
419907218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
420007218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
420107218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
420207218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
420307218a29SMatthew G. Knepley   }
420407218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
420507218a29SMatthew G. Knepley }
420607218a29SMatthew G. Knepley 
4207d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4208d71ae5a4SJacob Faibussowitsch {
4209df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4210b1353e8eSMatthew G. Knepley 
4211b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4212b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
42134f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
42149371c9d4SSatish Balay   if (height == 0) {
42159371c9d4SSatish Balay     *subprob = prob;
42163ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
42179371c9d4SSatish Balay   }
42189566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
42199566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
422063a3b9bcSJacob 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);
42219566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4222df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4223b1353e8eSMatthew G. Knepley     PetscInt cdim;
4224b1353e8eSMatthew G. Knepley 
42259566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
42269566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
42279566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4228b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4229b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4230b1353e8eSMatthew G. Knepley       PetscObject  obj;
4231b1353e8eSMatthew G. Knepley       PetscClassId id;
4232b1353e8eSMatthew G. Knepley 
42339566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
42349566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
42359566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
423663a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
42379566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4238b1353e8eSMatthew G. Knepley     }
4239b1353e8eSMatthew G. Knepley   }
4240df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
42413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4242b1353e8eSMatthew G. Knepley }
4243b1353e8eSMatthew G. Knepley 
42444366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
42454366bac7SMatthew G. Knepley {
42464366bac7SMatthew G. Knepley   IS              permIS;
42474366bac7SMatthew G. Knepley   PetscQuadrature quad;
42484366bac7SMatthew G. Knepley   DMPolytopeType  ct;
42494366bac7SMatthew G. Knepley   const PetscInt *perm;
42504366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
42514366bac7SMatthew G. Knepley 
42524366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
42534366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
42544366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
42554366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
42564366bac7SMatthew 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);
425785036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
42584366bac7SMatthew 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);
42594366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
42604366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
42614366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
42624366bac7SMatthew G. Knepley   *qperm = perm[q];
42634366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
42644366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
42654366bac7SMatthew G. Knepley }
42664366bac7SMatthew G. Knepley 
4267d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4268d71ae5a4SJacob Faibussowitsch {
4269c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4270c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4271c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4272c7bd5f0bSMatthew G. Knepley 
4273c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4274c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
42754f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4276665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
42779566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
427863a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
42799566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4280665f567fSMatthew G. Knepley   if (obj) {
42819566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4282665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4283665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4284665f567fSMatthew G. Knepley   }
42853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4286c7bd5f0bSMatthew G. Knepley }
4287c7bd5f0bSMatthew G. Knepley 
4288d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4289d71ae5a4SJacob Faibussowitsch {
42902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42919566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
42923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42932764a2aaSMatthew G. Knepley }
42942764a2aaSMatthew G. Knepley 
4295d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4296d71ae5a4SJacob Faibussowitsch {
42972764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42986528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
42996528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
43006528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
43016528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
43023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43032764a2aaSMatthew G. Knepley }
43042764a2aaSMatthew G. Knepley 
43052764a2aaSMatthew G. Knepley /*MC
43062764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
43072764a2aaSMatthew G. Knepley 
43082764a2aaSMatthew G. Knepley   Level: intermediate
43092764a2aaSMatthew G. Knepley 
4310db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
43112764a2aaSMatthew G. Knepley M*/
43122764a2aaSMatthew G. Knepley 
4313d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4314d71ae5a4SJacob Faibussowitsch {
43152764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
43162764a2aaSMatthew G. Knepley 
43172764a2aaSMatthew G. Knepley   PetscFunctionBegin;
43186528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
43194dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
43206528b96dSMatthew G. Knepley   ds->data = b;
43212764a2aaSMatthew G. Knepley 
43229566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
43233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43242764a2aaSMatthew G. Knepley }
4325