xref: /petsc/src/dm/dt/interface/dtds.c (revision 342bd5aaaaaec7e5e85bffd92ebcba06ee6843af)
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;
558*342bd5aaSMatthew G. Knepley   PetscSimplePointFn **tmpexactSol, **tmpexactSol_t, **tmplowerBound, **tmpupperBound;
559*342bd5aaSMatthew G. Knepley   void               **tmpexactCtx, **tmpexactCtx_t, **tmplowerCtx, **tmpupperCtx;
5600c2f2876SMatthew G. Knepley   void               **tmpctx;
56134aa8a36SMatthew G. Knepley   PetscInt             Nf = prob->Nf, f;
5622764a2aaSMatthew G. Knepley 
5632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5643ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5652764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5669566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5679566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5689371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5699371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5709371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5719371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5729371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5739371c9d4SSatish Balay   }
5749371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5759371c9d4SSatish Balay     tmpd[f] = NULL;
5769371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5779371c9d4SSatish Balay     tmpk[f] = 1;
5789371c9d4SSatish Balay   }
5799566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5812764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5822764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
583249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5845fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
585f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5869566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58732d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5880c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58932d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5900c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5919566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59232d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5930c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5949566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
595*342bd5aaSMatthew G. Knepley   PetscCall(PetscCalloc4(NfNew, &tmplowerBound, NfNew, &tmplowerCtx, NfNew, &tmpupperBound, NfNew, &tmpupperCtx));
596c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59795cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
598f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
599f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
600*342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerBound[f] = prob->lowerBound[f];
601*342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerCtx[f] = prob->lowerCtx[f];
602*342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperBound[f] = prob->upperBound[f];
603*342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperCtx[f] = prob->upperCtx[f];
604c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
60595cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
606f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
607f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
608*342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerBound[f] = NULL;
609*342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerCtx[f] = NULL;
610*342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperBound[f] = NULL;
611*342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperCtx[f] = NULL;
6129566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
613*342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4(prob->lowerBound, prob->lowerCtx, prob->upperBound, prob->upperCtx));
614c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
61595cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
616f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
617f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
618*342bd5aaSMatthew G. Knepley   prob->lowerBound = tmplowerBound;
619*342bd5aaSMatthew G. Knepley   prob->lowerCtx   = tmplowerCtx;
620*342bd5aaSMatthew G. Knepley   prob->upperBound = tmpupperBound;
621*342bd5aaSMatthew G. Knepley   prob->upperCtx   = tmpupperCtx;
6223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6232764a2aaSMatthew G. Knepley }
6242764a2aaSMatthew G. Knepley 
6252764a2aaSMatthew G. Knepley /*@
62620f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6272764a2aaSMatthew G. Knepley 
62820f4b53cSBarry Smith   Collective
6292764a2aaSMatthew G. Knepley 
6302764a2aaSMatthew G. Knepley   Input Parameter:
63160225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6322764a2aaSMatthew G. Knepley 
6332764a2aaSMatthew G. Knepley   Level: developer
6342764a2aaSMatthew G. Knepley 
635dce8aebaSBarry Smith .seealso: `PetscDSView()`
6362764a2aaSMatthew G. Knepley @*/
637d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
638d71ae5a4SJacob Faibussowitsch {
6392764a2aaSMatthew G. Knepley   PetscInt f;
6402764a2aaSMatthew G. Knepley 
6412764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6423ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
643f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6442764a2aaSMatthew G. Knepley 
645f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6469371c9d4SSatish Balay     *ds = NULL;
6473ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6489371c9d4SSatish Balay   }
649f4f49eeaSPierre Jolivet   ((PetscObject)*ds)->refct = 0;
6506528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
651df3a45bdSMatthew G. Knepley     PetscInt dim, d;
652df3a45bdSMatthew G. Knepley 
6539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6549566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
655df3a45bdSMatthew G. Knepley   }
6569566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6579566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
65848a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6599566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6609566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6619566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6629566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
663*342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4((*ds)->lowerBound, (*ds)->lowerCtx, (*ds)->upperBound, (*ds)->upperCtx));
664f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ds, destroy);
6659566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6669566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6674366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
66885036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((DMPolytopeType)c);
6694366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6704366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6714366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6724366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6734366bac7SMatthew G. Knepley   }
6749566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6762764a2aaSMatthew G. Knepley }
6772764a2aaSMatthew G. Knepley 
6782764a2aaSMatthew G. Knepley /*@
679dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6802764a2aaSMatthew G. Knepley 
681d083f849SBarry Smith   Collective
6822764a2aaSMatthew G. Knepley 
6832764a2aaSMatthew G. Knepley   Input Parameter:
684dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6852764a2aaSMatthew G. Knepley 
6862764a2aaSMatthew G. Knepley   Output Parameter:
687dce8aebaSBarry Smith . ds - The `PetscDS` object
6882764a2aaSMatthew G. Knepley 
6892764a2aaSMatthew G. Knepley   Level: beginner
6902764a2aaSMatthew G. Knepley 
691dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6922764a2aaSMatthew G. Knepley @*/
693d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
694d71ae5a4SJacob Faibussowitsch {
6952764a2aaSMatthew G. Knepley   PetscDS p;
6962764a2aaSMatthew G. Knepley 
6972764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6984f572ea9SToby Isaac   PetscAssertPointer(ds, 2);
6999566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
7002764a2aaSMatthew G. Knepley 
7019566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
7022764a2aaSMatthew G. Knepley   p->Nf               = 0;
7032764a2aaSMatthew G. Knepley   p->setup            = PETSC_FALSE;
70497b6e6e8SMatthew G. Knepley   p->numConstants     = 0;
70587510d7dSMatthew G. Knepley   p->numFuncConstants = 3; // Row and col fields, cell size
706a859676bSMatthew G. Knepley   p->dimEmbed         = -1;
70755c1f793SMatthew G. Knepley   p->useJacPre        = PETSC_TRUE;
70812fc5b22SMatthew G. Knepley   p->forceQuad        = PETSC_TRUE;
709a102dd69SStefano Zampini   PetscCall(PetscMalloc1(p->numConstants + p->numFuncConstants, &p->constants));
7109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
7114366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
7126528b96dSMatthew G. Knepley   *ds = p;
7133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7142764a2aaSMatthew G. Knepley }
7152764a2aaSMatthew G. Knepley 
716bc4ae4beSMatthew G. Knepley /*@
717dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
718bc4ae4beSMatthew G. Knepley 
71920f4b53cSBarry Smith   Not Collective
720bc4ae4beSMatthew G. Knepley 
721bc4ae4beSMatthew G. Knepley   Input Parameter:
72220f4b53cSBarry Smith . prob - The `PetscDS` object
723bc4ae4beSMatthew G. Knepley 
724bc4ae4beSMatthew G. Knepley   Output Parameter:
725bc4ae4beSMatthew G. Knepley . Nf - The number of fields
726bc4ae4beSMatthew G. Knepley 
727bc4ae4beSMatthew G. Knepley   Level: beginner
728bc4ae4beSMatthew G. Knepley 
729dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
730bc4ae4beSMatthew G. Knepley @*/
731d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
732d71ae5a4SJacob Faibussowitsch {
7332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7342764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7354f572ea9SToby Isaac   PetscAssertPointer(Nf, 2);
7362764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7382764a2aaSMatthew G. Knepley }
7392764a2aaSMatthew G. Knepley 
740bc4ae4beSMatthew G. Knepley /*@
741dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
742bc4ae4beSMatthew G. Knepley 
74320f4b53cSBarry Smith   Not Collective
744bc4ae4beSMatthew G. Knepley 
745bc4ae4beSMatthew G. Knepley   Input Parameter:
746dce8aebaSBarry Smith . prob - The `PetscDS` object
747bc4ae4beSMatthew G. Knepley 
748bc4ae4beSMatthew G. Knepley   Output Parameter:
749bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
750bc4ae4beSMatthew G. Knepley 
751bc4ae4beSMatthew G. Knepley   Level: beginner
752bc4ae4beSMatthew G. Knepley 
753dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
754bc4ae4beSMatthew G. Knepley @*/
755d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
756d71ae5a4SJacob Faibussowitsch {
7572764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7582764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7594f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
7602764a2aaSMatthew G. Knepley   *dim = 0;
7619de99aefSMatthew G. Knepley   if (prob->Nf) {
7629de99aefSMatthew G. Knepley     PetscObject  obj;
7639de99aefSMatthew G. Knepley     PetscClassId id;
7649de99aefSMatthew G. Knepley 
7659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
766665f567fSMatthew G. Knepley     if (obj) {
7679566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7689566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7699566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
77098921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7719de99aefSMatthew G. Knepley     }
772665f567fSMatthew G. Knepley   }
7733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7742764a2aaSMatthew G. Knepley }
7752764a2aaSMatthew G. Knepley 
776bc4ae4beSMatthew G. Knepley /*@
777dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
778a859676bSMatthew G. Knepley 
77920f4b53cSBarry Smith   Not Collective
780a859676bSMatthew G. Knepley 
781a859676bSMatthew G. Knepley   Input Parameter:
782dce8aebaSBarry Smith . prob - The `PetscDS` object
783a859676bSMatthew G. Knepley 
784a859676bSMatthew G. Knepley   Output Parameter:
785a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
786a859676bSMatthew G. Knepley 
787a859676bSMatthew G. Knepley   Level: beginner
788a859676bSMatthew G. Knepley 
789dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
790a859676bSMatthew G. Knepley @*/
791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
792d71ae5a4SJacob Faibussowitsch {
793a859676bSMatthew G. Knepley   PetscFunctionBegin;
794a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7954f572ea9SToby Isaac   PetscAssertPointer(dimEmbed, 2);
79608401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
797a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
799a859676bSMatthew G. Knepley }
800a859676bSMatthew G. Knepley 
801a859676bSMatthew G. Knepley /*@
802dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
803a859676bSMatthew G. Knepley 
80420f4b53cSBarry Smith   Logically Collective
805a859676bSMatthew G. Knepley 
806a859676bSMatthew G. Knepley   Input Parameters:
807dce8aebaSBarry Smith + prob     - The `PetscDS` object
808a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
809a859676bSMatthew G. Knepley 
810a859676bSMatthew G. Knepley   Level: beginner
811a859676bSMatthew G. Knepley 
812dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
813a859676bSMatthew G. Knepley @*/
814d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
815d71ae5a4SJacob Faibussowitsch {
816a859676bSMatthew G. Knepley   PetscFunctionBegin;
817a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
81863a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
819a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
821a859676bSMatthew G. Knepley }
822a859676bSMatthew G. Knepley 
823a859676bSMatthew G. Knepley /*@
82412fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
82512fc5b22SMatthew G. Knepley 
82612fc5b22SMatthew G. Knepley   Not collective
82712fc5b22SMatthew G. Knepley 
82812fc5b22SMatthew G. Knepley   Input Parameter:
82960225df5SJacob Faibussowitsch . ds - The `PetscDS` object
83012fc5b22SMatthew G. Knepley 
83112fc5b22SMatthew G. Knepley   Output Parameter:
83212fc5b22SMatthew G. Knepley . forceQuad - The flag
83312fc5b22SMatthew G. Knepley 
83412fc5b22SMatthew G. Knepley   Level: intermediate
83512fc5b22SMatthew G. Knepley 
83612fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
83712fc5b22SMatthew G. Knepley @*/
83812fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
83912fc5b22SMatthew G. Knepley {
84012fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84112fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8424f572ea9SToby Isaac   PetscAssertPointer(forceQuad, 2);
84312fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
84412fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
84512fc5b22SMatthew G. Knepley }
84612fc5b22SMatthew G. Knepley 
84712fc5b22SMatthew G. Knepley /*@
84812fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
84912fc5b22SMatthew G. Knepley 
85012fc5b22SMatthew G. Knepley   Logically collective on ds
85112fc5b22SMatthew G. Knepley 
85212fc5b22SMatthew G. Knepley   Input Parameters:
85312fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
85412fc5b22SMatthew G. Knepley - forceQuad - The flag
85512fc5b22SMatthew G. Knepley 
85612fc5b22SMatthew G. Knepley   Level: intermediate
85712fc5b22SMatthew G. Knepley 
85812fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
85912fc5b22SMatthew G. Knepley @*/
86012fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
86112fc5b22SMatthew G. Knepley {
86212fc5b22SMatthew G. Knepley   PetscFunctionBegin;
86312fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
86412fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
86512fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
86612fc5b22SMatthew G. Knepley }
86712fc5b22SMatthew G. Knepley 
86812fc5b22SMatthew G. Knepley /*@
869dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8708edf6225SMatthew G. Knepley 
87120f4b53cSBarry Smith   Not Collective
8728edf6225SMatthew G. Knepley 
8738edf6225SMatthew G. Knepley   Input Parameter:
874dce8aebaSBarry Smith . ds - The `PetscDS` object
8758edf6225SMatthew G. Knepley 
8768edf6225SMatthew G. Knepley   Output Parameter:
8775fedec97SMatthew G. Knepley . isCohesive - The flag
8788edf6225SMatthew G. Knepley 
8798edf6225SMatthew G. Knepley   Level: developer
8808edf6225SMatthew G. Knepley 
881dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8828edf6225SMatthew G. Knepley @*/
883d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
884d71ae5a4SJacob Faibussowitsch {
8858edf6225SMatthew G. Knepley   PetscFunctionBegin;
8865fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8874f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 2);
8885fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8908edf6225SMatthew G. Knepley }
8918edf6225SMatthew G. Knepley 
8928edf6225SMatthew G. Knepley /*@
893be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8945fedec97SMatthew G. Knepley 
89520f4b53cSBarry Smith   Not Collective
8965fedec97SMatthew G. Knepley 
8975fedec97SMatthew G. Knepley   Input Parameter:
898dce8aebaSBarry Smith . ds - The `PetscDS` object
8995fedec97SMatthew G. Knepley 
9005fedec97SMatthew G. Knepley   Output Parameter:
9015fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
9025fedec97SMatthew G. Knepley 
9035fedec97SMatthew G. Knepley   Level: developer
9045fedec97SMatthew G. Knepley 
905dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
9065fedec97SMatthew G. Knepley @*/
907d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
908d71ae5a4SJacob Faibussowitsch {
9095fedec97SMatthew G. Knepley   PetscInt f;
9105fedec97SMatthew G. Knepley 
9115fedec97SMatthew G. Knepley   PetscFunctionBegin;
9125fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9134f572ea9SToby Isaac   PetscAssertPointer(numCohesive, 2);
9145fedec97SMatthew G. Knepley   *numCohesive = 0;
9155fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9175fedec97SMatthew G. Knepley }
9185fedec97SMatthew G. Knepley 
9195fedec97SMatthew G. Knepley /*@
9205fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9215fedec97SMatthew G. Knepley 
92220f4b53cSBarry Smith   Not Collective
9235fedec97SMatthew G. Knepley 
924f1a722f8SMatthew G. Knepley   Input Parameters:
925dce8aebaSBarry Smith + ds - The `PetscDS` object
9265fedec97SMatthew G. Knepley - f  - The field index
9275fedec97SMatthew G. Knepley 
9285fedec97SMatthew G. Knepley   Output Parameter:
9295fedec97SMatthew G. Knepley . isCohesive - The flag
9305fedec97SMatthew G. Knepley 
9315fedec97SMatthew G. Knepley   Level: developer
9325fedec97SMatthew G. Knepley 
933dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9345fedec97SMatthew G. Knepley @*/
935d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
936d71ae5a4SJacob Faibussowitsch {
9375fedec97SMatthew G. Knepley   PetscFunctionBegin;
9385fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9394f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 3);
94063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9415fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9435fedec97SMatthew G. Knepley }
9445fedec97SMatthew G. Knepley 
9455fedec97SMatthew G. Knepley /*@
9465fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9478edf6225SMatthew G. Knepley 
94820f4b53cSBarry Smith   Not Collective
9498edf6225SMatthew G. Knepley 
9508edf6225SMatthew G. Knepley   Input Parameters:
951dce8aebaSBarry Smith + ds         - The `PetscDS` object
9525fedec97SMatthew G. Knepley . f          - The field index
9535fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9548edf6225SMatthew G. Knepley 
9558edf6225SMatthew G. Knepley   Level: developer
9568edf6225SMatthew G. Knepley 
957dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9588edf6225SMatthew G. Knepley @*/
959d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
960d71ae5a4SJacob Faibussowitsch {
9615fedec97SMatthew G. Knepley   PetscInt i;
9625fedec97SMatthew G. Knepley 
9638edf6225SMatthew G. Knepley   PetscFunctionBegin;
9645fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
96563a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9665fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9675fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9685fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9708edf6225SMatthew G. Knepley }
9718edf6225SMatthew G. Knepley 
9728edf6225SMatthew G. Knepley /*@
973bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
974bc4ae4beSMatthew G. Knepley 
97520f4b53cSBarry Smith   Not Collective
976bc4ae4beSMatthew G. Knepley 
977bc4ae4beSMatthew G. Knepley   Input Parameter:
978dce8aebaSBarry Smith . prob - The `PetscDS` object
979bc4ae4beSMatthew G. Knepley 
980bc4ae4beSMatthew G. Knepley   Output Parameter:
981bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
982bc4ae4beSMatthew G. Knepley 
983bc4ae4beSMatthew G. Knepley   Level: beginner
984bc4ae4beSMatthew G. Knepley 
985dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
986bc4ae4beSMatthew G. Knepley @*/
987d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
988d71ae5a4SJacob Faibussowitsch {
9892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9902764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9919566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
9924f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
9932764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9952764a2aaSMatthew G. Knepley }
9962764a2aaSMatthew G. Knepley 
997bc4ae4beSMatthew G. Knepley /*@
998bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
999bc4ae4beSMatthew G. Knepley 
100020f4b53cSBarry Smith   Not Collective
1001bc4ae4beSMatthew G. Knepley 
1002bc4ae4beSMatthew G. Knepley   Input Parameter:
1003dce8aebaSBarry Smith . prob - The `PetscDS` object
1004bc4ae4beSMatthew G. Knepley 
1005bc4ae4beSMatthew G. Knepley   Output Parameter:
100660225df5SJacob Faibussowitsch . Nc - The total number of components
1007bc4ae4beSMatthew G. Knepley 
1008bc4ae4beSMatthew G. Knepley   Level: beginner
1009bc4ae4beSMatthew G. Knepley 
1010dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1011bc4ae4beSMatthew G. Knepley @*/
1012d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
1013d71ae5a4SJacob Faibussowitsch {
10142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
10174f572ea9SToby Isaac   PetscAssertPointer(Nc, 2);
10182764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10202764a2aaSMatthew G. Knepley }
10212764a2aaSMatthew G. Knepley 
1022bc4ae4beSMatthew G. Knepley /*@
1023bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1024bc4ae4beSMatthew G. Knepley 
102520f4b53cSBarry Smith   Not Collective
1026bc4ae4beSMatthew G. Knepley 
1027bc4ae4beSMatthew G. Knepley   Input Parameters:
1028dce8aebaSBarry Smith + prob - The `PetscDS` object
1029bc4ae4beSMatthew G. Knepley - f    - The field number
1030bc4ae4beSMatthew G. Knepley 
1031bc4ae4beSMatthew G. Knepley   Output Parameter:
1032bc4ae4beSMatthew G. Knepley . disc - The discretization object
1033bc4ae4beSMatthew G. Knepley 
1034bc4ae4beSMatthew G. Knepley   Level: beginner
1035bc4ae4beSMatthew G. Knepley 
1036dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1037bc4ae4beSMatthew G. Knepley @*/
1038d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1039d71ae5a4SJacob Faibussowitsch {
10406528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10412764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10424f572ea9SToby Isaac   PetscAssertPointer(disc, 3);
104363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
10442764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10462764a2aaSMatthew G. Knepley }
10472764a2aaSMatthew G. Knepley 
1048bc4ae4beSMatthew G. Knepley /*@
1049bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1050bc4ae4beSMatthew G. Knepley 
105120f4b53cSBarry Smith   Not Collective
1052bc4ae4beSMatthew G. Knepley 
1053bc4ae4beSMatthew G. Knepley   Input Parameters:
1054dce8aebaSBarry Smith + prob - The `PetscDS` object
1055bc4ae4beSMatthew G. Knepley . f    - The field number
1056bc4ae4beSMatthew G. Knepley - disc - The discretization object
1057bc4ae4beSMatthew G. Knepley 
1058bc4ae4beSMatthew G. Knepley   Level: beginner
1059bc4ae4beSMatthew G. Knepley 
1060dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1061bc4ae4beSMatthew G. Knepley @*/
1062d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1063d71ae5a4SJacob Faibussowitsch {
10642764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10652764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10664f572ea9SToby Isaac   if (disc) PetscAssertPointer(disc, 3);
106763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10689566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10699566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10702764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10719566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1072665f567fSMatthew G. Knepley   if (disc) {
1073249df284SMatthew G. Knepley     PetscClassId id;
1074249df284SMatthew G. Knepley 
10759566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10761cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10779566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10781cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10799566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1080a6cbbb48SMatthew G. Knepley     }
10819566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1082249df284SMatthew G. Knepley   }
10833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10842764a2aaSMatthew G. Knepley }
10852764a2aaSMatthew G. Knepley 
1086bc4ae4beSMatthew G. Knepley /*@
10876528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10886528b96dSMatthew G. Knepley 
108920f4b53cSBarry Smith   Not Collective
10906528b96dSMatthew G. Knepley 
10916528b96dSMatthew G. Knepley   Input Parameter:
1092dce8aebaSBarry Smith . ds - The `PetscDS` object
10936528b96dSMatthew G. Knepley 
10946528b96dSMatthew G. Knepley   Output Parameter:
10956528b96dSMatthew G. Knepley . wf - The weak form object
10966528b96dSMatthew G. Knepley 
10976528b96dSMatthew G. Knepley   Level: beginner
10986528b96dSMatthew G. Knepley 
1099dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11006528b96dSMatthew G. Knepley @*/
1101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1102d71ae5a4SJacob Faibussowitsch {
11036528b96dSMatthew G. Knepley   PetscFunctionBegin;
11046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11054f572ea9SToby Isaac   PetscAssertPointer(wf, 2);
11066528b96dSMatthew G. Knepley   *wf = ds->wf;
11073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11086528b96dSMatthew G. Knepley }
11096528b96dSMatthew G. Knepley 
11106528b96dSMatthew G. Knepley /*@
11116528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
11126528b96dSMatthew G. Knepley 
111320f4b53cSBarry Smith   Not Collective
11146528b96dSMatthew G. Knepley 
11156528b96dSMatthew G. Knepley   Input Parameters:
1116dce8aebaSBarry Smith + ds - The `PetscDS` object
11176528b96dSMatthew G. Knepley - wf - The weak form object
11186528b96dSMatthew G. Knepley 
11196528b96dSMatthew G. Knepley   Level: beginner
11206528b96dSMatthew G. Knepley 
1121dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11226528b96dSMatthew G. Knepley @*/
1123d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1124d71ae5a4SJacob Faibussowitsch {
11256528b96dSMatthew G. Knepley   PetscFunctionBegin;
11266528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11276528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11289566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11296528b96dSMatthew G. Knepley   ds->wf = wf;
11309566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11336528b96dSMatthew G. Knepley }
11346528b96dSMatthew G. Knepley 
11356528b96dSMatthew G. Knepley /*@
1136bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1137bc4ae4beSMatthew G. Knepley 
113820f4b53cSBarry Smith   Not Collective
1139bc4ae4beSMatthew G. Knepley 
1140bc4ae4beSMatthew G. Knepley   Input Parameters:
1141dce8aebaSBarry Smith + prob - The `PetscDS` object
1142bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1143bc4ae4beSMatthew G. Knepley 
1144bc4ae4beSMatthew G. Knepley   Level: beginner
1145bc4ae4beSMatthew G. Knepley 
1146dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1147bc4ae4beSMatthew G. Knepley @*/
1148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1149d71ae5a4SJacob Faibussowitsch {
11502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11532764a2aaSMatthew G. Knepley }
11542764a2aaSMatthew G. Knepley 
1155249df284SMatthew G. Knepley /*@
1156dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1157083401c6SMatthew G. Knepley 
115820f4b53cSBarry Smith   Not Collective
1159083401c6SMatthew G. Knepley 
1160083401c6SMatthew G. Knepley   Input Parameter:
1161dce8aebaSBarry Smith . prob - The `PetscDS` object
1162083401c6SMatthew G. Knepley 
1163083401c6SMatthew G. Knepley   Output Parameter:
1164083401c6SMatthew G. Knepley . q - The quadrature object
1165083401c6SMatthew G. Knepley 
1166083401c6SMatthew G. Knepley   Level: intermediate
1167083401c6SMatthew G. Knepley 
1168dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1169083401c6SMatthew G. Knepley @*/
1170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1171d71ae5a4SJacob Faibussowitsch {
1172083401c6SMatthew G. Knepley   PetscObject  obj;
1173083401c6SMatthew G. Knepley   PetscClassId id;
1174083401c6SMatthew G. Knepley 
1175083401c6SMatthew G. Knepley   PetscFunctionBegin;
1176083401c6SMatthew G. Knepley   *q = NULL;
11773ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11789566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11799566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11809566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11819566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
118298921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1184083401c6SMatthew G. Knepley }
1185083401c6SMatthew G. Knepley 
1186083401c6SMatthew G. Knepley /*@
11873dddbd81SStefano Zampini   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1188249df284SMatthew G. Knepley 
118920f4b53cSBarry Smith   Not Collective
1190249df284SMatthew G. Knepley 
1191249df284SMatthew G. Knepley   Input Parameters:
1192dce8aebaSBarry Smith + prob - The `PetscDS` object
1193249df284SMatthew G. Knepley - f    - The field number
1194249df284SMatthew G. Knepley 
1195249df284SMatthew G. Knepley   Output Parameter:
1196249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1197249df284SMatthew G. Knepley 
1198249df284SMatthew G. Knepley   Level: developer
1199249df284SMatthew G. Knepley 
12003dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1201249df284SMatthew G. Knepley @*/
1202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1203d71ae5a4SJacob Faibussowitsch {
1204249df284SMatthew G. Knepley   PetscFunctionBegin;
1205249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
12064f572ea9SToby Isaac   PetscAssertPointer(implicit, 3);
120763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1208249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
12093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1210249df284SMatthew G. Knepley }
1211249df284SMatthew G. Knepley 
1212249df284SMatthew G. Knepley /*@
12133dddbd81SStefano Zampini   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1214249df284SMatthew G. Knepley 
121520f4b53cSBarry Smith   Not Collective
1216249df284SMatthew G. Knepley 
1217249df284SMatthew G. Knepley   Input Parameters:
1218dce8aebaSBarry Smith + prob     - The `PetscDS` object
1219249df284SMatthew G. Knepley . f        - The field number
1220249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1221249df284SMatthew G. Knepley 
1222249df284SMatthew G. Knepley   Level: developer
1223249df284SMatthew G. Knepley 
12243dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1225249df284SMatthew G. Knepley @*/
1226d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1227d71ae5a4SJacob Faibussowitsch {
1228249df284SMatthew G. Knepley   PetscFunctionBegin;
1229249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
123063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1231249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1233249df284SMatthew G. Knepley }
1234249df284SMatthew G. Knepley 
1235f9244615SMatthew G. Knepley /*@
1236f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1237f9244615SMatthew G. Knepley 
123820f4b53cSBarry Smith   Not Collective
1239f9244615SMatthew G. Knepley 
1240f9244615SMatthew G. Knepley   Input Parameters:
1241dce8aebaSBarry Smith + ds - The `PetscDS` object
1242f9244615SMatthew G. Knepley - f  - The field number
1243f9244615SMatthew G. Knepley 
1244f9244615SMatthew G. Knepley   Output Parameter:
1245f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1246f9244615SMatthew G. Knepley 
1247f9244615SMatthew G. Knepley   Level: developer
1248f9244615SMatthew G. Knepley 
1249dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1250f9244615SMatthew G. Knepley @*/
1251d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1252d71ae5a4SJacob Faibussowitsch {
1253f9244615SMatthew G. Knepley   PetscFunctionBegin;
1254f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12554f572ea9SToby Isaac   PetscAssertPointer(k, 3);
125663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1257f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1259f9244615SMatthew G. Knepley }
1260f9244615SMatthew G. Knepley 
1261f9244615SMatthew G. Knepley /*@
1262f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1263f9244615SMatthew G. Knepley 
126420f4b53cSBarry Smith   Not Collective
1265f9244615SMatthew G. Knepley 
1266f9244615SMatthew G. Knepley   Input Parameters:
1267dce8aebaSBarry Smith + ds - The `PetscDS` object
1268f9244615SMatthew G. Knepley . f  - The field number
1269f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1270f9244615SMatthew G. Knepley 
1271f9244615SMatthew G. Knepley   Level: developer
1272f9244615SMatthew G. Knepley 
1273a94f484eSPierre Jolivet .seealso: `PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1274f9244615SMatthew G. Knepley @*/
1275d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1276d71ae5a4SJacob Faibussowitsch {
1277f9244615SMatthew G. Knepley   PetscFunctionBegin;
1278f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
127963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1280f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1282f9244615SMatthew G. Knepley }
1283f9244615SMatthew G. Knepley 
1284c8943706SMatthew G. Knepley /*@C
1285c8943706SMatthew G. Knepley   PetscDSGetObjective - Get the pointwise objective function for a given test field
1286c8943706SMatthew G. Knepley 
1287c8943706SMatthew G. Knepley   Not Collective
1288c8943706SMatthew G. Knepley 
1289c8943706SMatthew G. Knepley   Input Parameters:
1290c8943706SMatthew G. Knepley + ds - The `PetscDS`
1291c8943706SMatthew G. Knepley - f  - The test field number
1292c8943706SMatthew G. Knepley 
1293a4e35b19SJacob Faibussowitsch   Output Parameter:
1294c8943706SMatthew G. Knepley . obj - integrand for the test function term
1295c8943706SMatthew G. Knepley 
1296c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1297c8943706SMatthew G. Knepley + dim          - the spatial dimension
1298c8943706SMatthew G. Knepley . Nf           - the number of fields
1299a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1300c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1301c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1302c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1303c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1304c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1305c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1306c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1307c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1308c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1309c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1310c8943706SMatthew G. Knepley . t            - current time
1311c8943706SMatthew G. Knepley . x            - coordinates of the current point
1312c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1313c8943706SMatthew G. Knepley . constants    - constant parameters
1314c8943706SMatthew G. Knepley - obj          - output values at the current point
1315c8943706SMatthew G. Knepley 
1316c8943706SMatthew G. Knepley   Level: intermediate
1317c8943706SMatthew G. Knepley 
1318c8943706SMatthew G. Knepley   Note:
13191702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1320c8943706SMatthew G. Knepley 
1321c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1322c8943706SMatthew G. Knepley @*/
1323d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f, void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1324d71ae5a4SJacob Faibussowitsch {
13256528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13266528b96dSMatthew G. Knepley   PetscInt        n;
13276528b96dSMatthew G. Knepley 
13282764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13296528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13304f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
133163a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
13329566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13336528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13352764a2aaSMatthew G. Knepley }
13362764a2aaSMatthew G. Knepley 
1337c8943706SMatthew G. Knepley /*@C
1338c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1339c8943706SMatthew G. Knepley 
1340c8943706SMatthew G. Knepley   Not Collective
1341c8943706SMatthew G. Knepley 
1342c8943706SMatthew G. Knepley   Input Parameters:
1343c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1344c8943706SMatthew G. Knepley . f   - The test field number
1345c8943706SMatthew G. Knepley - obj - integrand for the test function term
1346c8943706SMatthew G. Knepley 
1347c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1348c8943706SMatthew G. Knepley + dim          - the spatial dimension
1349c8943706SMatthew G. Knepley . Nf           - the number of fields
1350a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1351c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1352c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1353c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1354c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1355c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1356c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1357c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1358c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1359c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1360c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1361c8943706SMatthew G. Knepley . t            - current time
1362c8943706SMatthew G. Knepley . x            - coordinates of the current point
1363c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1364c8943706SMatthew G. Knepley . constants    - constant parameters
1365c8943706SMatthew G. Knepley - obj          - output values at the current point
1366c8943706SMatthew G. Knepley 
1367c8943706SMatthew G. Knepley   Level: intermediate
1368c8943706SMatthew G. Knepley 
1369c8943706SMatthew G. Knepley   Note:
13701702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1371c8943706SMatthew G. Knepley 
1372c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1373c8943706SMatthew G. Knepley @*/
1374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f, void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1375d71ae5a4SJacob Faibussowitsch {
13762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13786528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
137963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13822764a2aaSMatthew G. Knepley }
13832764a2aaSMatthew G. Knepley 
1384194d53e6SMatthew G. Knepley /*@C
1385194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1386194d53e6SMatthew G. Knepley 
138720f4b53cSBarry Smith   Not Collective
1388194d53e6SMatthew G. Knepley 
1389194d53e6SMatthew G. Knepley   Input Parameters:
1390dce8aebaSBarry Smith + ds - The `PetscDS`
1391194d53e6SMatthew G. Knepley - f  - The test field number
1392194d53e6SMatthew G. Knepley 
1393194d53e6SMatthew G. Knepley   Output Parameters:
1394194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1395194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1396194d53e6SMatthew G. Knepley 
1397a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1398194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1399194d53e6SMatthew G. Knepley . Nf           - the number of fields
1400a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1401194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1402194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1403194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1404194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1405194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1406194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1407194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1408194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1409194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1410194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1411194d53e6SMatthew G. Knepley . t            - current time
1412194d53e6SMatthew G. Knepley . x            - coordinates of the current point
141397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
141497b6e6e8SMatthew G. Knepley . constants    - constant parameters
1415194d53e6SMatthew G. Knepley - f0           - output values at the current point
1416194d53e6SMatthew G. Knepley 
1417194d53e6SMatthew G. Knepley   Level: intermediate
1418194d53e6SMatthew G. Knepley 
1419dce8aebaSBarry Smith   Note:
1420a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1421a4e35b19SJacob Faibussowitsch 
14221d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1423dce8aebaSBarry Smith 
1424dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1425194d53e6SMatthew G. Knepley @*/
1426a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1427d71ae5a4SJacob Faibussowitsch {
14286528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14296528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14306528b96dSMatthew G. Knepley 
14312764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
143363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
14349566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14356528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14366528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14382764a2aaSMatthew G. Knepley }
14392764a2aaSMatthew G. Knepley 
1440194d53e6SMatthew G. Knepley /*@C
1441194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1442194d53e6SMatthew G. Knepley 
144320f4b53cSBarry Smith   Not Collective
1444194d53e6SMatthew G. Knepley 
1445194d53e6SMatthew G. Knepley   Input Parameters:
1446dce8aebaSBarry Smith + ds - The `PetscDS`
1447194d53e6SMatthew G. Knepley . f  - The test field number
1448194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1449194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1450194d53e6SMatthew G. Knepley 
1451a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1452194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1453194d53e6SMatthew G. Knepley . Nf           - the number of fields
1454a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1455194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1456194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1457194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1458194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1459194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1460194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1461194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1462194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1463194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1464194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1465194d53e6SMatthew G. Knepley . t            - current time
1466194d53e6SMatthew G. Knepley . x            - coordinates of the current point
146797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
146897b6e6e8SMatthew G. Knepley . constants    - constant parameters
1469194d53e6SMatthew G. Knepley - f0           - output values at the current point
1470194d53e6SMatthew G. Knepley 
1471194d53e6SMatthew G. Knepley   Level: intermediate
1472194d53e6SMatthew G. Knepley 
1473dce8aebaSBarry Smith   Note:
1474a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1475a4e35b19SJacob Faibussowitsch 
14761d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1477dce8aebaSBarry Smith 
1478dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1479194d53e6SMatthew G. Knepley @*/
1480a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1481d71ae5a4SJacob Faibussowitsch {
14822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14836528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1484f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1485f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
148663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14879566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14892764a2aaSMatthew G. Knepley }
14902764a2aaSMatthew G. Knepley 
14913e75805dSMatthew G. Knepley /*@C
1492cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1493cb36c0f9SMatthew G. Knepley 
149420f4b53cSBarry Smith   Not Collective
1495cb36c0f9SMatthew G. Knepley 
1496cb36c0f9SMatthew G. Knepley   Input Parameters:
1497dce8aebaSBarry Smith + ds - The `PetscDS`
1498cb36c0f9SMatthew G. Knepley - f  - The test field number
1499cb36c0f9SMatthew G. Knepley 
1500cb36c0f9SMatthew G. Knepley   Output Parameters:
1501cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1502cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1503cb36c0f9SMatthew G. Knepley 
1504a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1505cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1506cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1507a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1508cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1509cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1510cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1511cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1512cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1513cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1514cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1515cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1516cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1517cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1518cb36c0f9SMatthew G. Knepley . t            - current time
1519cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1520cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1521cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1522cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1523cb36c0f9SMatthew G. Knepley 
1524cb36c0f9SMatthew G. Knepley   Level: intermediate
1525cb36c0f9SMatthew G. Knepley 
1526dce8aebaSBarry Smith   Note:
1527a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1528a4e35b19SJacob Faibussowitsch 
15291d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $ \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1530dce8aebaSBarry Smith 
1531dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1532cb36c0f9SMatthew G. Knepley @*/
1533a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1534d71ae5a4SJacob Faibussowitsch {
1535cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1536cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1537cb36c0f9SMatthew G. Knepley 
1538cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1539cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
154063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
15419566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1542cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1543cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1545cb36c0f9SMatthew G. Knepley }
1546cb36c0f9SMatthew G. Knepley 
1547cb36c0f9SMatthew G. Knepley /*@C
1548cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1549cb36c0f9SMatthew G. Knepley 
155020f4b53cSBarry Smith   Not Collective
1551cb36c0f9SMatthew G. Knepley 
1552cb36c0f9SMatthew G. Knepley   Input Parameters:
1553dce8aebaSBarry Smith + ds - The `PetscDS`
1554cb36c0f9SMatthew G. Knepley . f  - The test field number
1555cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1556cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1557cb36c0f9SMatthew G. Knepley 
1558a4e35b19SJacob Faibussowitsch   Calling sequence for the callbacks `f0`:
1559cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1560cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1561a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1562cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1563cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1564cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1565cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1566cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1567cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1568cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1569cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1570cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1571cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1572cb36c0f9SMatthew G. Knepley . t            - current time
1573cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1574cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1575cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1576cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1577cb36c0f9SMatthew G. Knepley 
1578cb36c0f9SMatthew G. Knepley   Level: intermediate
1579cb36c0f9SMatthew G. Knepley 
1580dce8aebaSBarry Smith   Note:
1581a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1582a4e35b19SJacob Faibussowitsch 
15831d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $ \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)$
1584dce8aebaSBarry Smith 
1585dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1586cb36c0f9SMatthew G. Knepley @*/
1587a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1588d71ae5a4SJacob Faibussowitsch {
1589cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1590cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1591cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1592cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
159363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1596cb36c0f9SMatthew G. Knepley }
1597cb36c0f9SMatthew G. Knepley 
1598cc4c1da9SBarry Smith /*@
1599dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
16003e75805dSMatthew G. Knepley 
160120f4b53cSBarry Smith   Not Collective
16023e75805dSMatthew G. Knepley 
16033e75805dSMatthew G. Knepley   Input Parameter:
160460225df5SJacob Faibussowitsch . ds - The `PetscDS`
16053e75805dSMatthew G. Knepley 
16063e75805dSMatthew G. Knepley   Output Parameter:
16073e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
16083e75805dSMatthew G. Knepley 
16093e75805dSMatthew G. Knepley   Level: intermediate
16103e75805dSMatthew G. Knepley 
1611dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
16123e75805dSMatthew G. Knepley @*/
1613d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1614d71ae5a4SJacob Faibussowitsch {
16153e75805dSMatthew G. Knepley   PetscFunctionBegin;
16166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16193e75805dSMatthew G. Knepley }
16203e75805dSMatthew G. Knepley 
1621194d53e6SMatthew G. Knepley /*@C
1622194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1623194d53e6SMatthew G. Knepley 
162420f4b53cSBarry Smith   Not Collective
1625194d53e6SMatthew G. Knepley 
1626194d53e6SMatthew G. Knepley   Input Parameters:
1627dce8aebaSBarry Smith + ds - The `PetscDS`
1628194d53e6SMatthew G. Knepley . f  - The test field number
1629194d53e6SMatthew G. Knepley - g  - The field number
1630194d53e6SMatthew G. Knepley 
1631194d53e6SMatthew G. Knepley   Output Parameters:
1632194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1633194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1634194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1635194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1636194d53e6SMatthew G. Knepley 
1637a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1638194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1639194d53e6SMatthew G. Knepley . Nf           - the number of fields
1640a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1641194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1642194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1643194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1644194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1645194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1646194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1647194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1648194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1649194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1650194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1651194d53e6SMatthew G. Knepley . t            - current time
16522aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1653194d53e6SMatthew G. Knepley . x            - coordinates of the current point
165497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
165597b6e6e8SMatthew G. Knepley . constants    - constant parameters
1656194d53e6SMatthew G. Knepley - g0           - output values at the current point
1657194d53e6SMatthew G. Knepley 
1658194d53e6SMatthew G. Knepley   Level: intermediate
1659194d53e6SMatthew G. Knepley 
1660dce8aebaSBarry Smith   Note:
1661a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
166260225df5SJacob Faibussowitsch 
1663a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16641d27aa22SBarry Smith 
16651d27aa22SBarry Smith   $$
16661702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
16671702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
16681d27aa22SBarry Smith   $$
1669dce8aebaSBarry Smith 
1670dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1671194d53e6SMatthew G. Knepley @*/
1672a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1673d71ae5a4SJacob Faibussowitsch {
16746528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16756528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16766528b96dSMatthew G. Knepley 
16772764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
167963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
168063a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
16819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16826528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16836528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16846528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16856528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16872764a2aaSMatthew G. Knepley }
16882764a2aaSMatthew G. Knepley 
1689194d53e6SMatthew G. Knepley /*@C
1690194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1691194d53e6SMatthew G. Knepley 
169220f4b53cSBarry Smith   Not Collective
1693194d53e6SMatthew G. Knepley 
1694194d53e6SMatthew G. Knepley   Input Parameters:
1695dce8aebaSBarry Smith + ds - The `PetscDS`
1696194d53e6SMatthew G. Knepley . f  - The test field number
1697194d53e6SMatthew G. Knepley . g  - The field number
1698194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1699194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1700194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1701194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1702194d53e6SMatthew G. Knepley 
1703a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1704194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1705194d53e6SMatthew G. Knepley . Nf           - the number of fields
1706a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1707194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1708194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1709194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1710194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1711194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1712194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1713194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1714194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1715194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1716194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1717194d53e6SMatthew G. Knepley . t            - current time
17182aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1719194d53e6SMatthew G. Knepley . x            - coordinates of the current point
172097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
172197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1722194d53e6SMatthew G. Knepley - g0           - output values at the current point
1723194d53e6SMatthew G. Knepley 
1724194d53e6SMatthew G. Knepley   Level: intermediate
1725194d53e6SMatthew G. Knepley 
1726dce8aebaSBarry Smith   Note:
1727a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
172860225df5SJacob Faibussowitsch 
1729a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
17301702e181SMatthew Knepley 
17311702e181SMatthew Knepley   $$
17321702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
17331702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
17341702e181SMatthew Knepley   $$
1735dce8aebaSBarry Smith 
1736dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1737194d53e6SMatthew G. Knepley @*/
1738a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1739d71ae5a4SJacob Faibussowitsch {
17402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17416528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17422764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17432764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17442764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17452764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
174663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
174763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17489566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17502764a2aaSMatthew G. Knepley }
17512764a2aaSMatthew G. Knepley 
1752cc4c1da9SBarry Smith /*@
1753dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
175455c1f793SMatthew G. Knepley 
175520f4b53cSBarry Smith   Not Collective
175655c1f793SMatthew G. Knepley 
175755c1f793SMatthew G. Knepley   Input Parameters:
1758dce8aebaSBarry Smith + prob      - The `PetscDS`
175955c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
176055c1f793SMatthew G. Knepley 
176155c1f793SMatthew G. Knepley   Level: intermediate
176255c1f793SMatthew G. Knepley 
1763cc4c1da9SBarry Smith   Developer Note:
1764cc4c1da9SBarry Smith   Should be called `PetscDSSetUseJacobianPreconditioner()`
1765cc4c1da9SBarry Smith 
1766dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
176755c1f793SMatthew G. Knepley @*/
1768d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1769d71ae5a4SJacob Faibussowitsch {
177055c1f793SMatthew G. Knepley   PetscFunctionBegin;
177155c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
177255c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
177455c1f793SMatthew G. Knepley }
177555c1f793SMatthew G. Knepley 
1776cc4c1da9SBarry Smith /*@
1777dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1778475e0ac9SMatthew G. Knepley 
177920f4b53cSBarry Smith   Not Collective
1780475e0ac9SMatthew G. Knepley 
1781475e0ac9SMatthew G. Knepley   Input Parameter:
178260225df5SJacob Faibussowitsch . ds - The `PetscDS`
1783475e0ac9SMatthew G. Knepley 
1784475e0ac9SMatthew G. Knepley   Output Parameter:
1785475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1786475e0ac9SMatthew G. Knepley 
1787475e0ac9SMatthew G. Knepley   Level: intermediate
1788475e0ac9SMatthew G. Knepley 
1789dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1790475e0ac9SMatthew G. Knepley @*/
1791d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1792d71ae5a4SJacob Faibussowitsch {
1793475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17946528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1795475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17963ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1799475e0ac9SMatthew G. Knepley }
1800475e0ac9SMatthew G. Knepley 
1801475e0ac9SMatthew G. Knepley /*@C
1802dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1803dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1804475e0ac9SMatthew G. Knepley 
180520f4b53cSBarry Smith   Not Collective
1806475e0ac9SMatthew G. Knepley 
1807475e0ac9SMatthew G. Knepley   Input Parameters:
1808dce8aebaSBarry Smith + ds - The `PetscDS`
1809475e0ac9SMatthew G. Knepley . f  - The test field number
1810475e0ac9SMatthew G. Knepley - g  - The field number
1811475e0ac9SMatthew G. Knepley 
1812475e0ac9SMatthew G. Knepley   Output Parameters:
1813475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1814475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1815475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1816475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1817475e0ac9SMatthew G. Knepley 
1818a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1819475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1820475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1821a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1822475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1823475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1824475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1825475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1826475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1827475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1828475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1829475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1830475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1831475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1832475e0ac9SMatthew G. Knepley . t            - current time
1833475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1834475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
183597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
183697b6e6e8SMatthew G. Knepley . constants    - constant parameters
1837475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1838475e0ac9SMatthew G. Knepley 
1839475e0ac9SMatthew G. Knepley   Level: intermediate
1840475e0ac9SMatthew G. Knepley 
1841dce8aebaSBarry Smith   Note:
1842a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1843a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
18441702e181SMatthew Knepley 
18451702e181SMatthew Knepley   $$
18461702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
18471702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
18481702e181SMatthew Knepley   $$
1849dce8aebaSBarry Smith 
1850dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1851475e0ac9SMatthew G. Knepley @*/
1852a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1853d71ae5a4SJacob Faibussowitsch {
18546528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18556528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18566528b96dSMatthew G. Knepley 
1857475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18586528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
185963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
186063a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
18619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18626528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18636528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18646528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18656528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1867475e0ac9SMatthew G. Knepley }
1868475e0ac9SMatthew G. Knepley 
1869475e0ac9SMatthew G. Knepley /*@C
1870dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1871dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1872475e0ac9SMatthew G. Knepley 
187320f4b53cSBarry Smith   Not Collective
1874475e0ac9SMatthew G. Knepley 
1875475e0ac9SMatthew G. Knepley   Input Parameters:
1876dce8aebaSBarry Smith + ds - The `PetscDS`
1877475e0ac9SMatthew G. Knepley . f  - The test field number
1878475e0ac9SMatthew G. Knepley . g  - The field number
1879475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1880475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1881475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1882475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1883475e0ac9SMatthew G. Knepley 
1884a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1885475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1886475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1887a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1888475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1889475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1890475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1891475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1892475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1893475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1894475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1895475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1896475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1897475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1898475e0ac9SMatthew G. Knepley . t            - current time
1899475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1900475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
190197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
190297b6e6e8SMatthew G. Knepley . constants    - constant parameters
1903475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1904475e0ac9SMatthew G. Knepley 
1905475e0ac9SMatthew G. Knepley   Level: intermediate
1906475e0ac9SMatthew G. Knepley 
1907dce8aebaSBarry Smith   Note:
1908a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
190960225df5SJacob Faibussowitsch 
1910a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
19111702e181SMatthew Knepley 
19121702e181SMatthew Knepley   $$
19131702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
19141702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
19151702e181SMatthew Knepley   $$
1916dce8aebaSBarry Smith 
1917dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1918475e0ac9SMatthew G. Knepley @*/
1919a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1920d71ae5a4SJacob Faibussowitsch {
1921475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
19226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1923475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1924475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1925475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1926475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
192763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
192863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1931475e0ac9SMatthew G. Knepley }
1932475e0ac9SMatthew G. Knepley 
1933cc4c1da9SBarry Smith /*@
1934b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1935b7e05686SMatthew G. Knepley 
193620f4b53cSBarry Smith   Not Collective
1937b7e05686SMatthew G. Knepley 
1938b7e05686SMatthew G. Knepley   Input Parameter:
1939dce8aebaSBarry Smith . ds - The `PetscDS`
1940b7e05686SMatthew G. Knepley 
1941b7e05686SMatthew G. Knepley   Output Parameter:
1942b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1943b7e05686SMatthew G. Knepley 
1944b7e05686SMatthew G. Knepley   Level: intermediate
1945b7e05686SMatthew G. Knepley 
1946dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1947b7e05686SMatthew G. Knepley @*/
1948d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1949d71ae5a4SJacob Faibussowitsch {
1950b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19516528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19529566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1954b7e05686SMatthew G. Knepley }
1955b7e05686SMatthew G. Knepley 
1956b7e05686SMatthew G. Knepley /*@C
1957b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1958b7e05686SMatthew G. Knepley 
195920f4b53cSBarry Smith   Not Collective
1960b7e05686SMatthew G. Knepley 
1961b7e05686SMatthew G. Knepley   Input Parameters:
1962dce8aebaSBarry Smith + ds - The `PetscDS`
1963b7e05686SMatthew G. Knepley . f  - The test field number
1964b7e05686SMatthew G. Knepley - g  - The field number
1965b7e05686SMatthew G. Knepley 
1966b7e05686SMatthew G. Knepley   Output Parameters:
1967b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1968b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1969b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1970b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1971b7e05686SMatthew G. Knepley 
1972a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1973b7e05686SMatthew G. Knepley + dim          - the spatial dimension
1974b7e05686SMatthew G. Knepley . Nf           - the number of fields
1975a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1976b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1977b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1978b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1979b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1980b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1981b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1982b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1983b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1984b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1985b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1986b7e05686SMatthew G. Knepley . t            - current time
1987b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1988b7e05686SMatthew G. Knepley . x            - coordinates of the current point
198997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
199097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1991b7e05686SMatthew G. Knepley - g0           - output values at the current point
1992b7e05686SMatthew G. Knepley 
1993b7e05686SMatthew G. Knepley   Level: intermediate
1994b7e05686SMatthew G. Knepley 
1995dce8aebaSBarry Smith   Note:
1996a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
199760225df5SJacob Faibussowitsch 
1998a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
19991702e181SMatthew Knepley 
20001702e181SMatthew Knepley   $$
20011702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
20021702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
20031702e181SMatthew Knepley   $$
2004dce8aebaSBarry Smith 
2005dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
2006b7e05686SMatthew G. Knepley @*/
2007a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2008d71ae5a4SJacob Faibussowitsch {
20096528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
20106528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
20116528b96dSMatthew G. Knepley 
2012b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
201463a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
201563a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
20169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
20176528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
20186528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
20196528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
20206528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
20213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2022b7e05686SMatthew G. Knepley }
2023b7e05686SMatthew G. Knepley 
2024b7e05686SMatthew G. Knepley /*@C
2025b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
2026b7e05686SMatthew G. Knepley 
202720f4b53cSBarry Smith   Not Collective
2028b7e05686SMatthew G. Knepley 
2029b7e05686SMatthew G. Knepley   Input Parameters:
2030dce8aebaSBarry Smith + ds - The `PetscDS`
2031b7e05686SMatthew G. Knepley . f  - The test field number
2032b7e05686SMatthew G. Knepley . g  - The field number
2033b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2034b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2035b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2036b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2037b7e05686SMatthew G. Knepley 
2038a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2039b7e05686SMatthew G. Knepley + dim          - the spatial dimension
2040b7e05686SMatthew G. Knepley . Nf           - the number of fields
2041a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2042b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2043b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2044b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2045b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2046b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2047b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2048b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2049b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2050b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2051b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2052b7e05686SMatthew G. Knepley . t            - current time
2053b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2054b7e05686SMatthew G. Knepley . x            - coordinates of the current point
205597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
205697b6e6e8SMatthew G. Knepley . constants    - constant parameters
2057b7e05686SMatthew G. Knepley - g0           - output values at the current point
2058b7e05686SMatthew G. Knepley 
2059b7e05686SMatthew G. Knepley   Level: intermediate
2060b7e05686SMatthew G. Knepley 
2061dce8aebaSBarry Smith   Note:
2062a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
206360225df5SJacob Faibussowitsch 
2064a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
20651702e181SMatthew Knepley 
20661702e181SMatthew Knepley   $$
20671702e181SMatthew Knepley   \int_\Omega \phi\, g_0(u, u_t, \nabla u, x, t) \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi
20681702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
20691702e181SMatthew Knepley   $$
2070dce8aebaSBarry Smith 
2071dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2072b7e05686SMatthew G. Knepley @*/
2073a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2074d71ae5a4SJacob Faibussowitsch {
2075b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2077b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2078b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2079b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2080b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
208163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
208263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2085b7e05686SMatthew G. Knepley }
2086b7e05686SMatthew G. Knepley 
20870c2f2876SMatthew G. Knepley /*@C
20880c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20890c2f2876SMatthew G. Knepley 
209020f4b53cSBarry Smith   Not Collective
20910c2f2876SMatthew G. Knepley 
20924165533cSJose E. Roman   Input Parameters:
2093dce8aebaSBarry Smith + ds - The `PetscDS` object
20940c2f2876SMatthew G. Knepley - f  - The field number
20950c2f2876SMatthew G. Knepley 
20964165533cSJose E. Roman   Output Parameter:
20970c2f2876SMatthew G. Knepley . r - Riemann solver
20980c2f2876SMatthew G. Knepley 
209920f4b53cSBarry Smith   Calling sequence of `r`:
21005db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21015db36cf9SMatthew G. Knepley . Nf           - The number of fields
21025db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21030c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21040c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21050c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21060c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
210797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
210897b6e6e8SMatthew G. Knepley . constants    - constant parameters
21090c2f2876SMatthew G. Knepley - ctx          - optional user context
21100c2f2876SMatthew G. Knepley 
21110c2f2876SMatthew G. Knepley   Level: intermediate
21120c2f2876SMatthew G. Knepley 
2113dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
21140c2f2876SMatthew G. Knepley @*/
2115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f, void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2116d71ae5a4SJacob Faibussowitsch {
21176528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
21186528b96dSMatthew G. Knepley   PetscInt          n;
21196528b96dSMatthew G. Knepley 
21200c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21224f572ea9SToby Isaac   PetscAssertPointer(r, 3);
212363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
21249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
21256528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
21263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21270c2f2876SMatthew G. Knepley }
21280c2f2876SMatthew G. Knepley 
21290c2f2876SMatthew G. Knepley /*@C
21300c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
21310c2f2876SMatthew G. Knepley 
213220f4b53cSBarry Smith   Not Collective
21330c2f2876SMatthew G. Knepley 
21344165533cSJose E. Roman   Input Parameters:
2135dce8aebaSBarry Smith + ds - The `PetscDS` object
21360c2f2876SMatthew G. Knepley . f  - The field number
21370c2f2876SMatthew G. Knepley - r  - Riemann solver
21380c2f2876SMatthew G. Knepley 
213920f4b53cSBarry Smith   Calling sequence of `r`:
21405db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21415db36cf9SMatthew G. Knepley . Nf           - The number of fields
21425db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21430c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21440c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21450c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21460c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
214797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
214897b6e6e8SMatthew G. Knepley . constants    - constant parameters
21490c2f2876SMatthew G. Knepley - ctx          - optional user context
21500c2f2876SMatthew G. Knepley 
21510c2f2876SMatthew G. Knepley   Level: intermediate
21520c2f2876SMatthew G. Knepley 
2153dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21540c2f2876SMatthew G. Knepley @*/
2155d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f, void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2156d71ae5a4SJacob Faibussowitsch {
21570c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21586528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2159de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
216063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21630c2f2876SMatthew G. Knepley }
21640c2f2876SMatthew G. Knepley 
216532d2bbc9SMatthew G. Knepley /*@C
216632d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
216732d2bbc9SMatthew G. Knepley 
216820f4b53cSBarry Smith   Not Collective
216932d2bbc9SMatthew G. Knepley 
217032d2bbc9SMatthew G. Knepley   Input Parameters:
2171dce8aebaSBarry Smith + ds - The `PetscDS`
217232d2bbc9SMatthew G. Knepley - f  - The field number
217332d2bbc9SMatthew G. Knepley 
2174f899ff85SJose E. Roman   Output Parameter:
2175a2b725a8SWilliam Gropp . update - update function
217632d2bbc9SMatthew G. Knepley 
217720f4b53cSBarry Smith   Calling sequence of `update`:
217832d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
217932d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2180a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
218132d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
218232d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
218332d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
218432d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
218532d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
218632d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
218732d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
218832d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
218932d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
219032d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
219132d2bbc9SMatthew G. Knepley . t            - current time
219232d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2193a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2194a4e35b19SJacob Faibussowitsch . constants    - constant parameters
219532d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
219632d2bbc9SMatthew G. Knepley 
219732d2bbc9SMatthew G. Knepley   Level: intermediate
219832d2bbc9SMatthew G. Knepley 
2199dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
220032d2bbc9SMatthew G. Knepley @*/
2201d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f, void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2202d71ae5a4SJacob Faibussowitsch {
220332d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
220563a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
22069371c9d4SSatish Balay   if (update) {
22074f572ea9SToby Isaac     PetscAssertPointer(update, 3);
22089371c9d4SSatish Balay     *update = ds->update[f];
22099371c9d4SSatish Balay   }
22103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
221132d2bbc9SMatthew G. Knepley }
221232d2bbc9SMatthew G. Knepley 
221332d2bbc9SMatthew G. Knepley /*@C
22143fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
221532d2bbc9SMatthew G. Knepley 
221620f4b53cSBarry Smith   Not Collective
221732d2bbc9SMatthew G. Knepley 
221832d2bbc9SMatthew G. Knepley   Input Parameters:
2219dce8aebaSBarry Smith + ds     - The `PetscDS`
222032d2bbc9SMatthew G. Knepley . f      - The field number
222132d2bbc9SMatthew G. Knepley - update - update function
222232d2bbc9SMatthew G. Knepley 
222320f4b53cSBarry Smith   Calling sequence of `update`:
222432d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
222532d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2226a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
222732d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
222832d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
222932d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
223032d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
223132d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
223232d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
223332d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
223432d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
223532d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
223632d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
223732d2bbc9SMatthew G. Knepley . t            - current time
223832d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2239a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2240a4e35b19SJacob Faibussowitsch . constants    - constant parameters
224132d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
224232d2bbc9SMatthew G. Knepley 
224332d2bbc9SMatthew G. Knepley   Level: intermediate
224432d2bbc9SMatthew G. Knepley 
2245dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
224632d2bbc9SMatthew G. Knepley @*/
2247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f, void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2248d71ae5a4SJacob Faibussowitsch {
224932d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22506528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225132d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
225263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22539566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22546528b96dSMatthew G. Knepley   ds->update[f] = update;
22553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
225632d2bbc9SMatthew G. Knepley }
225732d2bbc9SMatthew G. Knepley 
2258d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2259d71ae5a4SJacob Faibussowitsch {
22600c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22616528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
226263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
22634f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22643ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22660c2f2876SMatthew G. Knepley }
22670c2f2876SMatthew G. Knepley 
2268d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2269d71ae5a4SJacob Faibussowitsch {
22700c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22716528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
227263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22739566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22746528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22760c2f2876SMatthew G. Knepley }
22770c2f2876SMatthew G. Knepley 
2278194d53e6SMatthew G. Knepley /*@C
2279194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2280194d53e6SMatthew G. Knepley 
228120f4b53cSBarry Smith   Not Collective
2282194d53e6SMatthew G. Knepley 
2283194d53e6SMatthew G. Knepley   Input Parameters:
22846528b96dSMatthew G. Knepley + ds - The PetscDS
2285194d53e6SMatthew G. Knepley - f  - The test field number
2286194d53e6SMatthew G. Knepley 
2287194d53e6SMatthew G. Knepley   Output Parameters:
2288194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2289194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2290194d53e6SMatthew G. Knepley 
2291a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2292194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2293194d53e6SMatthew G. Knepley . Nf           - the number of fields
2294a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2295194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2296194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2297194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2298194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2299194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2300194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2301194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2302194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2303194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2304194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2305194d53e6SMatthew G. Knepley . t            - current time
2306194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2307194d53e6SMatthew G. Knepley . n            - unit normal at the current point
230897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
230997b6e6e8SMatthew G. Knepley . constants    - constant parameters
2310194d53e6SMatthew G. Knepley - f0           - output values at the current point
2311194d53e6SMatthew G. Knepley 
2312194d53e6SMatthew G. Knepley   Level: intermediate
2313194d53e6SMatthew G. Knepley 
2314dce8aebaSBarry Smith   Note:
2315a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
231660225df5SJacob Faibussowitsch 
2317a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
23181702e181SMatthew Knepley 
23191702e181SMatthew Knepley   $$
2320dce8aebaSBarry Smith   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n
23211702e181SMatthew Knepley   $$
2322dce8aebaSBarry Smith 
2323dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2324194d53e6SMatthew G. Knepley @*/
2325a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2326d71ae5a4SJacob Faibussowitsch {
23276528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
23286528b96dSMatthew G. Knepley   PetscInt          n0, n1;
23296528b96dSMatthew G. Knepley 
23302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
233263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
23339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
23346528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
23356528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
23363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23372764a2aaSMatthew G. Knepley }
23382764a2aaSMatthew G. Knepley 
2339194d53e6SMatthew G. Knepley /*@C
2340194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2341194d53e6SMatthew G. Knepley 
234220f4b53cSBarry Smith   Not Collective
2343194d53e6SMatthew G. Knepley 
2344194d53e6SMatthew G. Knepley   Input Parameters:
2345dce8aebaSBarry Smith + ds - The `PetscDS`
2346194d53e6SMatthew G. Knepley . f  - The test field number
2347194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2348194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2349194d53e6SMatthew G. Knepley 
2350a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2351194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2352194d53e6SMatthew G. Knepley . Nf           - the number of fields
2353a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2354194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2355194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2356194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2357194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2358194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2359194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2360194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2361194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2362194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2363194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2364194d53e6SMatthew G. Knepley . t            - current time
2365194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2366194d53e6SMatthew G. Knepley . n            - unit normal at the current point
236797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
236897b6e6e8SMatthew G. Knepley . constants    - constant parameters
2369194d53e6SMatthew G. Knepley - f0           - output values at the current point
2370194d53e6SMatthew G. Knepley 
2371194d53e6SMatthew G. Knepley   Level: intermediate
2372194d53e6SMatthew G. Knepley 
2373dce8aebaSBarry Smith   Note:
2374a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
237560225df5SJacob Faibussowitsch 
2376a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
23771702e181SMatthew Knepley 
23781702e181SMatthew Knepley   $$
2379dce8aebaSBarry Smith   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n
23801702e181SMatthew Knepley   $$
2381dce8aebaSBarry Smith 
2382dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2383194d53e6SMatthew G. Knepley @*/
2384a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2385d71ae5a4SJacob Faibussowitsch {
23862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
238863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23912764a2aaSMatthew G. Knepley }
23922764a2aaSMatthew G. Knepley 
239327f02ce8SMatthew G. Knepley /*@
2394dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
239527f02ce8SMatthew G. Knepley 
239620f4b53cSBarry Smith   Not Collective
239727f02ce8SMatthew G. Knepley 
239827f02ce8SMatthew G. Knepley   Input Parameter:
2399dce8aebaSBarry Smith . ds - The `PetscDS`
240027f02ce8SMatthew G. Knepley 
240127f02ce8SMatthew G. Knepley   Output Parameter:
240227f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
240327f02ce8SMatthew G. Knepley 
240427f02ce8SMatthew G. Knepley   Level: intermediate
240527f02ce8SMatthew G. Knepley 
2406dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
240727f02ce8SMatthew G. Knepley @*/
2408d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2409d71ae5a4SJacob Faibussowitsch {
241027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24116528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24124f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
24139566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
24143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
241527f02ce8SMatthew G. Knepley }
241627f02ce8SMatthew G. Knepley 
2417194d53e6SMatthew G. Knepley /*@C
2418194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2419194d53e6SMatthew G. Knepley 
242020f4b53cSBarry Smith   Not Collective
2421194d53e6SMatthew G. Knepley 
2422194d53e6SMatthew G. Knepley   Input Parameters:
2423dce8aebaSBarry Smith + ds - The `PetscDS`
2424194d53e6SMatthew G. Knepley . f  - The test field number
2425194d53e6SMatthew G. Knepley - g  - The field number
2426194d53e6SMatthew G. Knepley 
2427194d53e6SMatthew G. Knepley   Output Parameters:
2428194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2429194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2430194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2431194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2432194d53e6SMatthew G. Knepley 
2433a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2434194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2435194d53e6SMatthew G. Knepley . Nf           - the number of fields
2436a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2437194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2438194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2439194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2440194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2441194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2442194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2443194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2444194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2445194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2446194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2447194d53e6SMatthew G. Knepley . t            - current time
24482aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2449194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2450194d53e6SMatthew G. Knepley . n            - normal at the current point
245197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
245297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2453194d53e6SMatthew G. Knepley - g0           - output values at the current point
2454194d53e6SMatthew G. Knepley 
2455194d53e6SMatthew G. Knepley   Level: intermediate
2456194d53e6SMatthew G. Knepley 
2457dce8aebaSBarry Smith   Note:
2458a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
245960225df5SJacob Faibussowitsch 
2460a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
24611702e181SMatthew Knepley 
24621702e181SMatthew Knepley   $$
24631702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
24641702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
24651702e181SMatthew Knepley   $$
2466dce8aebaSBarry Smith 
2467dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2468194d53e6SMatthew G. Knepley @*/
2469a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2470d71ae5a4SJacob Faibussowitsch {
24716528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24726528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24736528b96dSMatthew G. Knepley 
24742764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24756528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
247663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
247763a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
24789566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24796528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24806528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24816528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24826528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24842764a2aaSMatthew G. Knepley }
24852764a2aaSMatthew G. Knepley 
2486194d53e6SMatthew G. Knepley /*@C
2487194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2488194d53e6SMatthew G. Knepley 
248920f4b53cSBarry Smith   Not Collective
2490194d53e6SMatthew G. Knepley 
2491194d53e6SMatthew G. Knepley   Input Parameters:
24926528b96dSMatthew G. Knepley + ds - The PetscDS
2493194d53e6SMatthew G. Knepley . f  - The test field number
2494194d53e6SMatthew G. Knepley . g  - The field number
2495194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2496194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2497194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2498194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2499194d53e6SMatthew G. Knepley 
2500a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2501194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2502194d53e6SMatthew G. Knepley . Nf           - the number of fields
2503a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2504194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2505194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2506194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2507194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2508194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2509194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2510194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2511194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2512194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2513194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2514194d53e6SMatthew G. Knepley . t            - current time
25152aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2516194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2517194d53e6SMatthew G. Knepley . n            - normal at the current point
251897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
251997b6e6e8SMatthew G. Knepley . constants    - constant parameters
2520194d53e6SMatthew G. Knepley - g0           - output values at the current point
2521194d53e6SMatthew G. Knepley 
2522194d53e6SMatthew G. Knepley   Level: intermediate
2523194d53e6SMatthew G. Knepley 
2524dce8aebaSBarry Smith   Note:
2525a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
252660225df5SJacob Faibussowitsch 
2527a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
25281702e181SMatthew Knepley 
25291702e181SMatthew Knepley   $$
25301702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
25311702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
25321702e181SMatthew Knepley   $$
2533dce8aebaSBarry Smith 
2534dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2535194d53e6SMatthew G. Knepley @*/
2536a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2537d71ae5a4SJacob Faibussowitsch {
25382764a2aaSMatthew G. Knepley   PetscFunctionBegin;
25396528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25402764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
25412764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
25422764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
25432764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
254463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
254563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
25469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
25473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25482764a2aaSMatthew G. Knepley }
25492764a2aaSMatthew G. Knepley 
255027f02ce8SMatthew G. Knepley /*@
255127f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
255227f02ce8SMatthew G. Knepley 
255320f4b53cSBarry Smith   Not Collective
255427f02ce8SMatthew G. Knepley 
255527f02ce8SMatthew G. Knepley   Input Parameter:
2556dce8aebaSBarry Smith . ds - The `PetscDS`
255727f02ce8SMatthew G. Knepley 
255827f02ce8SMatthew G. Knepley   Output Parameter:
255960225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
256027f02ce8SMatthew G. Knepley 
256127f02ce8SMatthew G. Knepley   Level: intermediate
256227f02ce8SMatthew G. Knepley 
2563dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
256427f02ce8SMatthew G. Knepley @*/
2565d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2566d71ae5a4SJacob Faibussowitsch {
256727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25694f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
257227f02ce8SMatthew G. Knepley }
257327f02ce8SMatthew G. Knepley 
257427f02ce8SMatthew G. Knepley /*@C
257527f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
257627f02ce8SMatthew G. Knepley 
257720f4b53cSBarry Smith   Not Collective; No Fortran Support
257827f02ce8SMatthew G. Knepley 
257927f02ce8SMatthew G. Knepley   Input Parameters:
2580dce8aebaSBarry Smith + ds - The `PetscDS`
258127f02ce8SMatthew G. Knepley . f  - The test field number
258227f02ce8SMatthew G. Knepley - g  - The field number
258327f02ce8SMatthew G. Knepley 
258427f02ce8SMatthew G. Knepley   Output Parameters:
258527f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
258627f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
258727f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
258827f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
258927f02ce8SMatthew G. Knepley 
2590a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
259127f02ce8SMatthew G. Knepley + dim          - the spatial dimension
259227f02ce8SMatthew G. Knepley . Nf           - the number of fields
259327f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
259427f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
259527f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
259627f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
259727f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
259827f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
259927f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
260027f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
260127f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
260227f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
260327f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
260427f02ce8SMatthew G. Knepley . t            - current time
260527f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
260627f02ce8SMatthew G. Knepley . x            - coordinates of the current point
260727f02ce8SMatthew G. Knepley . n            - normal at the current point
260827f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
260927f02ce8SMatthew G. Knepley . constants    - constant parameters
261027f02ce8SMatthew G. Knepley - g0           - output values at the current point
261127f02ce8SMatthew G. Knepley 
261227f02ce8SMatthew G. Knepley   Level: intermediate
261327f02ce8SMatthew G. Knepley 
2614dce8aebaSBarry Smith   Note:
2615a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
261660225df5SJacob Faibussowitsch 
2617a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
26181702e181SMatthew Knepley 
26191702e181SMatthew Knepley   $$
26201702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
26211702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
26221702e181SMatthew Knepley   $$
2623dce8aebaSBarry Smith 
2624dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
262527f02ce8SMatthew G. Knepley @*/
2626a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2627d71ae5a4SJacob Faibussowitsch {
26286528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
26296528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
26306528b96dSMatthew G. Knepley 
263127f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
263363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
263463a3b9bcSJacob Faibussowitsch   PetscCheck(!(g < 0) && !(g >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", g, ds->Nf);
26359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
26366528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
26376528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
26386528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
26396528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
26403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264127f02ce8SMatthew G. Knepley }
264227f02ce8SMatthew G. Knepley 
264327f02ce8SMatthew G. Knepley /*@C
264427f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
264527f02ce8SMatthew G. Knepley 
264620f4b53cSBarry Smith   Not Collective; No Fortran Support
264727f02ce8SMatthew G. Knepley 
264827f02ce8SMatthew G. Knepley   Input Parameters:
2649dce8aebaSBarry Smith + ds - The `PetscDS`
265027f02ce8SMatthew G. Knepley . f  - The test field number
265127f02ce8SMatthew G. Knepley . g  - The field number
265227f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
265327f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
265427f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
265527f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
265627f02ce8SMatthew G. Knepley 
2657a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
265827f02ce8SMatthew G. Knepley + dim          - the spatial dimension
265927f02ce8SMatthew G. Knepley . Nf           - the number of fields
266027f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
266127f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
266227f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
266327f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
266427f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
266527f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
266627f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
266727f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
266827f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
266927f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
267027f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
267127f02ce8SMatthew G. Knepley . t            - current time
267227f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
267327f02ce8SMatthew G. Knepley . x            - coordinates of the current point
267427f02ce8SMatthew G. Knepley . n            - normal at the current point
267527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
267627f02ce8SMatthew G. Knepley . constants    - constant parameters
267727f02ce8SMatthew G. Knepley - g0           - output values at the current point
267827f02ce8SMatthew G. Knepley 
267927f02ce8SMatthew G. Knepley   Level: intermediate
268027f02ce8SMatthew G. Knepley 
2681dce8aebaSBarry Smith   Note:
2682a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
268360225df5SJacob Faibussowitsch 
2684a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
26851702e181SMatthew Knepley 
26861702e181SMatthew Knepley   $$
26871702e181SMatthew Knepley   \int_\Gamma \phi\, {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi\, {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi
26881702e181SMatthew Knepley   + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
26891702e181SMatthew Knepley   $$
2690dce8aebaSBarry Smith 
2691dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
269227f02ce8SMatthew G. Knepley @*/
2693a4e35b19SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2694d71ae5a4SJacob Faibussowitsch {
269527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
269727f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
269827f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
269927f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
270027f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
270163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
270263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
27039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
27043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
270527f02ce8SMatthew G. Knepley }
270627f02ce8SMatthew G. Knepley 
27070d3e9b51SMatthew G. Knepley /*@C
2708c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2709c371a6d1SMatthew G. Knepley 
271020f4b53cSBarry Smith   Not Collective
2711c371a6d1SMatthew G. Knepley 
2712c371a6d1SMatthew G. Knepley   Input Parameters:
2713c371a6d1SMatthew G. Knepley + prob - The PetscDS
2714c371a6d1SMatthew G. Knepley - f    - The test field number
2715c371a6d1SMatthew G. Knepley 
2716d8d19677SJose E. Roman   Output Parameters:
2717a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2718a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2719c371a6d1SMatthew G. Knepley 
272020f4b53cSBarry Smith   Calling sequence of `exactSol`:
2721c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2722c371a6d1SMatthew G. Knepley . t   - current time
2723c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2724c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2725a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2726c371a6d1SMatthew G. Knepley - ctx - a user context
2727c371a6d1SMatthew G. Knepley 
2728c371a6d1SMatthew G. Knepley   Level: intermediate
2729c371a6d1SMatthew G. Knepley 
2730dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2731c371a6d1SMatthew G. Knepley @*/
2732d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2733d71ae5a4SJacob Faibussowitsch {
2734c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2735c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
273663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
27379371c9d4SSatish Balay   if (sol) {
27384f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27399371c9d4SSatish Balay     *sol = prob->exactSol[f];
27409371c9d4SSatish Balay   }
27419371c9d4SSatish Balay   if (ctx) {
27424f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27439371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
27449371c9d4SSatish Balay   }
27453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2746c371a6d1SMatthew G. Knepley }
2747c371a6d1SMatthew G. Knepley 
2748c371a6d1SMatthew G. Knepley /*@C
2749578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2750c371a6d1SMatthew G. Knepley 
275120f4b53cSBarry Smith   Not Collective
2752c371a6d1SMatthew G. Knepley 
2753c371a6d1SMatthew G. Knepley   Input Parameters:
2754dce8aebaSBarry Smith + prob - The `PetscDS`
2755c371a6d1SMatthew G. Knepley . f    - The test field number
275695cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
275720f4b53cSBarry Smith - ctx  - solution context or `NULL`
2758c371a6d1SMatthew G. Knepley 
275920f4b53cSBarry Smith   Calling sequence of `sol`:
2760c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2761c371a6d1SMatthew G. Knepley . t   - current time
2762c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2763c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2764c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2765c371a6d1SMatthew G. Knepley - ctx - a user context
2766c371a6d1SMatthew G. Knepley 
2767c371a6d1SMatthew G. Knepley   Level: intermediate
2768c371a6d1SMatthew G. Knepley 
2769dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2770c371a6d1SMatthew G. Knepley @*/
2771d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2772d71ae5a4SJacob Faibussowitsch {
2773c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2774c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
277563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27769566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27779371c9d4SSatish Balay   if (sol) {
27789371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27799371c9d4SSatish Balay     prob->exactSol[f] = sol;
27809371c9d4SSatish Balay   }
27819371c9d4SSatish Balay   if (ctx) {
27829371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27839371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27849371c9d4SSatish Balay   }
27853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2786c371a6d1SMatthew G. Knepley }
2787c371a6d1SMatthew G. Knepley 
27885638fd0eSMatthew G. Knepley /*@C
2789f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2790f2cacb80SMatthew G. Knepley 
279120f4b53cSBarry Smith   Not Collective
2792f2cacb80SMatthew G. Knepley 
2793f2cacb80SMatthew G. Knepley   Input Parameters:
2794dce8aebaSBarry Smith + prob - The `PetscDS`
2795f2cacb80SMatthew G. Knepley - f    - The test field number
2796f2cacb80SMatthew G. Knepley 
2797d8d19677SJose E. Roman   Output Parameters:
2798a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2799a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2800f2cacb80SMatthew G. Knepley 
280120f4b53cSBarry Smith   Calling sequence of `exactSol`:
2802f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2803f2cacb80SMatthew G. Knepley . t   - current time
2804f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2805f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2806a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2807f2cacb80SMatthew G. Knepley - ctx - a user context
2808f2cacb80SMatthew G. Knepley 
2809f2cacb80SMatthew G. Knepley   Level: intermediate
2810f2cacb80SMatthew G. Knepley 
2811dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2812f2cacb80SMatthew G. Knepley @*/
2813d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2814d71ae5a4SJacob Faibussowitsch {
2815f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2816f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
281763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
28189371c9d4SSatish Balay   if (sol) {
28194f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
28209371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
28219371c9d4SSatish Balay   }
28229371c9d4SSatish Balay   if (ctx) {
28234f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
28249371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
28259371c9d4SSatish Balay   }
28263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2827f2cacb80SMatthew G. Knepley }
2828f2cacb80SMatthew G. Knepley 
2829f2cacb80SMatthew G. Knepley /*@C
2830f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2831f2cacb80SMatthew G. Knepley 
283220f4b53cSBarry Smith   Not Collective
2833f2cacb80SMatthew G. Knepley 
2834f2cacb80SMatthew G. Knepley   Input Parameters:
2835dce8aebaSBarry Smith + prob - The `PetscDS`
2836f2cacb80SMatthew G. Knepley . f    - The test field number
2837f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
283820f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2839f2cacb80SMatthew G. Knepley 
284020f4b53cSBarry Smith   Calling sequence of `sol`:
2841f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2842f2cacb80SMatthew G. Knepley . t   - current time
2843f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2844f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2845f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2846f2cacb80SMatthew G. Knepley - ctx - a user context
2847f2cacb80SMatthew G. Knepley 
2848f2cacb80SMatthew G. Knepley   Level: intermediate
2849f2cacb80SMatthew G. Knepley 
2850dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2851f2cacb80SMatthew G. Knepley @*/
2852d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2853d71ae5a4SJacob Faibussowitsch {
2854f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2855f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28579566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28589371c9d4SSatish Balay   if (sol) {
28599371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28609371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28619371c9d4SSatish Balay   }
28629371c9d4SSatish Balay   if (ctx) {
28639371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28649371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28659371c9d4SSatish Balay   }
28663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2867f2cacb80SMatthew G. Knepley }
2868f2cacb80SMatthew G. Knepley 
2869f2cacb80SMatthew G. Knepley /*@C
2870*342bd5aaSMatthew G. Knepley   PetscDSGetLowerBound - Get the pointwise lower bound function for a given field
2871*342bd5aaSMatthew G. Knepley 
2872*342bd5aaSMatthew G. Knepley   Not Collective
2873*342bd5aaSMatthew G. Knepley 
2874*342bd5aaSMatthew G. Knepley   Input Parameters:
2875*342bd5aaSMatthew G. Knepley + ds - The PetscDS
2876*342bd5aaSMatthew G. Knepley - f  - The field number
2877*342bd5aaSMatthew G. Knepley 
2878*342bd5aaSMatthew G. Knepley   Output Parameters:
2879*342bd5aaSMatthew G. Knepley + lb  - lower bound for the field
2880*342bd5aaSMatthew G. Knepley - ctx - lower bound context
2881*342bd5aaSMatthew G. Knepley 
2882*342bd5aaSMatthew G. Knepley   Calling sequence of `lb`:
2883*342bd5aaSMatthew G. Knepley + dim - the spatial dimension
2884*342bd5aaSMatthew G. Knepley . t   - current time
2885*342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2886*342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2887*342bd5aaSMatthew G. Knepley . u   - the lower bound evaluated at the current point
2888*342bd5aaSMatthew G. Knepley - ctx - a user context
2889*342bd5aaSMatthew G. Knepley 
2890*342bd5aaSMatthew G. Knepley   Level: intermediate
2891*342bd5aaSMatthew G. Knepley 
2892*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2893*342bd5aaSMatthew G. Knepley @*/
2894*342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSGetLowerBound(PetscDS ds, PetscInt f, PetscErrorCode (**lb)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2895*342bd5aaSMatthew G. Knepley {
2896*342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2897*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2898*342bd5aaSMatthew G. Knepley   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
2899*342bd5aaSMatthew G. Knepley   if (lb) {
2900*342bd5aaSMatthew G. Knepley     PetscAssertPointer(lb, 3);
2901*342bd5aaSMatthew G. Knepley     *lb = ds->lowerBound[f];
2902*342bd5aaSMatthew G. Knepley   }
2903*342bd5aaSMatthew G. Knepley   if (ctx) {
2904*342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2905*342bd5aaSMatthew G. Knepley     *ctx = ds->lowerCtx[f];
2906*342bd5aaSMatthew G. Knepley   }
2907*342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2908*342bd5aaSMatthew G. Knepley }
2909*342bd5aaSMatthew G. Knepley 
2910*342bd5aaSMatthew G. Knepley /*@C
2911*342bd5aaSMatthew G. Knepley   PetscDSSetLowerBound - Set the pointwise lower bound function for a given field
2912*342bd5aaSMatthew G. Knepley 
2913*342bd5aaSMatthew G. Knepley   Not Collective
2914*342bd5aaSMatthew G. Knepley 
2915*342bd5aaSMatthew G. Knepley   Input Parameters:
2916*342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2917*342bd5aaSMatthew G. Knepley . f   - The field number
2918*342bd5aaSMatthew G. Knepley . lb  - solution function for the test fields
2919*342bd5aaSMatthew G. Knepley - ctx - solution context or `NULL`
2920*342bd5aaSMatthew G. Knepley 
2921*342bd5aaSMatthew G. Knepley   Calling sequence of `lb`:
2922*342bd5aaSMatthew G. Knepley + dim - the spatial dimension
2923*342bd5aaSMatthew G. Knepley . t   - current time
2924*342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2925*342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2926*342bd5aaSMatthew G. Knepley . u   - the lower bound evaluated at the current point
2927*342bd5aaSMatthew G. Knepley - ctx - a user context
2928*342bd5aaSMatthew G. Knepley 
2929*342bd5aaSMatthew G. Knepley   Level: intermediate
2930*342bd5aaSMatthew G. Knepley 
2931*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2932*342bd5aaSMatthew G. Knepley @*/
2933*342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSSetLowerBound(PetscDS ds, PetscInt f, PetscErrorCode (*lb)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2934*342bd5aaSMatthew G. Knepley {
2935*342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2936*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2937*342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
2938*342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
2939*342bd5aaSMatthew G. Knepley   if (lb) {
2940*342bd5aaSMatthew G. Knepley     PetscValidFunction(lb, 3);
2941*342bd5aaSMatthew G. Knepley     ds->lowerBound[f] = lb;
2942*342bd5aaSMatthew G. Knepley   }
2943*342bd5aaSMatthew G. Knepley   if (ctx) {
2944*342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
2945*342bd5aaSMatthew G. Knepley     ds->lowerCtx[f] = ctx;
2946*342bd5aaSMatthew G. Knepley   }
2947*342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2948*342bd5aaSMatthew G. Knepley }
2949*342bd5aaSMatthew G. Knepley 
2950*342bd5aaSMatthew G. Knepley /*@C
2951*342bd5aaSMatthew G. Knepley   PetscDSGetUpperBound - Get the pointwise upper bound function for a given field
2952*342bd5aaSMatthew G. Knepley 
2953*342bd5aaSMatthew G. Knepley   Not Collective
2954*342bd5aaSMatthew G. Knepley 
2955*342bd5aaSMatthew G. Knepley   Input Parameters:
2956*342bd5aaSMatthew G. Knepley + ds - The PetscDS
2957*342bd5aaSMatthew G. Knepley - f  - The field number
2958*342bd5aaSMatthew G. Knepley 
2959*342bd5aaSMatthew G. Knepley   Output Parameters:
2960*342bd5aaSMatthew G. Knepley + ub  - upper bound for the field
2961*342bd5aaSMatthew G. Knepley - ctx - upper bound context
2962*342bd5aaSMatthew G. Knepley 
2963*342bd5aaSMatthew G. Knepley   Calling sequence of `ub`:
2964*342bd5aaSMatthew G. Knepley + dim - the spatial dimension
2965*342bd5aaSMatthew G. Knepley . t   - current time
2966*342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
2967*342bd5aaSMatthew G. Knepley . Nc  - the number of field components
2968*342bd5aaSMatthew G. Knepley . u   - the upper bound evaluated at the current point
2969*342bd5aaSMatthew G. Knepley - ctx - a user context
2970*342bd5aaSMatthew G. Knepley 
2971*342bd5aaSMatthew G. Knepley   Level: intermediate
2972*342bd5aaSMatthew G. Knepley 
2973*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
2974*342bd5aaSMatthew G. Knepley @*/
2975*342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSGetUpperBound(PetscDS ds, PetscInt f, PetscErrorCode (**ub)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2976*342bd5aaSMatthew G. Knepley {
2977*342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2978*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2979*342bd5aaSMatthew G. Knepley   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
2980*342bd5aaSMatthew G. Knepley   if (ub) {
2981*342bd5aaSMatthew G. Knepley     PetscAssertPointer(ub, 3);
2982*342bd5aaSMatthew G. Knepley     *ub = ds->upperBound[f];
2983*342bd5aaSMatthew G. Knepley   }
2984*342bd5aaSMatthew G. Knepley   if (ctx) {
2985*342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2986*342bd5aaSMatthew G. Knepley     *ctx = ds->upperCtx[f];
2987*342bd5aaSMatthew G. Knepley   }
2988*342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2989*342bd5aaSMatthew G. Knepley }
2990*342bd5aaSMatthew G. Knepley 
2991*342bd5aaSMatthew G. Knepley /*@C
2992*342bd5aaSMatthew G. Knepley   PetscDSSetUpperBound - Set the pointwise upper bound function for a given field
2993*342bd5aaSMatthew G. Knepley 
2994*342bd5aaSMatthew G. Knepley   Not Collective
2995*342bd5aaSMatthew G. Knepley 
2996*342bd5aaSMatthew G. Knepley   Input Parameters:
2997*342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2998*342bd5aaSMatthew G. Knepley . f   - The field number
2999*342bd5aaSMatthew G. Knepley . ub  - solution function for the test fields
3000*342bd5aaSMatthew G. Knepley - ctx - solution context or `NULL`
3001*342bd5aaSMatthew G. Knepley 
3002*342bd5aaSMatthew G. Knepley   Calling sequence of `ub`:
3003*342bd5aaSMatthew G. Knepley + dim - the spatial dimension
3004*342bd5aaSMatthew G. Knepley . t   - current time
3005*342bd5aaSMatthew G. Knepley . x   - coordinates of the current point
3006*342bd5aaSMatthew G. Knepley . Nc  - the number of field components
3007*342bd5aaSMatthew G. Knepley . u   - the upper bound evaluated at the current point
3008*342bd5aaSMatthew G. Knepley - ctx - a user context
3009*342bd5aaSMatthew G. Knepley 
3010*342bd5aaSMatthew G. Knepley   Level: intermediate
3011*342bd5aaSMatthew G. Knepley 
3012*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
3013*342bd5aaSMatthew G. Knepley @*/
3014*342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSSetUpperBound(PetscDS ds, PetscInt f, PetscErrorCode (*ub)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
3015*342bd5aaSMatthew G. Knepley {
3016*342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
3017*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3018*342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
3019*342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
3020*342bd5aaSMatthew G. Knepley   if (ub) {
3021*342bd5aaSMatthew G. Knepley     PetscValidFunction(ub, 3);
3022*342bd5aaSMatthew G. Knepley     ds->upperBound[f] = ub;
3023*342bd5aaSMatthew G. Knepley   }
3024*342bd5aaSMatthew G. Knepley   if (ctx) {
3025*342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
3026*342bd5aaSMatthew G. Knepley     ds->upperCtx[f] = ctx;
3027*342bd5aaSMatthew G. Knepley   }
3028*342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
3029*342bd5aaSMatthew G. Knepley }
3030*342bd5aaSMatthew G. Knepley 
3031*342bd5aaSMatthew G. Knepley /*@C
303297b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
303397b6e6e8SMatthew G. Knepley 
303420f4b53cSBarry Smith   Not Collective
303597b6e6e8SMatthew G. Knepley 
303697b6e6e8SMatthew G. Knepley   Input Parameter:
3037a102dd69SStefano Zampini . ds - The `PetscDS` object
303897b6e6e8SMatthew G. Knepley 
303997b6e6e8SMatthew G. Knepley   Output Parameters:
304097b6e6e8SMatthew G. Knepley + numConstants - The number of constants
304197b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
304297b6e6e8SMatthew G. Knepley 
304397b6e6e8SMatthew G. Knepley   Level: intermediate
304497b6e6e8SMatthew G. Knepley 
3045dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
304697b6e6e8SMatthew G. Knepley @*/
3047a102dd69SStefano Zampini PetscErrorCode PetscDSGetConstants(PetscDS ds, PetscInt *numConstants, const PetscScalar *constants[])
3048d71ae5a4SJacob Faibussowitsch {
304997b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
3050a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
30519371c9d4SSatish Balay   if (numConstants) {
30524f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
3053a102dd69SStefano Zampini     *numConstants = ds->numConstants;
30549371c9d4SSatish Balay   }
30559371c9d4SSatish Balay   if (constants) {
30564f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
3057a102dd69SStefano Zampini     *constants = ds->constants;
30589371c9d4SSatish Balay   }
30593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
306097b6e6e8SMatthew G. Knepley }
306197b6e6e8SMatthew G. Knepley 
30620d3e9b51SMatthew G. Knepley /*@C
306397b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
306497b6e6e8SMatthew G. Knepley 
306520f4b53cSBarry Smith   Not Collective
306697b6e6e8SMatthew G. Knepley 
306797b6e6e8SMatthew G. Knepley   Input Parameters:
3068a102dd69SStefano Zampini + ds           - The `PetscDS` object
306997b6e6e8SMatthew G. Knepley . numConstants - The number of constants
3070a3b724e8SBarry Smith - constants    - The array of constants, `NULL` if there are none
307197b6e6e8SMatthew G. Knepley 
307297b6e6e8SMatthew G. Knepley   Level: intermediate
307397b6e6e8SMatthew G. Knepley 
3074dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
307597b6e6e8SMatthew G. Knepley @*/
3076a102dd69SStefano Zampini PetscErrorCode PetscDSSetConstants(PetscDS ds, PetscInt numConstants, PetscScalar constants[])
3077d71ae5a4SJacob Faibussowitsch {
307897b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
3079a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3080a102dd69SStefano Zampini   if (numConstants != ds->numConstants) {
3081a102dd69SStefano Zampini     PetscCall(PetscFree(ds->constants));
3082a102dd69SStefano Zampini     ds->numConstants = numConstants;
3083a102dd69SStefano Zampini     PetscCall(PetscMalloc1(ds->numConstants + ds->numFuncConstants, &ds->constants));
308420be0f5bSMatthew G. Knepley   }
3085a102dd69SStefano Zampini   if (ds->numConstants) {
30864f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
3087a102dd69SStefano Zampini     PetscCall(PetscArraycpy(ds->constants, constants, ds->numConstants));
308897b6e6e8SMatthew G. Knepley   }
30893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
309097b6e6e8SMatthew G. Knepley }
309197b6e6e8SMatthew G. Knepley 
3092a102dd69SStefano Zampini /*@C
3093a102dd69SStefano Zampini   PetscDSSetIntegrationParameters - Set the parameters for a particular integration
3094a102dd69SStefano Zampini 
3095a102dd69SStefano Zampini   Not Collective
3096a102dd69SStefano Zampini 
3097a102dd69SStefano Zampini   Input Parameters:
3098a102dd69SStefano Zampini + ds     - The `PetscDS` object
3099a102dd69SStefano Zampini . fieldI - The test field for a given point function, or PETSC_DETERMINE
3100a102dd69SStefano Zampini - fieldJ - The basis field for a given point function, or PETSC_DETERMINE
3101a102dd69SStefano Zampini 
3102a102dd69SStefano Zampini   Level: intermediate
3103a102dd69SStefano Zampini 
3104a102dd69SStefano Zampini .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
3105a102dd69SStefano Zampini @*/
3106a102dd69SStefano Zampini PetscErrorCode PetscDSSetIntegrationParameters(PetscDS ds, PetscInt fieldI, PetscInt fieldJ)
3107a102dd69SStefano Zampini {
3108a102dd69SStefano Zampini   PetscFunctionBegin;
3109a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3110a102dd69SStefano Zampini   ds->constants[ds->numConstants]     = fieldI;
3111a102dd69SStefano Zampini   ds->constants[ds->numConstants + 1] = fieldJ;
3112a102dd69SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
3113a102dd69SStefano Zampini }
3114a102dd69SStefano Zampini 
311587510d7dSMatthew G. Knepley /*@C
311687510d7dSMatthew G. Knepley   PetscDSSetCellParameters - Set the parameters for a particular cell
311787510d7dSMatthew G. Knepley 
311887510d7dSMatthew G. Knepley   Not Collective
311987510d7dSMatthew G. Knepley 
312087510d7dSMatthew G. Knepley   Input Parameters:
312187510d7dSMatthew G. Knepley + ds     - The `PetscDS` object
312287510d7dSMatthew G. Knepley - volume - The cell volume
312387510d7dSMatthew G. Knepley 
312487510d7dSMatthew G. Knepley   Level: intermediate
312587510d7dSMatthew G. Knepley 
312687510d7dSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
312787510d7dSMatthew G. Knepley @*/
312887510d7dSMatthew G. Knepley PetscErrorCode PetscDSSetCellParameters(PetscDS ds, PetscReal volume)
312987510d7dSMatthew G. Knepley {
313087510d7dSMatthew G. Knepley   PetscFunctionBegin;
313187510d7dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
313287510d7dSMatthew G. Knepley   ds->constants[ds->numConstants + 2] = volume;
313387510d7dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
313487510d7dSMatthew G. Knepley }
313587510d7dSMatthew G. Knepley 
31364cd1e086SMatthew G. Knepley /*@
31374cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
31384cd1e086SMatthew G. Knepley 
313920f4b53cSBarry Smith   Not Collective
31404cd1e086SMatthew G. Knepley 
31414cd1e086SMatthew G. Knepley   Input Parameters:
3142dce8aebaSBarry Smith + prob - The `PetscDS` object
31434cd1e086SMatthew G. Knepley - disc - The discretization object
31444cd1e086SMatthew G. Knepley 
31454cd1e086SMatthew G. Knepley   Output Parameter:
31464cd1e086SMatthew G. Knepley . f - The field number
31474cd1e086SMatthew G. Knepley 
31484cd1e086SMatthew G. Knepley   Level: beginner
31494cd1e086SMatthew G. Knepley 
3150dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31514cd1e086SMatthew G. Knepley @*/
3152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
3153d71ae5a4SJacob Faibussowitsch {
31544cd1e086SMatthew G. Knepley   PetscInt g;
31554cd1e086SMatthew G. Knepley 
31564cd1e086SMatthew G. Knepley   PetscFunctionBegin;
31574cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31584f572ea9SToby Isaac   PetscAssertPointer(f, 3);
31594cd1e086SMatthew G. Knepley   *f = -1;
31609371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
31619371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
31629371c9d4SSatish Balay   }
316308401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
31644cd1e086SMatthew G. Knepley   *f = g;
31653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31664cd1e086SMatthew G. Knepley }
31674cd1e086SMatthew G. Knepley 
31684cd1e086SMatthew G. Knepley /*@
31694cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
31704cd1e086SMatthew G. Knepley 
317120f4b53cSBarry Smith   Not Collective
31724cd1e086SMatthew G. Knepley 
31734cd1e086SMatthew G. Knepley   Input Parameters:
3174dce8aebaSBarry Smith + prob - The `PetscDS` object
31754cd1e086SMatthew G. Knepley - f    - The field number
31764cd1e086SMatthew G. Knepley 
31774cd1e086SMatthew G. Knepley   Output Parameter:
31784cd1e086SMatthew G. Knepley . size - The size
31794cd1e086SMatthew G. Knepley 
31804cd1e086SMatthew G. Knepley   Level: beginner
31814cd1e086SMatthew G. Knepley 
3182dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31834cd1e086SMatthew G. Knepley @*/
3184d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
3185d71ae5a4SJacob Faibussowitsch {
31864cd1e086SMatthew G. Knepley   PetscFunctionBegin;
31874cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31884f572ea9SToby Isaac   PetscAssertPointer(size, 3);
318963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
31909566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3191d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
31923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31934cd1e086SMatthew G. Knepley }
31944cd1e086SMatthew G. Knepley 
3195bc4ae4beSMatthew G. Knepley /*@
3196bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
3197bc4ae4beSMatthew G. Knepley 
319820f4b53cSBarry Smith   Not Collective
3199bc4ae4beSMatthew G. Knepley 
3200bc4ae4beSMatthew G. Knepley   Input Parameters:
3201dce8aebaSBarry Smith + prob - The `PetscDS` object
3202bc4ae4beSMatthew G. Knepley - f    - The field number
3203bc4ae4beSMatthew G. Knepley 
3204bc4ae4beSMatthew G. Knepley   Output Parameter:
3205bc4ae4beSMatthew G. Knepley . off - The offset
3206bc4ae4beSMatthew G. Knepley 
3207bc4ae4beSMatthew G. Knepley   Level: beginner
3208bc4ae4beSMatthew G. Knepley 
3209dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3210bc4ae4beSMatthew G. Knepley @*/
3211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
3212d71ae5a4SJacob Faibussowitsch {
32134cd1e086SMatthew G. Knepley   PetscInt size, g;
32142764a2aaSMatthew G. Knepley 
32152764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32162764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32174f572ea9SToby Isaac   PetscAssertPointer(off, 3);
321863a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
32192764a2aaSMatthew G. Knepley   *off = 0;
32202764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
32219566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
32224cd1e086SMatthew G. Knepley     *off += size;
32232764a2aaSMatthew G. Knepley   }
32243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32252764a2aaSMatthew G. Knepley }
32262764a2aaSMatthew G. Knepley 
3227bc4ae4beSMatthew G. Knepley /*@
32285fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
32295fedec97SMatthew G. Knepley 
323020f4b53cSBarry Smith   Not Collective
32315fedec97SMatthew G. Knepley 
32325fedec97SMatthew G. Knepley   Input Parameters:
323360225df5SJacob Faibussowitsch + ds - The `PetscDS` object
32345fedec97SMatthew G. Knepley - f  - The field number
32355fedec97SMatthew G. Knepley 
32365fedec97SMatthew G. Knepley   Output Parameter:
32375fedec97SMatthew G. Knepley . off - The offset
32385fedec97SMatthew G. Knepley 
32395fedec97SMatthew G. Knepley   Level: beginner
32405fedec97SMatthew G. Knepley 
3241dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32425fedec97SMatthew G. Knepley @*/
3243d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
3244d71ae5a4SJacob Faibussowitsch {
32455fedec97SMatthew G. Knepley   PetscInt size, g;
32465fedec97SMatthew G. Knepley 
32475fedec97SMatthew G. Knepley   PetscFunctionBegin;
32485fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32494f572ea9SToby Isaac   PetscAssertPointer(off, 3);
325063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
32515fedec97SMatthew G. Knepley   *off = 0;
32525fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
32535fedec97SMatthew G. Knepley     PetscBool cohesive;
32545fedec97SMatthew G. Knepley 
32559566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
32569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
32575fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
32585fedec97SMatthew G. Knepley   }
32593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32605fedec97SMatthew G. Knepley }
32615fedec97SMatthew G. Knepley 
32625fedec97SMatthew G. Knepley /*@
326347e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3264bc4ae4beSMatthew G. Knepley 
326520f4b53cSBarry Smith   Not Collective
3266bc4ae4beSMatthew G. Knepley 
326747e57110SSander Arens   Input Parameter:
3268dce8aebaSBarry Smith . prob - The `PetscDS` object
3269bc4ae4beSMatthew G. Knepley 
3270bc4ae4beSMatthew G. Knepley   Output Parameter:
327147e57110SSander Arens . dimensions - The number of dimensions
3272bc4ae4beSMatthew G. Knepley 
3273bc4ae4beSMatthew G. Knepley   Level: beginner
3274bc4ae4beSMatthew G. Knepley 
3275dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3276bc4ae4beSMatthew G. Knepley @*/
3277d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3278d71ae5a4SJacob Faibussowitsch {
32792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32802764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32819566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32824f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
328347e57110SSander Arens   *dimensions = prob->Nb;
32843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32856ce16762SMatthew G. Knepley }
328647e57110SSander Arens 
328747e57110SSander Arens /*@
328847e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
328947e57110SSander Arens 
329020f4b53cSBarry Smith   Not Collective
329147e57110SSander Arens 
329247e57110SSander Arens   Input Parameter:
3293dce8aebaSBarry Smith . prob - The `PetscDS` object
329447e57110SSander Arens 
329547e57110SSander Arens   Output Parameter:
329647e57110SSander Arens . components - The number of components
329747e57110SSander Arens 
329847e57110SSander Arens   Level: beginner
329947e57110SSander Arens 
3300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
330147e57110SSander Arens @*/
3302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3303d71ae5a4SJacob Faibussowitsch {
330447e57110SSander Arens   PetscFunctionBegin;
330547e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33069566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33074f572ea9SToby Isaac   PetscAssertPointer(components, 2);
330847e57110SSander Arens   *components = prob->Nc;
33093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33106ce16762SMatthew G. Knepley }
33116ce16762SMatthew G. Knepley 
33126ce16762SMatthew G. Knepley /*@
33136ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
33146ce16762SMatthew G. Knepley 
331520f4b53cSBarry Smith   Not Collective
33166ce16762SMatthew G. Knepley 
33176ce16762SMatthew G. Knepley   Input Parameters:
3318dce8aebaSBarry Smith + prob - The `PetscDS` object
33196ce16762SMatthew G. Knepley - f    - The field number
33206ce16762SMatthew G. Knepley 
33216ce16762SMatthew G. Knepley   Output Parameter:
33226ce16762SMatthew G. Knepley . off - The offset
33236ce16762SMatthew G. Knepley 
33246ce16762SMatthew G. Knepley   Level: beginner
33256ce16762SMatthew G. Knepley 
3326dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
33276ce16762SMatthew G. Knepley @*/
3328d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3329d71ae5a4SJacob Faibussowitsch {
33306ce16762SMatthew G. Knepley   PetscFunctionBegin;
33316ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33324f572ea9SToby Isaac   PetscAssertPointer(off, 3);
333363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
33349566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
333547e57110SSander Arens   *off = prob->off[f];
33363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33372764a2aaSMatthew G. Knepley }
33382764a2aaSMatthew G. Knepley 
3339194d53e6SMatthew G. Knepley /*@
3340194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3341194d53e6SMatthew G. Knepley 
334220f4b53cSBarry Smith   Not Collective
3343194d53e6SMatthew G. Knepley 
3344194d53e6SMatthew G. Knepley   Input Parameter:
3345dce8aebaSBarry Smith . prob - The `PetscDS` object
3346194d53e6SMatthew G. Knepley 
3347194d53e6SMatthew G. Knepley   Output Parameter:
3348194d53e6SMatthew G. Knepley . offsets - The offsets
3349194d53e6SMatthew G. Knepley 
3350194d53e6SMatthew G. Knepley   Level: beginner
3351194d53e6SMatthew G. Knepley 
3352dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3353194d53e6SMatthew G. Knepley @*/
3354d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3355d71ae5a4SJacob Faibussowitsch {
3356194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3357194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33584f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
33599566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3360194d53e6SMatthew G. Knepley   *offsets = prob->off;
33613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3362194d53e6SMatthew G. Knepley }
3363194d53e6SMatthew G. Knepley 
3364194d53e6SMatthew G. Knepley /*@
3365194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3366194d53e6SMatthew G. Knepley 
336720f4b53cSBarry Smith   Not Collective
3368194d53e6SMatthew G. Knepley 
3369194d53e6SMatthew G. Knepley   Input Parameter:
3370dce8aebaSBarry Smith . prob - The `PetscDS` object
3371194d53e6SMatthew G. Knepley 
3372194d53e6SMatthew G. Knepley   Output Parameter:
3373194d53e6SMatthew G. Knepley . offsets - The offsets
3374194d53e6SMatthew G. Knepley 
3375194d53e6SMatthew G. Knepley   Level: beginner
3376194d53e6SMatthew G. Knepley 
3377dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3378194d53e6SMatthew G. Knepley @*/
3379d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3380d71ae5a4SJacob Faibussowitsch {
3381194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3382194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33834f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
33849566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3385194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
33863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3387194d53e6SMatthew G. Knepley }
3388194d53e6SMatthew G. Knepley 
33899ee2af8cSMatthew G. Knepley /*@
33909ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
33919ee2af8cSMatthew G. Knepley 
339220f4b53cSBarry Smith   Not Collective
33939ee2af8cSMatthew G. Knepley 
33949ee2af8cSMatthew G. Knepley   Input Parameters:
3395dce8aebaSBarry Smith + ds - The `PetscDS` object
33969ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
33979ee2af8cSMatthew G. Knepley 
33989ee2af8cSMatthew G. Knepley   Output Parameter:
33999ee2af8cSMatthew G. Knepley . offsets - The offsets
34009ee2af8cSMatthew G. Knepley 
34019ee2af8cSMatthew G. Knepley   Level: beginner
34029ee2af8cSMatthew G. Knepley 
3403dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
34049ee2af8cSMatthew G. Knepley @*/
3405d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3406d71ae5a4SJacob Faibussowitsch {
34079ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
34089ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
34094f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
341028b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
341163a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
34129566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
34139ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
34143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34159ee2af8cSMatthew G. Knepley }
34169ee2af8cSMatthew G. Knepley 
34179ee2af8cSMatthew G. Knepley /*@
34189ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
34199ee2af8cSMatthew G. Knepley 
342020f4b53cSBarry Smith   Not Collective
34219ee2af8cSMatthew G. Knepley 
34229ee2af8cSMatthew G. Knepley   Input Parameters:
3423dce8aebaSBarry Smith + ds - The `PetscDS` object
34249ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
34259ee2af8cSMatthew G. Knepley 
34269ee2af8cSMatthew G. Knepley   Output Parameter:
34279ee2af8cSMatthew G. Knepley . offsets - The offsets
34289ee2af8cSMatthew G. Knepley 
34299ee2af8cSMatthew G. Knepley   Level: beginner
34309ee2af8cSMatthew G. Knepley 
3431dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
34329ee2af8cSMatthew G. Knepley @*/
3433d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3434d71ae5a4SJacob Faibussowitsch {
34359ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
34369ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
34374f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
343828b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
343963a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
34409566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
34419ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
34423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34439ee2af8cSMatthew G. Knepley }
34449ee2af8cSMatthew G. Knepley 
344568c9edb9SMatthew G. Knepley /*@C
344668c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
344768c9edb9SMatthew G. Knepley 
344820f4b53cSBarry Smith   Not Collective
344968c9edb9SMatthew G. Knepley 
345068c9edb9SMatthew G. Knepley   Input Parameter:
3451dce8aebaSBarry Smith . prob - The `PetscDS` object
345268c9edb9SMatthew G. Knepley 
3453ef0bb6c7SMatthew G. Knepley   Output Parameter:
3454ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
345568c9edb9SMatthew G. Knepley 
345668c9edb9SMatthew G. Knepley   Level: intermediate
345768c9edb9SMatthew G. Knepley 
3458dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
345968c9edb9SMatthew G. Knepley @*/
3460d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3461d71ae5a4SJacob Faibussowitsch {
34622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
34632764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
34644f572ea9SToby Isaac   PetscAssertPointer(T, 2);
34659566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3466ef0bb6c7SMatthew G. Knepley   *T = prob->T;
34673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34682764a2aaSMatthew G. Knepley }
34692764a2aaSMatthew G. Knepley 
347068c9edb9SMatthew G. Knepley /*@C
34714d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
347268c9edb9SMatthew G. Knepley 
347320f4b53cSBarry Smith   Not Collective
347468c9edb9SMatthew G. Knepley 
347568c9edb9SMatthew G. Knepley   Input Parameter:
3476dce8aebaSBarry Smith . prob - The `PetscDS` object
347768c9edb9SMatthew G. Knepley 
3478ef0bb6c7SMatthew G. Knepley   Output Parameter:
3479a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
348068c9edb9SMatthew G. Knepley 
348168c9edb9SMatthew G. Knepley   Level: intermediate
348268c9edb9SMatthew G. Knepley 
3483dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
348468c9edb9SMatthew G. Knepley @*/
3485d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3486d71ae5a4SJacob Faibussowitsch {
34872764a2aaSMatthew G. Knepley   PetscFunctionBegin;
34882764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
34894f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
34909566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3491ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
34923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34932764a2aaSMatthew G. Knepley }
34942764a2aaSMatthew G. Knepley 
3495d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3496d71ae5a4SJacob Faibussowitsch {
34972764a2aaSMatthew G. Knepley   PetscFunctionBegin;
34982764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
34999566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35009371c9d4SSatish Balay   if (u) {
35014f572ea9SToby Isaac     PetscAssertPointer(u, 2);
35029371c9d4SSatish Balay     *u = prob->u;
35039371c9d4SSatish Balay   }
35049371c9d4SSatish Balay   if (u_t) {
35054f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
35069371c9d4SSatish Balay     *u_t = prob->u_t;
35079371c9d4SSatish Balay   }
35089371c9d4SSatish Balay   if (u_x) {
35094f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
35109371c9d4SSatish Balay     *u_x = prob->u_x;
35119371c9d4SSatish Balay   }
35123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35132764a2aaSMatthew G. Knepley }
35142764a2aaSMatthew G. Knepley 
3515d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3516d71ae5a4SJacob Faibussowitsch {
35172764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35182764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35199566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35209371c9d4SSatish Balay   if (f0) {
35214f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
35229371c9d4SSatish Balay     *f0 = prob->f0;
35239371c9d4SSatish Balay   }
35249371c9d4SSatish Balay   if (f1) {
35254f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
35269371c9d4SSatish Balay     *f1 = prob->f1;
35279371c9d4SSatish Balay   }
35289371c9d4SSatish Balay   if (g0) {
35294f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
35309371c9d4SSatish Balay     *g0 = prob->g0;
35319371c9d4SSatish Balay   }
35329371c9d4SSatish Balay   if (g1) {
35334f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
35349371c9d4SSatish Balay     *g1 = prob->g1;
35359371c9d4SSatish Balay   }
35369371c9d4SSatish Balay   if (g2) {
35374f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
35389371c9d4SSatish Balay     *g2 = prob->g2;
35399371c9d4SSatish Balay   }
35409371c9d4SSatish Balay   if (g3) {
35414f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
35429371c9d4SSatish Balay     *g3 = prob->g3;
35439371c9d4SSatish Balay   }
35443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35452764a2aaSMatthew G. Knepley }
35462764a2aaSMatthew G. Knepley 
3547d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3548d71ae5a4SJacob Faibussowitsch {
35492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
35502764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
35519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
35529371c9d4SSatish Balay   if (x) {
35534f572ea9SToby Isaac     PetscAssertPointer(x, 2);
35549371c9d4SSatish Balay     *x = prob->x;
35559371c9d4SSatish Balay   }
35569371c9d4SSatish Balay   if (basisReal) {
35574f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
35589371c9d4SSatish Balay     *basisReal = prob->basisReal;
35599371c9d4SSatish Balay   }
35609371c9d4SSatish Balay   if (basisDerReal) {
35614f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
35629371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
35639371c9d4SSatish Balay   }
35649371c9d4SSatish Balay   if (testReal) {
35654f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
35669371c9d4SSatish Balay     *testReal = prob->testReal;
35679371c9d4SSatish Balay   }
35689371c9d4SSatish Balay   if (testDerReal) {
35694f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
35709371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
35719371c9d4SSatish Balay   }
35723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35732764a2aaSMatthew G. Knepley }
35742764a2aaSMatthew G. Knepley 
357558ebd649SToby Isaac /*@C
3576a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
357758ebd649SToby Isaac 
357820f4b53cSBarry Smith   Collective
3579783e2ec8SMatthew G. Knepley 
358058ebd649SToby Isaac   Input Parameters:
358158ebd649SToby Isaac + ds       - The PetscDS object
3582dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
358358ebd649SToby Isaac . name     - The BC name
358445480ffeSMatthew G. Knepley . label    - The label defining constrained points
3585dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
358645480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
358758ebd649SToby Isaac . field    - The field to constrain
358845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
358958ebd649SToby Isaac . comps    - An array of constrained component numbers
359058ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3591a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
359258ebd649SToby Isaac - ctx      - An optional user context for bcFunc
359358ebd649SToby Isaac 
35942fe279fdSBarry Smith   Output Parameter:
359560225df5SJacob Faibussowitsch . bd - The boundary number
359645480ffeSMatthew G. Knepley 
359758ebd649SToby Isaac   Options Database Keys:
359858ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
359958ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
360058ebd649SToby Isaac 
3601dce8aebaSBarry Smith   Level: developer
3602dce8aebaSBarry Smith 
360356cf3b9cSMatthew G. Knepley   Note:
3604a4e35b19SJacob 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\:
360556cf3b9cSMatthew G. Knepley 
360620f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
360756cf3b9cSMatthew G. Knepley 
3608a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3609dce8aebaSBarry Smith .vb
361020f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3611dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3612dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3613dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3614dce8aebaSBarry Smith .ve
361556cf3b9cSMatthew G. Knepley + dim - the spatial dimension
361656cf3b9cSMatthew G. Knepley . Nf - the number of fields
361756cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
361856cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
361956cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
362056cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
362156cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
362256cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
362356cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
362456cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
362556cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
362656cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
362756cf3b9cSMatthew G. Knepley . t - current time
362856cf3b9cSMatthew G. Knepley . x - coordinates of the current point
362956cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
363056cf3b9cSMatthew G. Knepley . constants - constant parameters
363156cf3b9cSMatthew G. Knepley - bcval - output values at the current point
363256cf3b9cSMatthew G. Knepley 
3633a4e35b19SJacob Faibussowitsch   Notes:
3634a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3635a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3636a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3637a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3638a4e35b19SJacob Faibussowitsch 
3639dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
364058ebd649SToby Isaac @*/
3641d71ae5a4SJacob 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)
3642d71ae5a4SJacob Faibussowitsch {
364345480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
364445480ffeSMatthew G. Knepley   PetscInt    n    = 0;
364545480ffeSMatthew G. Knepley   const char *lname;
364658ebd649SToby Isaac 
364758ebd649SToby Isaac   PetscFunctionBegin;
364858ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3649783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
36504f572ea9SToby Isaac   PetscAssertPointer(name, 3);
365145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
365245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
365345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
365445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3655dce9da9cSMatthew 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);
3656d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3657d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3658d57bb9dbSMatthew G. Knepley     PetscInt  c;
3659d57bb9dbSMatthew G. Knepley 
36609566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
366163a3b9bcSJacob 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);
3662d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
36631dca8a05SBarry 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);
3664d57bb9dbSMatthew G. Knepley     }
3665d57bb9dbSMatthew G. Knepley   }
36669566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
36679566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
36689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
36699566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
36709566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
36719566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
36729566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
36739566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
36749566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
36759566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3676f971fd6bSMatthew G. Knepley   b->type   = type;
367745480ffeSMatthew G. Knepley   b->label  = label;
367845480ffeSMatthew G. Knepley   b->Nv     = Nv;
367958ebd649SToby Isaac   b->field  = field;
368045480ffeSMatthew G. Knepley   b->Nc     = Nc;
368158ebd649SToby Isaac   b->func   = bcFunc;
368256cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
368358ebd649SToby Isaac   b->ctx    = ctx;
368445480ffeSMatthew G. Knepley   b->next   = NULL;
368545480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
368645480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
368745480ffeSMatthew G. Knepley   while (head) {
368845480ffeSMatthew G. Knepley     if (!head->next) {
368945480ffeSMatthew G. Knepley       head->next = b;
369045480ffeSMatthew G. Knepley       head       = b;
369145480ffeSMatthew G. Knepley     }
369245480ffeSMatthew G. Knepley     head = head->next;
369345480ffeSMatthew G. Knepley     ++n;
369445480ffeSMatthew G. Knepley   }
36959371c9d4SSatish Balay   if (bd) {
36964f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
36979371c9d4SSatish Balay     *bd = n;
36989371c9d4SSatish Balay   }
36993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
370045480ffeSMatthew G. Knepley }
370145480ffeSMatthew G. Knepley 
3702a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
370345480ffeSMatthew G. Knepley /*@C
3704a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
370545480ffeSMatthew G. Knepley 
370620f4b53cSBarry Smith   Collective
370745480ffeSMatthew G. Knepley 
370845480ffeSMatthew G. Knepley   Input Parameters:
3709dce8aebaSBarry Smith + ds       - The `PetscDS` object
3710dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
371145480ffeSMatthew G. Knepley . name     - The BC name
371245480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3713dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
371445480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
371545480ffeSMatthew G. Knepley . field    - The field to constrain
371645480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
371745480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
371845480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3719a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
372045480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
372145480ffeSMatthew G. Knepley 
37222fe279fdSBarry Smith   Output Parameter:
372360225df5SJacob Faibussowitsch . bd - The boundary number
372445480ffeSMatthew G. Knepley 
372545480ffeSMatthew G. Knepley   Options Database Keys:
372645480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
372745480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
372845480ffeSMatthew G. Knepley 
372920f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3730dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3731dce8aebaSBarry Smith .vb
373220f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3733dce8aebaSBarry Smith .ve
3734dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3735dce8aebaSBarry Smith .vb
373620f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3737dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3738dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3739dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3740dce8aebaSBarry Smith .ve
374145480ffeSMatthew G. Knepley + dim - the spatial dimension
374245480ffeSMatthew G. Knepley . Nf - the number of fields
374345480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
374445480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
374545480ffeSMatthew G. Knepley . u - each field evaluated at the current point
374645480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
374745480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
374845480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
374945480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
375045480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
375145480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
375245480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
375345480ffeSMatthew G. Knepley . t - current time
375445480ffeSMatthew G. Knepley . x - coordinates of the current point
375545480ffeSMatthew G. Knepley . numConstants - number of constant parameters
375645480ffeSMatthew G. Knepley . constants - constant parameters
375745480ffeSMatthew G. Knepley - bcval - output values at the current point
375845480ffeSMatthew G. Knepley 
375945480ffeSMatthew G. Knepley   Level: developer
376045480ffeSMatthew G. Knepley 
3761a4e35b19SJacob Faibussowitsch   Notes:
3762a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3763a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3764a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3765a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3766a4e35b19SJacob Faibussowitsch 
3767dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3768dce8aebaSBarry Smith 
3769dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
377045480ffeSMatthew G. Knepley @*/
3771d71ae5a4SJacob 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)
3772d71ae5a4SJacob Faibussowitsch {
377345480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
377445480ffeSMatthew G. Knepley   PetscInt   n    = 0;
377545480ffeSMatthew G. Knepley 
377645480ffeSMatthew G. Knepley   PetscFunctionBegin;
377745480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
377845480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
37794f572ea9SToby Isaac   PetscAssertPointer(name, 3);
37804f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
378145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
378245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
378345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
37849566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
37859566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
37869566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
37879566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
37889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
37899566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
37909566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
37919566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
37929566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
379345480ffeSMatthew G. Knepley   b->type   = type;
379445480ffeSMatthew G. Knepley   b->label  = NULL;
379545480ffeSMatthew G. Knepley   b->Nv     = Nv;
379645480ffeSMatthew G. Knepley   b->field  = field;
379745480ffeSMatthew G. Knepley   b->Nc     = Nc;
379845480ffeSMatthew G. Knepley   b->func   = bcFunc;
379945480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
380045480ffeSMatthew G. Knepley   b->ctx    = ctx;
380145480ffeSMatthew G. Knepley   b->next   = NULL;
380245480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
380345480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
380445480ffeSMatthew G. Knepley   while (head) {
380545480ffeSMatthew G. Knepley     if (!head->next) {
380645480ffeSMatthew G. Knepley       head->next = b;
380745480ffeSMatthew G. Knepley       head       = b;
380845480ffeSMatthew G. Knepley     }
380945480ffeSMatthew G. Knepley     head = head->next;
381045480ffeSMatthew G. Knepley     ++n;
381145480ffeSMatthew G. Knepley   }
38129371c9d4SSatish Balay   if (bd) {
38134f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
38149371c9d4SSatish Balay     *bd = n;
38159371c9d4SSatish Balay   }
38163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
381758ebd649SToby Isaac }
381858ebd649SToby Isaac 
3819b67eacb3SMatthew G. Knepley /*@C
3820a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3821b67eacb3SMatthew G. Knepley 
3822b67eacb3SMatthew G. Knepley   Input Parameters:
3823dce8aebaSBarry Smith + ds       - The `PetscDS` object
3824b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3825dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3826b67eacb3SMatthew G. Knepley . name     - The BC name
382745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3828dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
382945480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3830b67eacb3SMatthew G. Knepley . field    - The field to constrain
383145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3832b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3833b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3834a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3835b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3836b67eacb3SMatthew G. Knepley 
3837b67eacb3SMatthew G. Knepley   Level: developer
3838b67eacb3SMatthew G. Knepley 
3839a4e35b19SJacob Faibussowitsch   Notes:
3840a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3841a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3842a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3843a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3844a4e35b19SJacob Faibussowitsch 
3845dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3846dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3847dce8aebaSBarry Smith 
3848dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3849b67eacb3SMatthew G. Knepley @*/
3850d71ae5a4SJacob 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)
3851d71ae5a4SJacob Faibussowitsch {
3852b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3853b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3854b67eacb3SMatthew G. Knepley 
3855b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3856b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3857b67eacb3SMatthew G. Knepley   while (b) {
3858b67eacb3SMatthew G. Knepley     if (n == bd) break;
3859b67eacb3SMatthew G. Knepley     b = b->next;
3860b67eacb3SMatthew G. Knepley     ++n;
3861b67eacb3SMatthew G. Knepley   }
386263a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3863b67eacb3SMatthew G. Knepley   if (name) {
38649566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38659566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3866b67eacb3SMatthew G. Knepley   }
3867b67eacb3SMatthew G. Knepley   b->type = type;
386845480ffeSMatthew G. Knepley   if (label) {
386945480ffeSMatthew G. Knepley     const char *name;
387045480ffeSMatthew G. Knepley 
387145480ffeSMatthew G. Knepley     b->label = label;
38729566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38739566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
38749566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
387545480ffeSMatthew G. Knepley   }
387645480ffeSMatthew G. Knepley   if (Nv >= 0) {
387745480ffeSMatthew G. Knepley     b->Nv = Nv;
38789566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38799566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
38809566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
388145480ffeSMatthew G. Knepley   }
388245480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
388345480ffeSMatthew G. Knepley   if (Nc >= 0) {
388445480ffeSMatthew G. Knepley     b->Nc = Nc;
38859566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38869566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
38879566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
388845480ffeSMatthew G. Knepley   }
388945480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
389045480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
389145480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
38923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3893b67eacb3SMatthew G. Knepley }
3894b67eacb3SMatthew G. Knepley 
389558ebd649SToby Isaac /*@
389658ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
389758ebd649SToby Isaac 
38982fe279fdSBarry Smith   Input Parameter:
3899dce8aebaSBarry Smith . ds - The `PetscDS` object
390058ebd649SToby Isaac 
39012fe279fdSBarry Smith   Output Parameter:
390258ebd649SToby Isaac . numBd - The number of BC
390358ebd649SToby Isaac 
390458ebd649SToby Isaac   Level: intermediate
390558ebd649SToby Isaac 
3906dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
390758ebd649SToby Isaac @*/
3908d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3909d71ae5a4SJacob Faibussowitsch {
391058ebd649SToby Isaac   DSBoundary b = ds->boundary;
391158ebd649SToby Isaac 
391258ebd649SToby Isaac   PetscFunctionBegin;
391358ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
39144f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
391558ebd649SToby Isaac   *numBd = 0;
39169371c9d4SSatish Balay   while (b) {
39179371c9d4SSatish Balay     ++(*numBd);
39189371c9d4SSatish Balay     b = b->next;
39199371c9d4SSatish Balay   }
39203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
392158ebd649SToby Isaac }
392258ebd649SToby Isaac 
392358ebd649SToby Isaac /*@C
39249a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
392558ebd649SToby Isaac 
392658ebd649SToby Isaac   Input Parameters:
3927dce8aebaSBarry Smith + ds - The `PetscDS` object
392858ebd649SToby Isaac - bd - The BC number
392958ebd649SToby Isaac 
393058ebd649SToby Isaac   Output Parameters:
3931dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3932dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
393358ebd649SToby Isaac . name   - The BC name
393445480ffeSMatthew G. Knepley . label  - The label defining constrained points
3935dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
393645480ffeSMatthew G. Knepley . values - An array of ids for constrained points
393758ebd649SToby Isaac . field  - The field to constrain
393845480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
393958ebd649SToby Isaac . comps  - An array of constrained component numbers
394060225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
394160225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
394258ebd649SToby Isaac - ctx    - An optional user context for bcFunc
394358ebd649SToby Isaac 
394458ebd649SToby Isaac   Options Database Keys:
394558ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
394658ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
394758ebd649SToby Isaac 
394858ebd649SToby Isaac   Level: developer
394958ebd649SToby Isaac 
3950dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
395158ebd649SToby Isaac @*/
3952d71ae5a4SJacob 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)
3953d71ae5a4SJacob Faibussowitsch {
395458ebd649SToby Isaac   DSBoundary b = ds->boundary;
395558ebd649SToby Isaac   PetscInt   n = 0;
395658ebd649SToby Isaac 
395758ebd649SToby Isaac   PetscFunctionBegin;
395858ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
395958ebd649SToby Isaac   while (b) {
396058ebd649SToby Isaac     if (n == bd) break;
396158ebd649SToby Isaac     b = b->next;
396258ebd649SToby Isaac     ++n;
396358ebd649SToby Isaac   }
396463a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
396545480ffeSMatthew G. Knepley   if (wf) {
39664f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
396745480ffeSMatthew G. Knepley     *wf = b->wf;
396845480ffeSMatthew G. Knepley   }
3969f971fd6bSMatthew G. Knepley   if (type) {
39704f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3971f971fd6bSMatthew G. Knepley     *type = b->type;
397258ebd649SToby Isaac   }
397358ebd649SToby Isaac   if (name) {
39744f572ea9SToby Isaac     PetscAssertPointer(name, 5);
397558ebd649SToby Isaac     *name = b->name;
397658ebd649SToby Isaac   }
397745480ffeSMatthew G. Knepley   if (label) {
39784f572ea9SToby Isaac     PetscAssertPointer(label, 6);
397945480ffeSMatthew G. Knepley     *label = b->label;
398045480ffeSMatthew G. Knepley   }
398145480ffeSMatthew G. Knepley   if (Nv) {
39824f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
398345480ffeSMatthew G. Knepley     *Nv = b->Nv;
398445480ffeSMatthew G. Knepley   }
398545480ffeSMatthew G. Knepley   if (values) {
39864f572ea9SToby Isaac     PetscAssertPointer(values, 8);
398745480ffeSMatthew G. Knepley     *values = b->values;
398858ebd649SToby Isaac   }
398958ebd649SToby Isaac   if (field) {
39904f572ea9SToby Isaac     PetscAssertPointer(field, 9);
399158ebd649SToby Isaac     *field = b->field;
399258ebd649SToby Isaac   }
399345480ffeSMatthew G. Knepley   if (Nc) {
39944f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
399545480ffeSMatthew G. Knepley     *Nc = b->Nc;
399658ebd649SToby Isaac   }
399758ebd649SToby Isaac   if (comps) {
39984f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
399958ebd649SToby Isaac     *comps = b->comps;
400058ebd649SToby Isaac   }
400158ebd649SToby Isaac   if (func) {
40024f572ea9SToby Isaac     PetscAssertPointer(func, 12);
400358ebd649SToby Isaac     *func = b->func;
400458ebd649SToby Isaac   }
400556cf3b9cSMatthew G. Knepley   if (func_t) {
40064f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
400756cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
400856cf3b9cSMatthew G. Knepley   }
400958ebd649SToby Isaac   if (ctx) {
40104f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
401158ebd649SToby Isaac     *ctx = b->ctx;
401258ebd649SToby Isaac   }
40133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
401458ebd649SToby Isaac }
401558ebd649SToby Isaac 
401610af620dSMatthew G. Knepley /*@
401710af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
401810af620dSMatthew G. Knepley 
401910af620dSMatthew G. Knepley   Not Collective
402010af620dSMatthew G. Knepley 
402110af620dSMatthew G. Knepley   Input Parameters:
402210af620dSMatthew G. Knepley + ds - The source `PetscDS` object
402310af620dSMatthew G. Knepley - dm - The `DM` holding labels
402410af620dSMatthew G. Knepley 
402510af620dSMatthew G. Knepley   Level: intermediate
402610af620dSMatthew G. Knepley 
402710af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
402810af620dSMatthew G. Knepley @*/
402910af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
403010af620dSMatthew G. Knepley {
403110af620dSMatthew G. Knepley   DSBoundary b;
403210af620dSMatthew G. Knepley 
403310af620dSMatthew G. Knepley   PetscFunctionBegin;
403410af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
403510af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
403610af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
403710af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
403810af620dSMatthew G. Knepley   }
403910af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
404010af620dSMatthew G. Knepley }
404110af620dSMatthew G. Knepley 
4042d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
4043d71ae5a4SJacob Faibussowitsch {
404445480ffeSMatthew G. Knepley   PetscFunctionBegin;
40459566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
40469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
40479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
40489566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
40499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
405045480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
405145480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
405245480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
40539566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
40549566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
405545480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
405645480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
40579566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
40589566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
405945480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
406045480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
406145480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
40623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
406345480ffeSMatthew G. Knepley }
406445480ffeSMatthew G. Knepley 
40659252d075SMatthew G. Knepley /*@
40669252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
40679252d075SMatthew G. Knepley 
406820f4b53cSBarry Smith   Not Collective
40699252d075SMatthew G. Knepley 
407036951cb5SMatthew G. Knepley   Input Parameters:
4071dce8aebaSBarry Smith + ds        - The source `PetscDS` object
4072dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
407336951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
40749252d075SMatthew G. Knepley 
40759252d075SMatthew G. Knepley   Output Parameter:
4076dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
40779252d075SMatthew G. Knepley 
40789252d075SMatthew G. Knepley   Level: intermediate
40799252d075SMatthew G. Knepley 
4080dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40819252d075SMatthew G. Knepley @*/
4082d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
4083d71ae5a4SJacob Faibussowitsch {
408445480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
4085dff059c6SToby Isaac 
4086dff059c6SToby Isaac   PetscFunctionBegin;
408736951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
408836951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
40893ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
40909566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
4091f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
409236951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
4093dff059c6SToby Isaac     DSBoundary bNew;
409436951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
4095dff059c6SToby Isaac 
409636951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
409736951cb5SMatthew G. Knepley       PetscInt f;
409836951cb5SMatthew G. Knepley 
40999371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
41009371c9d4SSatish Balay         if (b->field == fields[f]) break;
410136951cb5SMatthew G. Knepley       if (f == numFields) continue;
410236951cb5SMatthew G. Knepley       fieldNew = f;
410336951cb5SMatthew G. Knepley     }
41049566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
410536951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
4106dff059c6SToby Isaac     *lastnext   = bNew;
4107f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
4108dff059c6SToby Isaac   }
41093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4110dff059c6SToby Isaac }
4111dff059c6SToby Isaac 
41126c1eb96dSMatthew G. Knepley /*@
4113dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
411445480ffeSMatthew G. Knepley 
411520f4b53cSBarry Smith   Not Collective
411645480ffeSMatthew G. Knepley 
411745480ffeSMatthew G. Knepley   Input Parameter:
4118dce8aebaSBarry Smith . ds - The `PetscDS` object
411945480ffeSMatthew G. Knepley 
412045480ffeSMatthew G. Knepley   Level: intermediate
412145480ffeSMatthew G. Knepley 
4122dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
412345480ffeSMatthew G. Knepley @*/
4124d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
4125d71ae5a4SJacob Faibussowitsch {
412645480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
412745480ffeSMatthew G. Knepley 
412845480ffeSMatthew G. Knepley   PetscFunctionBegin;
412945480ffeSMatthew G. Knepley   while (next) {
413045480ffeSMatthew G. Knepley     DSBoundary b = next;
413145480ffeSMatthew G. Knepley 
413245480ffeSMatthew G. Knepley     next = b->next;
41339566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
41349566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
41359566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
41369566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
41379566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
41389566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
413945480ffeSMatthew G. Knepley   }
41403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
414145480ffeSMatthew G. Knepley }
414245480ffeSMatthew G. Knepley 
414345480ffeSMatthew G. Knepley /*@
41446c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
41456c1eb96dSMatthew G. Knepley 
414620f4b53cSBarry Smith   Not Collective
41476c1eb96dSMatthew G. Knepley 
4148d8d19677SJose E. Roman   Input Parameters:
4149dce8aebaSBarry Smith + prob      - The `PetscDS` object
41506c1eb96dSMatthew G. Knepley . numFields - Number of new fields
4151bb4b53efSMatthew G. Knepley . fields    - Old field number for each new field
4152bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit
4153bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit
41546c1eb96dSMatthew G. Knepley 
41556c1eb96dSMatthew G. Knepley   Output Parameter:
4156dce8aebaSBarry Smith . newprob - The `PetscDS` copy
41576c1eb96dSMatthew G. Knepley 
41586c1eb96dSMatthew G. Knepley   Level: intermediate
41596c1eb96dSMatthew G. Knepley 
4160dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
41616c1eb96dSMatthew G. Knepley @*/
4162bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscInt minDegree, PetscInt maxDegree, PetscDS newprob)
4163d71ae5a4SJacob Faibussowitsch {
41646c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
41656c1eb96dSMatthew G. Knepley 
41666c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
41676c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41684f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
4169bb4b53efSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 6);
41709566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41719566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
417245480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
41736c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
41746c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
41756c1eb96dSMatthew G. Knepley     PetscObject    disc;
4176bb4b53efSMatthew G. Knepley     PetscClassId   id;
41776c1eb96dSMatthew G. Knepley 
41786c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
41799566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
4180bb4b53efSMatthew G. Knepley     PetscCallContinue(PetscObjectGetClassId(disc, &id));
4181bb4b53efSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
4182bb4b53efSMatthew G. Knepley       PetscFE fe;
4183bb4b53efSMatthew G. Knepley 
4184bb4b53efSMatthew G. Knepley       PetscCall(PetscFELimitDegree((PetscFE)disc, minDegree, maxDegree, &fe));
4185bb4b53efSMatthew G. Knepley       PetscCall(PetscDSSetDiscretization(newprob, fn, (PetscObject)fe));
4186bb4b53efSMatthew G. Knepley       PetscCall(PetscFEDestroy(&fe));
4187bb4b53efSMatthew G. Knepley     } else {
41889566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
41896c1eb96dSMatthew G. Knepley     }
4190bb4b53efSMatthew G. Knepley   }
41913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41926c1eb96dSMatthew G. Knepley }
41936c1eb96dSMatthew G. Knepley 
41946c1eb96dSMatthew G. Knepley /*@
41959252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
41969252d075SMatthew G. Knepley 
419720f4b53cSBarry Smith   Not Collective
41989252d075SMatthew G. Knepley 
4199d8d19677SJose E. Roman   Input Parameters:
4200dce8aebaSBarry Smith + prob      - The `PetscDS` object
42019252d075SMatthew G. Knepley . numFields - Number of new fields
42029252d075SMatthew G. Knepley - fields    - Old field number for each new field
42039252d075SMatthew G. Knepley 
42049252d075SMatthew G. Knepley   Output Parameter:
4205dce8aebaSBarry Smith . newprob - The `PetscDS` copy
42069252d075SMatthew G. Knepley 
42079252d075SMatthew G. Knepley   Level: intermediate
42089252d075SMatthew G. Knepley 
4209dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
42109252d075SMatthew G. Knepley @*/
4211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
4212d71ae5a4SJacob Faibussowitsch {
42139252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
42149252d075SMatthew G. Knepley 
42159252d075SMatthew G. Knepley   PetscFunctionBegin;
42169252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
42174f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
42189252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
42199566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
42209566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
422163a3b9bcSJacob 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);
42229252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
42239252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
42249252d075SMatthew G. Knepley     PetscPointFunc   obj;
42259252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
42269252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
42279252d075SMatthew G. Knepley     PetscRiemannFunc r;
42289252d075SMatthew G. Knepley 
4229c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
42309566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
42319566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
42329566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
42339566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
42349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
42359566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
42369566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
42379566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
42389252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
42399252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
42409252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
42419252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
42429252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
42439252d075SMatthew G. Knepley 
4244c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
42459566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
42469566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
42479566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
42489566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
42499566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
42509566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
42519252d075SMatthew G. Knepley     }
42529252d075SMatthew G. Knepley   }
42533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42549252d075SMatthew G. Knepley }
42559252d075SMatthew G. Knepley 
4256da51fcedSMatthew G. Knepley /*@
4257dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
4258da51fcedSMatthew G. Knepley 
425920f4b53cSBarry Smith   Not Collective
4260da51fcedSMatthew G. Knepley 
4261da51fcedSMatthew G. Knepley   Input Parameter:
4262dce8aebaSBarry Smith . prob - The `PetscDS` object
4263da51fcedSMatthew G. Knepley 
4264da51fcedSMatthew G. Knepley   Output Parameter:
4265dce8aebaSBarry Smith . newprob - The `PetscDS` copy
4266da51fcedSMatthew G. Knepley 
4267da51fcedSMatthew G. Knepley   Level: intermediate
4268da51fcedSMatthew G. Knepley 
4269dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4270da51fcedSMatthew G. Knepley @*/
4271d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
4272d71ae5a4SJacob Faibussowitsch {
4273b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
42749252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4275da51fcedSMatthew G. Knepley 
4276da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4277da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4278da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
42799566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
42809566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
428163a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
42829566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
42839566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
42849566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
42853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42869252d075SMatthew G. Knepley }
428745480ffeSMatthew G. Knepley 
42889252d075SMatthew G. Knepley /*@
4289dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4290da51fcedSMatthew G. Knepley 
429120f4b53cSBarry Smith   Not Collective
42929252d075SMatthew G. Knepley 
42939252d075SMatthew G. Knepley   Input Parameter:
4294dce8aebaSBarry Smith . prob - The `PetscDS` object
42959252d075SMatthew G. Knepley 
42969252d075SMatthew G. Knepley   Output Parameter:
4297dce8aebaSBarry Smith . newprob - The `PetscDS` copy
42989252d075SMatthew G. Knepley 
42999252d075SMatthew G. Knepley   Level: intermediate
43009252d075SMatthew G. Knepley 
4301dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
43029252d075SMatthew G. Knepley @*/
4303d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4304d71ae5a4SJacob Faibussowitsch {
43059252d075SMatthew G. Knepley   PetscInt           Nc;
43069252d075SMatthew G. Knepley   const PetscScalar *constants;
43079252d075SMatthew G. Knepley 
43089252d075SMatthew G. Knepley   PetscFunctionBegin;
43099252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
43109252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
43119566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
43129566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
43133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4314da51fcedSMatthew G. Knepley }
4315da51fcedSMatthew G. Knepley 
431645480ffeSMatthew G. Knepley /*@
4317dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
431845480ffeSMatthew G. Knepley 
431920f4b53cSBarry Smith   Not Collective
432045480ffeSMatthew G. Knepley 
432145480ffeSMatthew G. Knepley   Input Parameter:
4322dce8aebaSBarry Smith . ds - The `PetscDS` object
432345480ffeSMatthew G. Knepley 
432445480ffeSMatthew G. Knepley   Output Parameter:
4325dce8aebaSBarry Smith . newds - The `PetscDS` copy
432645480ffeSMatthew G. Knepley 
432745480ffeSMatthew G. Knepley   Level: intermediate
432845480ffeSMatthew G. Knepley 
4329*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyBounds()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
433045480ffeSMatthew G. Knepley @*/
4331d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4332d71ae5a4SJacob Faibussowitsch {
43338434afd1SBarry Smith   PetscSimplePointFn *sol;
433445480ffeSMatthew G. Knepley   void               *ctx;
433545480ffeSMatthew G. Knepley   PetscInt            Nf, f;
433645480ffeSMatthew G. Knepley 
433745480ffeSMatthew G. Knepley   PetscFunctionBegin;
433845480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
433945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
43409566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
434145480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
43429566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
43439566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
43449566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
43459566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
434645480ffeSMatthew G. Knepley   }
43473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
434845480ffeSMatthew G. Knepley }
434945480ffeSMatthew G. Knepley 
4350*342bd5aaSMatthew G. Knepley /*@
4351*342bd5aaSMatthew G. Knepley   PetscDSCopyBounds - Copy lower and upper solution bounds to another `PetscDS`
4352*342bd5aaSMatthew G. Knepley 
4353*342bd5aaSMatthew G. Knepley   Not Collective
4354*342bd5aaSMatthew G. Knepley 
4355*342bd5aaSMatthew G. Knepley   Input Parameter:
4356*342bd5aaSMatthew G. Knepley . ds - The `PetscDS` object
4357*342bd5aaSMatthew G. Knepley 
4358*342bd5aaSMatthew G. Knepley   Output Parameter:
4359*342bd5aaSMatthew G. Knepley . newds - The `PetscDS` copy
4360*342bd5aaSMatthew G. Knepley 
4361*342bd5aaSMatthew G. Knepley   Level: intermediate
4362*342bd5aaSMatthew G. Knepley 
4363*342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyExactSolutions()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4364*342bd5aaSMatthew G. Knepley @*/
4365*342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSCopyBounds(PetscDS ds, PetscDS newds)
4366*342bd5aaSMatthew G. Knepley {
4367*342bd5aaSMatthew G. Knepley   PetscSimplePointFn *bound;
4368*342bd5aaSMatthew G. Knepley   void               *ctx;
4369*342bd5aaSMatthew G. Knepley   PetscInt            Nf, f;
4370*342bd5aaSMatthew G. Knepley 
4371*342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
4372*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4373*342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
4374*342bd5aaSMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
4375*342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4376*342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetLowerBound(ds, f, &bound, &ctx));
4377*342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetLowerBound(newds, f, bound, ctx));
4378*342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetUpperBound(ds, f, &bound, &ctx));
4379*342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetUpperBound(newds, f, bound, ctx));
4380*342bd5aaSMatthew G. Knepley   }
4381*342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
4382*342bd5aaSMatthew G. Knepley }
4383*342bd5aaSMatthew G. Knepley 
4384bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, PetscInt minDegree, PetscInt maxDegree, DM dmNew, PetscDS dsNew)
438507218a29SMatthew G. Knepley {
438607218a29SMatthew G. Knepley   DSBoundary b;
438707218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
438807218a29SMatthew G. Knepley   PetscBool  isCohesive;
438907218a29SMatthew G. Knepley   void      *ctx;
439007218a29SMatthew G. Knepley 
439107218a29SMatthew G. Knepley   PetscFunctionBegin;
439207218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
439307218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
4394*342bd5aaSMatthew G. Knepley   PetscCall(PetscDSCopyBounds(ds, dsNew));
4395bb4b53efSMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, minDegree, maxDegree, dsNew));
439607218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
439707218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
439807218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
439907218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
440007218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
440107218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
440207218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
440307218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
440407218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
440507218a29SMatthew G. Knepley   }
440607218a29SMatthew G. Knepley   if (Nf) {
440707218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
440807218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
440907218a29SMatthew G. Knepley   }
441007218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
441107218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
441207218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
441307218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
441407218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
441507218a29SMatthew G. Knepley   }
441607218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
441707218a29SMatthew G. Knepley }
441807218a29SMatthew G. Knepley 
4419d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4420d71ae5a4SJacob Faibussowitsch {
4421df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4422b1353e8eSMatthew G. Knepley 
4423b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4424b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
44254f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
44269371c9d4SSatish Balay   if (height == 0) {
44279371c9d4SSatish Balay     *subprob = prob;
44283ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
44299371c9d4SSatish Balay   }
44309566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
44319566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
443263a3b9bcSJacob 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);
44339566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4434df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4435b1353e8eSMatthew G. Knepley     PetscInt cdim;
4436b1353e8eSMatthew G. Knepley 
44379566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
44389566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
44399566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4440b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4441b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4442b1353e8eSMatthew G. Knepley       PetscObject  obj;
4443b1353e8eSMatthew G. Knepley       PetscClassId id;
4444b1353e8eSMatthew G. Knepley 
44459566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
44469566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
44479566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
444863a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
44499566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4450b1353e8eSMatthew G. Knepley     }
4451b1353e8eSMatthew G. Knepley   }
4452df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
44533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4454b1353e8eSMatthew G. Knepley }
4455b1353e8eSMatthew G. Knepley 
44564366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
44574366bac7SMatthew G. Knepley {
44584366bac7SMatthew G. Knepley   IS              permIS;
44594366bac7SMatthew G. Knepley   PetscQuadrature quad;
44604366bac7SMatthew G. Knepley   DMPolytopeType  ct;
44614366bac7SMatthew G. Knepley   const PetscInt *perm;
44624366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
44634366bac7SMatthew G. Knepley 
44644366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
44654366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
44664366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
44674366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
44684366bac7SMatthew 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);
446985036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
44704366bac7SMatthew 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);
44714366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
44724366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
44734366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
44744366bac7SMatthew G. Knepley   *qperm = perm[q];
44754366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
44764366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
44774366bac7SMatthew G. Knepley }
44784366bac7SMatthew G. Knepley 
4479d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4480d71ae5a4SJacob Faibussowitsch {
4481c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4482c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4483c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4484c7bd5f0bSMatthew G. Knepley 
4485c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4486c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
44874f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4488665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
44899566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
449063a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
44919566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4492665f567fSMatthew G. Knepley   if (obj) {
44939566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4494665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4495665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4496665f567fSMatthew G. Knepley   }
44973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4498c7bd5f0bSMatthew G. Knepley }
4499c7bd5f0bSMatthew G. Knepley 
4500d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4501d71ae5a4SJacob Faibussowitsch {
45022764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45039566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
45043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45052764a2aaSMatthew G. Knepley }
45062764a2aaSMatthew G. Knepley 
4507d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4508d71ae5a4SJacob Faibussowitsch {
45092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45106528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
45116528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
45126528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
45136528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
45143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45152764a2aaSMatthew G. Knepley }
45162764a2aaSMatthew G. Knepley 
45172764a2aaSMatthew G. Knepley /*MC
45182764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
45192764a2aaSMatthew G. Knepley 
45202764a2aaSMatthew G. Knepley   Level: intermediate
45212764a2aaSMatthew G. Knepley 
4522db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
45232764a2aaSMatthew G. Knepley M*/
45242764a2aaSMatthew G. Knepley 
4525d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4526d71ae5a4SJacob Faibussowitsch {
45272764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
45282764a2aaSMatthew G. Knepley 
45292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
45306528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
45314dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
45326528b96dSMatthew G. Knepley   ds->data = b;
45332764a2aaSMatthew G. Knepley 
45349566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
45353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45362764a2aaSMatthew G. Knepley }
4537