xref: /petsc/src/dm/dt/interface/dtds.c (revision ffeef943c8ee50edff320d8a3135bb0c94853e4c)
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 
234*ffeef943SBarry 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 
256*ffeef943SBarry Smith /*@
257dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2582764a2aaSMatthew G. Knepley 
25920f4b53cSBarry Smith   Collective
2602764a2aaSMatthew G. Knepley 
261d8d19677SJose E. Roman   Input Parameters:
262dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2632764a2aaSMatthew G. Knepley - v    - the viewer
2642764a2aaSMatthew G. Knepley 
2652764a2aaSMatthew G. Knepley   Level: developer
2662764a2aaSMatthew G. Knepley 
26720f4b53cSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`, `PetscDSViewFromOptions()`
2682764a2aaSMatthew G. Knepley @*/
269d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
270d71ae5a4SJacob Faibussowitsch {
2717d8a60eaSMatthew G. Knepley   PetscBool iascii;
2722764a2aaSMatthew G. Knepley 
2732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2742764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2759566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
276ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2789566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
279dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2812764a2aaSMatthew G. Knepley }
2822764a2aaSMatthew G. Knepley 
2832764a2aaSMatthew G. Knepley /*@
284dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2852764a2aaSMatthew G. Knepley 
28620f4b53cSBarry Smith   Collective
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   Input Parameter:
289dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2902764a2aaSMatthew G. Knepley 
291dce8aebaSBarry Smith   Options Database Keys:
292dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
293dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
294147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
295147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
296147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
2972764a2aaSMatthew G. Knepley 
298dce8aebaSBarry Smith   Level: intermediate
2992764a2aaSMatthew G. Knepley 
300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3012764a2aaSMatthew G. Knepley @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
303d71ae5a4SJacob Faibussowitsch {
304f1fd5e65SToby Isaac   DSBoundary  b;
3052764a2aaSMatthew G. Knepley   const char *defaultType;
3062764a2aaSMatthew G. Knepley   char        name[256];
3072764a2aaSMatthew G. Knepley   PetscBool   flg;
3082764a2aaSMatthew G. Knepley 
3092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3102764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3112764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3122764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3132764a2aaSMatthew G. Knepley   } else {
3142764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3152764a2aaSMatthew G. Knepley   }
3169566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3172764a2aaSMatthew G. Knepley 
318d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
319f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
320f1fd5e65SToby Isaac     char      optname[1024];
321f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
322f1fd5e65SToby Isaac     PetscBool flg;
323f1fd5e65SToby Isaac 
3249566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3259566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
327f1fd5e65SToby Isaac     if (flg) {
32845480ffeSMatthew G. Knepley       b->Nv = len;
3299566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3309566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3319566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3329566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
333f1fd5e65SToby Isaac     }
334e7b0402cSSander Arens     len = 1024;
3359566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3369566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
338f1fd5e65SToby Isaac     if (flg) {
33945480ffeSMatthew G. Knepley       b->Nc = len;
3409566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3429566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
343f1fd5e65SToby Isaac     }
344f1fd5e65SToby Isaac   }
3459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3462764a2aaSMatthew G. Knepley   if (flg) {
3479566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3482764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3499566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3502764a2aaSMatthew G. Knepley   }
3519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
35212fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
353b2deab97SMatthew G. Knepley   PetscCall(PetscOptionsInt("-petscds_print_integrate", "Discrete System", "", prob->printIntegrate, &prob->printIntegrate, NULL));
354dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3552764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
356dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
357d0609cedSBarry Smith   PetscOptionsEnd();
3589566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3602764a2aaSMatthew G. Knepley }
3612764a2aaSMatthew G. Knepley 
362cc4c1da9SBarry Smith /*@
363dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3642764a2aaSMatthew G. Knepley 
36520f4b53cSBarry Smith   Collective
3662764a2aaSMatthew G. Knepley 
3672764a2aaSMatthew G. Knepley   Input Parameter:
368dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3692764a2aaSMatthew G. Knepley 
3702764a2aaSMatthew G. Knepley   Level: developer
3712764a2aaSMatthew G. Knepley 
372dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3732764a2aaSMatthew G. Knepley @*/
374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
375d71ae5a4SJacob Faibussowitsch {
3762764a2aaSMatthew G. Knepley   const PetscInt Nf          = prob->Nf;
377f9244615SMatthew G. Knepley   PetscBool      hasH        = PETSC_FALSE;
378e59ddd55SMatthew G. Knepley   PetscInt       maxOrder[4] = {-2, -2, -2, -2};
3794bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3802764a2aaSMatthew G. Knepley 
3812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3822764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3833ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3842764a2aaSMatthew G. Knepley   /* Calculate sizes */
3859566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3869566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
387f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3899566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3909566063dSJacob Faibussowitsch   PetscCall(PetscCalloc6(Nf + 1, &prob->offCohesive[0], Nf + 1, &prob->offCohesive[1], Nf + 1, &prob->offCohesive[2], Nf + 1, &prob->offDerCohesive[0], Nf + 1, &prob->offDerCohesive[1], Nf + 1, &prob->offDerCohesive[2]));
3919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
39212fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
39307218a29SMatthew G. Knepley     // Note: This assumes we have one kind of cell at each dimension.
39407218a29SMatthew G. Knepley     //       We can fix this by having quadrature hold the celltype
39507218a29SMatthew G. Knepley     PetscQuadrature maxQuad[4] = {NULL, NULL, NULL, NULL};
39612fc5b22SMatthew G. Knepley 
39712fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
39812fc5b22SMatthew G. Knepley       PetscObject     obj;
39912fc5b22SMatthew G. Knepley       PetscClassId    id;
40012fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
40107218a29SMatthew G. Knepley       PetscInt        dim = -1, order = -1, forder = -1;
40212fc5b22SMatthew G. Knepley 
40312fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40412fc5b22SMatthew G. Knepley       if (!obj) continue;
40512fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
40612fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
40712fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
40812fc5b22SMatthew G. Knepley 
40912fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
41012fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
41112fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41212fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
41312fc5b22SMatthew G. Knepley 
41412fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
41512fc5b22SMatthew G. Knepley       }
41607218a29SMatthew G. Knepley       if (q) {
41707218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
41807218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(q, &order));
41907218a29SMatthew G. Knepley         if (order > maxOrder[dim]) {
42007218a29SMatthew G. Knepley           maxOrder[dim] = order;
42107218a29SMatthew G. Knepley           maxQuad[dim]  = q;
42212fc5b22SMatthew G. Knepley         }
42307218a29SMatthew G. Knepley       }
42407218a29SMatthew G. Knepley       if (fq) {
42507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
42607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(fq, &forder));
42707218a29SMatthew G. Knepley         if (forder > maxOrder[dim]) {
42807218a29SMatthew G. Knepley           maxOrder[dim] = forder;
42907218a29SMatthew G. Knepley           maxQuad[dim]  = fq;
43007218a29SMatthew G. Knepley         }
43112fc5b22SMatthew G. Knepley       }
43212fc5b22SMatthew G. Knepley     }
43312fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
43412fc5b22SMatthew G. Knepley       PetscObject     obj;
43512fc5b22SMatthew G. Knepley       PetscClassId    id;
43607218a29SMatthew G. Knepley       PetscQuadrature q;
43707218a29SMatthew G. Knepley       PetscInt        dim;
43812fc5b22SMatthew G. Knepley 
43912fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
44012fc5b22SMatthew G. Knepley       if (!obj) continue;
44112fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44212fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44312fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44412fc5b22SMatthew G. Knepley 
44507218a29SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
44607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
44707218a29SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, maxQuad[dim]));
448aa9788aaSMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, dim ? maxQuad[dim - 1] : NULL));
44912fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
45012fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
45112fc5b22SMatthew G. Knepley 
45207218a29SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
45307218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
45407218a29SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, maxQuad[dim]));
45512fc5b22SMatthew G. Knepley       }
45612fc5b22SMatthew G. Knepley     }
45712fc5b22SMatthew G. Knepley   }
4582764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4599de99aefSMatthew G. Knepley     PetscObject     obj;
4609de99aefSMatthew G. Knepley     PetscClassId    id;
461665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4629de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4632764a2aaSMatthew G. Knepley 
4649566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
465f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
466665f567fSMatthew G. Knepley     if (!obj) {
467665f567fSMatthew G. Knepley       /* Empty mesh */
468665f567fSMatthew G. Knepley       Nb = Nc    = 0;
469665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
470665f567fSMatthew G. Knepley     } else {
4719566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4729de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4739de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4749de99aefSMatthew G. Knepley 
4759566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
47649ae0b56SMatthew G. Knepley         {
47749ae0b56SMatthew G. Knepley           PetscQuadrature fq;
47807218a29SMatthew G. Knepley           PetscInt        dim, order;
47949ae0b56SMatthew G. Knepley 
48007218a29SMatthew G. Knepley           PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
48149ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
48207218a29SMatthew G. Knepley           if (maxOrder[dim] < 0) maxOrder[dim] = order;
48307218a29SMatthew G. Knepley           PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, maxOrder[dim]);
48449ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
48549ae0b56SMatthew G. Knepley           if (fq) {
48607218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
48707218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &order));
48807218a29SMatthew G. Knepley             if (maxOrder[dim] < 0) maxOrder[dim] = order;
48907218a29SMatthew G. Knepley             PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, order, maxOrder[dim]);
49049ae0b56SMatthew G. Knepley           }
49149ae0b56SMatthew G. Knepley         }
4929566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4949566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4959566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4969de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4979de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4989de99aefSMatthew G. Knepley 
4999566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
5009566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
5019c3cf19fSMatthew G. Knepley         Nb = Nc;
5029566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
5034d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
50463a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
505665f567fSMatthew G. Knepley     }
50647e57110SSander Arens     prob->Nc[f]                    = Nc;
50747e57110SSander Arens     prob->Nb[f]                    = Nb;
508194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
509194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5109ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5119ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5129ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5139ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5149ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5159ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5169566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5172764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5184bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5192764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5209c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5212764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5225fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5235fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5242764a2aaSMatthew G. Knepley   }
5259ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5269ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5272764a2aaSMatthew G. Knepley   /* Allocate works space */
5285fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(NsMax * prob->totComp, &prob->u, NsMax * prob->totComp, &prob->u_t, NsMax * prob->totComp * dimEmbed + (hasH ? NsMax * prob->totComp * dimEmbed * dimEmbed : 0), &prob->u_x));
5309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5319371c9d4SSatish Balay   PetscCall(PetscMalloc6(NsMax * NqMax * NcMax, &prob->f0, NsMax * NqMax * NcMax * dimEmbed, &prob->f1, NsMax * NsMax * NqMax * NcMax * NcMax, &prob->g0, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed, &prob->g1, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed,
5329371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
533dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5342764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5362764a2aaSMatthew G. Knepley }
5372764a2aaSMatthew G. Knepley 
538d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
539d71ae5a4SJacob Faibussowitsch {
5402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5429566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5439566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5449566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5459566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5479566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5492764a2aaSMatthew G. Knepley }
5502764a2aaSMatthew G. Knepley 
551d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
552d71ae5a4SJacob Faibussowitsch {
553f744cafaSSander Arens   PetscObject         *tmpd;
55434aa8a36SMatthew G. Knepley   PetscBool           *tmpi;
555f9244615SMatthew G. Knepley   PetscInt            *tmpk;
5565fedec97SMatthew G. Knepley   PetscBool           *tmpc;
5576528b96dSMatthew G. Knepley   PetscPointFunc      *tmpup;
5588434afd1SBarry Smith   PetscSimplePointFn **tmpexactSol, **tmpexactSol_t;
559f2cacb80SMatthew G. Knepley   void               **tmpexactCtx, **tmpexactCtx_t;
5600c2f2876SMatthew G. Knepley   void               **tmpctx;
56134aa8a36SMatthew G. Knepley   PetscInt             Nf = prob->Nf, f;
5622764a2aaSMatthew G. Knepley 
5632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5643ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5652764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5669566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5679566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5689371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5699371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5709371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5719371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5729371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5739371c9d4SSatish Balay   }
5749371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5759371c9d4SSatish Balay     tmpd[f] = NULL;
5769371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5779371c9d4SSatish Balay     tmpk[f] = 1;
5789371c9d4SSatish Balay   }
5799566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5812764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5822764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
583249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5845fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
585f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5869566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58732d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5880c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58932d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5900c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5919566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59232d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5930c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5949566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
595c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59695cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
597f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
598f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
599c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
60095cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
601f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
602f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
6039566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
604c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60595cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
606f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
607f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6092764a2aaSMatthew G. Knepley }
6102764a2aaSMatthew G. Knepley 
6112764a2aaSMatthew G. Knepley /*@
61220f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6132764a2aaSMatthew G. Knepley 
61420f4b53cSBarry Smith   Collective
6152764a2aaSMatthew G. Knepley 
6162764a2aaSMatthew G. Knepley   Input Parameter:
61760225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6182764a2aaSMatthew G. Knepley 
6192764a2aaSMatthew G. Knepley   Level: developer
6202764a2aaSMatthew G. Knepley 
621dce8aebaSBarry Smith .seealso: `PetscDSView()`
6222764a2aaSMatthew G. Knepley @*/
623d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
624d71ae5a4SJacob Faibussowitsch {
6252764a2aaSMatthew G. Knepley   PetscInt f;
6262764a2aaSMatthew G. Knepley 
6272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6283ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
629f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6302764a2aaSMatthew G. Knepley 
631f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6329371c9d4SSatish Balay     *ds = NULL;
6333ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6349371c9d4SSatish Balay   }
635f4f49eeaSPierre Jolivet   ((PetscObject)*ds)->refct = 0;
6366528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
637df3a45bdSMatthew G. Knepley     PetscInt dim, d;
638df3a45bdSMatthew G. Knepley 
6399566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6409566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
641df3a45bdSMatthew G. Knepley   }
6429566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6439566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64448a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6459566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6479566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6489566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
649f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ds, destroy);
6509566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6519566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6524366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
65385036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((DMPolytopeType)c);
6544366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6554366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6564366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6574366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6584366bac7SMatthew G. Knepley   }
6599566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6612764a2aaSMatthew G. Knepley }
6622764a2aaSMatthew G. Knepley 
6632764a2aaSMatthew G. Knepley /*@
664dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6652764a2aaSMatthew G. Knepley 
666d083f849SBarry Smith   Collective
6672764a2aaSMatthew G. Knepley 
6682764a2aaSMatthew G. Knepley   Input Parameter:
669dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6702764a2aaSMatthew G. Knepley 
6712764a2aaSMatthew G. Knepley   Output Parameter:
672dce8aebaSBarry Smith . ds - The `PetscDS` object
6732764a2aaSMatthew G. Knepley 
6742764a2aaSMatthew G. Knepley   Level: beginner
6752764a2aaSMatthew G. Knepley 
676dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6772764a2aaSMatthew G. Knepley @*/
678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
679d71ae5a4SJacob Faibussowitsch {
6802764a2aaSMatthew G. Knepley   PetscDS p;
6812764a2aaSMatthew G. Knepley 
6822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6834f572ea9SToby Isaac   PetscAssertPointer(ds, 2);
6846528b96dSMatthew G. Knepley   *ds = NULL;
6859566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6862764a2aaSMatthew G. Knepley 
6879566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6882764a2aaSMatthew G. Knepley 
6892764a2aaSMatthew G. Knepley   p->Nf           = 0;
6902764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
69197b6e6e8SMatthew G. Knepley   p->numConstants = 0;
69297b6e6e8SMatthew G. Knepley   p->constants    = NULL;
693a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
69455c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
69512fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6969566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6974366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
6982764a2aaSMatthew G. Knepley 
6996528b96dSMatthew G. Knepley   *ds = p;
7003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7012764a2aaSMatthew G. Knepley }
7022764a2aaSMatthew G. Knepley 
703bc4ae4beSMatthew G. Knepley /*@
704dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
705bc4ae4beSMatthew G. Knepley 
70620f4b53cSBarry Smith   Not Collective
707bc4ae4beSMatthew G. Knepley 
708bc4ae4beSMatthew G. Knepley   Input Parameter:
70920f4b53cSBarry Smith . prob - The `PetscDS` object
710bc4ae4beSMatthew G. Knepley 
711bc4ae4beSMatthew G. Knepley   Output Parameter:
712bc4ae4beSMatthew G. Knepley . Nf - The number of fields
713bc4ae4beSMatthew G. Knepley 
714bc4ae4beSMatthew G. Knepley   Level: beginner
715bc4ae4beSMatthew G. Knepley 
716dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
717bc4ae4beSMatthew G. Knepley @*/
718d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
719d71ae5a4SJacob Faibussowitsch {
7202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7224f572ea9SToby Isaac   PetscAssertPointer(Nf, 2);
7232764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7252764a2aaSMatthew G. Knepley }
7262764a2aaSMatthew G. Knepley 
727bc4ae4beSMatthew G. Knepley /*@
728dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
729bc4ae4beSMatthew G. Knepley 
73020f4b53cSBarry Smith   Not Collective
731bc4ae4beSMatthew G. Knepley 
732bc4ae4beSMatthew G. Knepley   Input Parameter:
733dce8aebaSBarry Smith . prob - The `PetscDS` object
734bc4ae4beSMatthew G. Knepley 
735bc4ae4beSMatthew G. Knepley   Output Parameter:
736bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
737bc4ae4beSMatthew G. Knepley 
738bc4ae4beSMatthew G. Knepley   Level: beginner
739bc4ae4beSMatthew G. Knepley 
740dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
741bc4ae4beSMatthew G. Knepley @*/
742d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
743d71ae5a4SJacob Faibussowitsch {
7442764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7452764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7464f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
7472764a2aaSMatthew G. Knepley   *dim = 0;
7489de99aefSMatthew G. Knepley   if (prob->Nf) {
7499de99aefSMatthew G. Knepley     PetscObject  obj;
7509de99aefSMatthew G. Knepley     PetscClassId id;
7519de99aefSMatthew G. Knepley 
7529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
753665f567fSMatthew G. Knepley     if (obj) {
7549566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7559566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7569566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
75798921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7589de99aefSMatthew G. Knepley     }
759665f567fSMatthew G. Knepley   }
7603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7612764a2aaSMatthew G. Knepley }
7622764a2aaSMatthew G. Knepley 
763bc4ae4beSMatthew G. Knepley /*@
764dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
765a859676bSMatthew G. Knepley 
76620f4b53cSBarry Smith   Not Collective
767a859676bSMatthew G. Knepley 
768a859676bSMatthew G. Knepley   Input Parameter:
769dce8aebaSBarry Smith . prob - The `PetscDS` object
770a859676bSMatthew G. Knepley 
771a859676bSMatthew G. Knepley   Output Parameter:
772a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
773a859676bSMatthew G. Knepley 
774a859676bSMatthew G. Knepley   Level: beginner
775a859676bSMatthew G. Knepley 
776dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
777a859676bSMatthew G. Knepley @*/
778d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
779d71ae5a4SJacob Faibussowitsch {
780a859676bSMatthew G. Knepley   PetscFunctionBegin;
781a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7824f572ea9SToby Isaac   PetscAssertPointer(dimEmbed, 2);
78308401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
784a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
786a859676bSMatthew G. Knepley }
787a859676bSMatthew G. Knepley 
788a859676bSMatthew G. Knepley /*@
789dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
790a859676bSMatthew G. Knepley 
79120f4b53cSBarry Smith   Logically Collective
792a859676bSMatthew G. Knepley 
793a859676bSMatthew G. Knepley   Input Parameters:
794dce8aebaSBarry Smith + prob     - The `PetscDS` object
795a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
796a859676bSMatthew G. Knepley 
797a859676bSMatthew G. Knepley   Level: beginner
798a859676bSMatthew G. Knepley 
799dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
800a859676bSMatthew G. Knepley @*/
801d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
802d71ae5a4SJacob Faibussowitsch {
803a859676bSMatthew G. Knepley   PetscFunctionBegin;
804a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
80563a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
806a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
808a859676bSMatthew G. Knepley }
809a859676bSMatthew G. Knepley 
810a859676bSMatthew G. Knepley /*@
81112fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
81212fc5b22SMatthew G. Knepley 
81312fc5b22SMatthew G. Knepley   Not collective
81412fc5b22SMatthew G. Knepley 
81512fc5b22SMatthew G. Knepley   Input Parameter:
81660225df5SJacob Faibussowitsch . ds - The `PetscDS` object
81712fc5b22SMatthew G. Knepley 
81812fc5b22SMatthew G. Knepley   Output Parameter:
81912fc5b22SMatthew G. Knepley . forceQuad - The flag
82012fc5b22SMatthew G. Knepley 
82112fc5b22SMatthew G. Knepley   Level: intermediate
82212fc5b22SMatthew G. Knepley 
82312fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82412fc5b22SMatthew G. Knepley @*/
82512fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
82612fc5b22SMatthew G. Knepley {
82712fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82812fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8294f572ea9SToby Isaac   PetscAssertPointer(forceQuad, 2);
83012fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
83112fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83212fc5b22SMatthew G. Knepley }
83312fc5b22SMatthew G. Knepley 
83412fc5b22SMatthew G. Knepley /*@
83512fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
83612fc5b22SMatthew G. Knepley 
83712fc5b22SMatthew G. Knepley   Logically collective on ds
83812fc5b22SMatthew G. Knepley 
83912fc5b22SMatthew G. Knepley   Input Parameters:
84012fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
84112fc5b22SMatthew G. Knepley - forceQuad - The flag
84212fc5b22SMatthew G. Knepley 
84312fc5b22SMatthew G. Knepley   Level: intermediate
84412fc5b22SMatthew G. Knepley 
84512fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
84612fc5b22SMatthew G. Knepley @*/
84712fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
84812fc5b22SMatthew G. Knepley {
84912fc5b22SMatthew G. Knepley   PetscFunctionBegin;
85012fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
85112fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
85212fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
85312fc5b22SMatthew G. Knepley }
85412fc5b22SMatthew G. Knepley 
85512fc5b22SMatthew G. Knepley /*@
856dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8578edf6225SMatthew G. Knepley 
85820f4b53cSBarry Smith   Not Collective
8598edf6225SMatthew G. Knepley 
8608edf6225SMatthew G. Knepley   Input Parameter:
861dce8aebaSBarry Smith . ds - The `PetscDS` object
8628edf6225SMatthew G. Knepley 
8638edf6225SMatthew G. Knepley   Output Parameter:
8645fedec97SMatthew G. Knepley . isCohesive - The flag
8658edf6225SMatthew G. Knepley 
8668edf6225SMatthew G. Knepley   Level: developer
8678edf6225SMatthew G. Knepley 
868dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8698edf6225SMatthew G. Knepley @*/
870d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
871d71ae5a4SJacob Faibussowitsch {
8728edf6225SMatthew G. Knepley   PetscFunctionBegin;
8735fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8744f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 2);
8755fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8778edf6225SMatthew G. Knepley }
8788edf6225SMatthew G. Knepley 
8798edf6225SMatthew G. Knepley /*@
880be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8815fedec97SMatthew G. Knepley 
88220f4b53cSBarry Smith   Not Collective
8835fedec97SMatthew G. Knepley 
8845fedec97SMatthew G. Knepley   Input Parameter:
885dce8aebaSBarry Smith . ds - The `PetscDS` object
8865fedec97SMatthew G. Knepley 
8875fedec97SMatthew G. Knepley   Output Parameter:
8885fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8895fedec97SMatthew G. Knepley 
8905fedec97SMatthew G. Knepley   Level: developer
8915fedec97SMatthew G. Knepley 
892dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8935fedec97SMatthew G. Knepley @*/
894d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
895d71ae5a4SJacob Faibussowitsch {
8965fedec97SMatthew G. Knepley   PetscInt f;
8975fedec97SMatthew G. Knepley 
8985fedec97SMatthew G. Knepley   PetscFunctionBegin;
8995fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9004f572ea9SToby Isaac   PetscAssertPointer(numCohesive, 2);
9015fedec97SMatthew G. Knepley   *numCohesive = 0;
9025fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9045fedec97SMatthew G. Knepley }
9055fedec97SMatthew G. Knepley 
9065fedec97SMatthew G. Knepley /*@
9075fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9085fedec97SMatthew G. Knepley 
90920f4b53cSBarry Smith   Not Collective
9105fedec97SMatthew G. Knepley 
911f1a722f8SMatthew G. Knepley   Input Parameters:
912dce8aebaSBarry Smith + ds - The `PetscDS` object
9135fedec97SMatthew G. Knepley - f  - The field index
9145fedec97SMatthew G. Knepley 
9155fedec97SMatthew G. Knepley   Output Parameter:
9165fedec97SMatthew G. Knepley . isCohesive - The flag
9175fedec97SMatthew G. Knepley 
9185fedec97SMatthew G. Knepley   Level: developer
9195fedec97SMatthew G. Knepley 
920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9215fedec97SMatthew G. Knepley @*/
922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
923d71ae5a4SJacob Faibussowitsch {
9245fedec97SMatthew G. Knepley   PetscFunctionBegin;
9255fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9264f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 3);
92763a3b9bcSJacob 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);
9285fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9305fedec97SMatthew G. Knepley }
9315fedec97SMatthew G. Knepley 
9325fedec97SMatthew G. Knepley /*@
9335fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9348edf6225SMatthew G. Knepley 
93520f4b53cSBarry Smith   Not Collective
9368edf6225SMatthew G. Knepley 
9378edf6225SMatthew G. Knepley   Input Parameters:
938dce8aebaSBarry Smith + ds         - The `PetscDS` object
9395fedec97SMatthew G. Knepley . f          - The field index
9405fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9418edf6225SMatthew G. Knepley 
9428edf6225SMatthew G. Knepley   Level: developer
9438edf6225SMatthew G. Knepley 
944dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9458edf6225SMatthew G. Knepley @*/
946d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
947d71ae5a4SJacob Faibussowitsch {
9485fedec97SMatthew G. Knepley   PetscInt i;
9495fedec97SMatthew G. Knepley 
9508edf6225SMatthew G. Knepley   PetscFunctionBegin;
9515fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
95263a3b9bcSJacob 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);
9535fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9545fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9555fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9578edf6225SMatthew G. Knepley }
9588edf6225SMatthew G. Knepley 
9598edf6225SMatthew G. Knepley /*@
960bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
961bc4ae4beSMatthew G. Knepley 
96220f4b53cSBarry Smith   Not Collective
963bc4ae4beSMatthew G. Knepley 
964bc4ae4beSMatthew G. Knepley   Input Parameter:
965dce8aebaSBarry Smith . prob - The `PetscDS` object
966bc4ae4beSMatthew G. Knepley 
967bc4ae4beSMatthew G. Knepley   Output Parameter:
968bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
969bc4ae4beSMatthew G. Knepley 
970bc4ae4beSMatthew G. Knepley   Level: beginner
971bc4ae4beSMatthew G. Knepley 
972dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
973bc4ae4beSMatthew G. Knepley @*/
974d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
975d71ae5a4SJacob Faibussowitsch {
9762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9772764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9789566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
9794f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
9802764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9822764a2aaSMatthew G. Knepley }
9832764a2aaSMatthew G. Knepley 
984bc4ae4beSMatthew G. Knepley /*@
985bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
986bc4ae4beSMatthew G. Knepley 
98720f4b53cSBarry Smith   Not Collective
988bc4ae4beSMatthew G. Knepley 
989bc4ae4beSMatthew G. Knepley   Input Parameter:
990dce8aebaSBarry Smith . prob - The `PetscDS` object
991bc4ae4beSMatthew G. Knepley 
992bc4ae4beSMatthew G. Knepley   Output Parameter:
99360225df5SJacob Faibussowitsch . Nc - The total number of components
994bc4ae4beSMatthew G. Knepley 
995bc4ae4beSMatthew G. Knepley   Level: beginner
996bc4ae4beSMatthew G. Knepley 
997dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
998bc4ae4beSMatthew G. Knepley @*/
999d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
1000d71ae5a4SJacob Faibussowitsch {
10012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10022764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10039566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
10044f572ea9SToby Isaac   PetscAssertPointer(Nc, 2);
10052764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10072764a2aaSMatthew G. Knepley }
10082764a2aaSMatthew G. Knepley 
1009bc4ae4beSMatthew G. Knepley /*@
1010bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1011bc4ae4beSMatthew G. Knepley 
101220f4b53cSBarry Smith   Not Collective
1013bc4ae4beSMatthew G. Knepley 
1014bc4ae4beSMatthew G. Knepley   Input Parameters:
1015dce8aebaSBarry Smith + prob - The `PetscDS` object
1016bc4ae4beSMatthew G. Knepley - f    - The field number
1017bc4ae4beSMatthew G. Knepley 
1018bc4ae4beSMatthew G. Knepley   Output Parameter:
1019bc4ae4beSMatthew G. Knepley . disc - The discretization object
1020bc4ae4beSMatthew G. Knepley 
1021bc4ae4beSMatthew G. Knepley   Level: beginner
1022bc4ae4beSMatthew G. Knepley 
1023dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1024bc4ae4beSMatthew G. Knepley @*/
1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1026d71ae5a4SJacob Faibussowitsch {
10276528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10282764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10294f572ea9SToby Isaac   PetscAssertPointer(disc, 3);
103063a3b9bcSJacob 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);
10312764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10332764a2aaSMatthew G. Knepley }
10342764a2aaSMatthew G. Knepley 
1035bc4ae4beSMatthew G. Knepley /*@
1036bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1037bc4ae4beSMatthew G. Knepley 
103820f4b53cSBarry Smith   Not Collective
1039bc4ae4beSMatthew G. Knepley 
1040bc4ae4beSMatthew G. Knepley   Input Parameters:
1041dce8aebaSBarry Smith + prob - The `PetscDS` object
1042bc4ae4beSMatthew G. Knepley . f    - The field number
1043bc4ae4beSMatthew G. Knepley - disc - The discretization object
1044bc4ae4beSMatthew G. Knepley 
1045bc4ae4beSMatthew G. Knepley   Level: beginner
1046bc4ae4beSMatthew G. Knepley 
1047dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1048bc4ae4beSMatthew G. Knepley @*/
1049d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1050d71ae5a4SJacob Faibussowitsch {
10512764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10522764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10534f572ea9SToby Isaac   if (disc) PetscAssertPointer(disc, 3);
105463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10559566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10569566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10572764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1059665f567fSMatthew G. Knepley   if (disc) {
1060249df284SMatthew G. Knepley     PetscClassId id;
1061249df284SMatthew G. Knepley 
10629566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10631cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10649566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10651cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10669566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1067a6cbbb48SMatthew G. Knepley     }
10689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1069249df284SMatthew G. Knepley   }
10703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10712764a2aaSMatthew G. Knepley }
10722764a2aaSMatthew G. Knepley 
1073bc4ae4beSMatthew G. Knepley /*@
10746528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10756528b96dSMatthew G. Knepley 
107620f4b53cSBarry Smith   Not Collective
10776528b96dSMatthew G. Knepley 
10786528b96dSMatthew G. Knepley   Input Parameter:
1079dce8aebaSBarry Smith . ds - The `PetscDS` object
10806528b96dSMatthew G. Knepley 
10816528b96dSMatthew G. Knepley   Output Parameter:
10826528b96dSMatthew G. Knepley . wf - The weak form object
10836528b96dSMatthew G. Knepley 
10846528b96dSMatthew G. Knepley   Level: beginner
10856528b96dSMatthew G. Knepley 
1086dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10876528b96dSMatthew G. Knepley @*/
1088d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1089d71ae5a4SJacob Faibussowitsch {
10906528b96dSMatthew G. Knepley   PetscFunctionBegin;
10916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10924f572ea9SToby Isaac   PetscAssertPointer(wf, 2);
10936528b96dSMatthew G. Knepley   *wf = ds->wf;
10943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10956528b96dSMatthew G. Knepley }
10966528b96dSMatthew G. Knepley 
10976528b96dSMatthew G. Knepley /*@
10986528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10996528b96dSMatthew G. Knepley 
110020f4b53cSBarry Smith   Not Collective
11016528b96dSMatthew G. Knepley 
11026528b96dSMatthew G. Knepley   Input Parameters:
1103dce8aebaSBarry Smith + ds - The `PetscDS` object
11046528b96dSMatthew G. Knepley - wf - The weak form object
11056528b96dSMatthew G. Knepley 
11066528b96dSMatthew G. Knepley   Level: beginner
11076528b96dSMatthew G. Knepley 
1108dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11096528b96dSMatthew G. Knepley @*/
1110d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1111d71ae5a4SJacob Faibussowitsch {
11126528b96dSMatthew G. Knepley   PetscFunctionBegin;
11136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11159566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11166528b96dSMatthew G. Knepley   ds->wf = wf;
11179566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11206528b96dSMatthew G. Knepley }
11216528b96dSMatthew G. Knepley 
11226528b96dSMatthew G. Knepley /*@
1123bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1124bc4ae4beSMatthew G. Knepley 
112520f4b53cSBarry Smith   Not Collective
1126bc4ae4beSMatthew G. Knepley 
1127bc4ae4beSMatthew G. Knepley   Input Parameters:
1128dce8aebaSBarry Smith + prob - The `PetscDS` object
1129bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1130bc4ae4beSMatthew G. Knepley 
1131bc4ae4beSMatthew G. Knepley   Level: beginner
1132bc4ae4beSMatthew G. Knepley 
1133dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1134bc4ae4beSMatthew G. Knepley @*/
1135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1136d71ae5a4SJacob Faibussowitsch {
11372764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11402764a2aaSMatthew G. Knepley }
11412764a2aaSMatthew G. Knepley 
1142249df284SMatthew G. Knepley /*@
1143dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1144083401c6SMatthew G. Knepley 
114520f4b53cSBarry Smith   Not Collective
1146083401c6SMatthew G. Knepley 
1147083401c6SMatthew G. Knepley   Input Parameter:
1148dce8aebaSBarry Smith . prob - The `PetscDS` object
1149083401c6SMatthew G. Knepley 
1150083401c6SMatthew G. Knepley   Output Parameter:
1151083401c6SMatthew G. Knepley . q - The quadrature object
1152083401c6SMatthew G. Knepley 
1153083401c6SMatthew G. Knepley   Level: intermediate
1154083401c6SMatthew G. Knepley 
1155dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1156083401c6SMatthew G. Knepley @*/
1157d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1158d71ae5a4SJacob Faibussowitsch {
1159083401c6SMatthew G. Knepley   PetscObject  obj;
1160083401c6SMatthew G. Knepley   PetscClassId id;
1161083401c6SMatthew G. Knepley 
1162083401c6SMatthew G. Knepley   PetscFunctionBegin;
1163083401c6SMatthew G. Knepley   *q = NULL;
11643ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11669566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11679566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11689566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116998921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1171083401c6SMatthew G. Knepley }
1172083401c6SMatthew G. Knepley 
1173083401c6SMatthew G. Knepley /*@
1174dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1175249df284SMatthew G. Knepley 
117620f4b53cSBarry Smith   Not Collective
1177249df284SMatthew G. Knepley 
1178249df284SMatthew G. Knepley   Input Parameters:
1179dce8aebaSBarry Smith + prob - The `PetscDS` object
1180249df284SMatthew G. Knepley - f    - The field number
1181249df284SMatthew G. Knepley 
1182249df284SMatthew G. Knepley   Output Parameter:
1183249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1184249df284SMatthew G. Knepley 
1185249df284SMatthew G. Knepley   Level: developer
1186249df284SMatthew G. Knepley 
1187dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1188249df284SMatthew G. Knepley @*/
1189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1190d71ae5a4SJacob Faibussowitsch {
1191249df284SMatthew G. Knepley   PetscFunctionBegin;
1192249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
11934f572ea9SToby Isaac   PetscAssertPointer(implicit, 3);
119463a3b9bcSJacob 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);
1195249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1197249df284SMatthew G. Knepley }
1198249df284SMatthew G. Knepley 
1199249df284SMatthew G. Knepley /*@
1200dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1201249df284SMatthew G. Knepley 
120220f4b53cSBarry Smith   Not Collective
1203249df284SMatthew G. Knepley 
1204249df284SMatthew G. Knepley   Input Parameters:
1205dce8aebaSBarry Smith + prob     - The `PetscDS` object
1206249df284SMatthew G. Knepley . f        - The field number
1207249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1208249df284SMatthew G. Knepley 
1209249df284SMatthew G. Knepley   Level: developer
1210249df284SMatthew G. Knepley 
1211dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1212249df284SMatthew G. Knepley @*/
1213d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1214d71ae5a4SJacob Faibussowitsch {
1215249df284SMatthew G. Knepley   PetscFunctionBegin;
1216249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
121763a3b9bcSJacob 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);
1218249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1220249df284SMatthew G. Knepley }
1221249df284SMatthew G. Knepley 
1222f9244615SMatthew G. Knepley /*@
1223f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1224f9244615SMatthew G. Knepley 
122520f4b53cSBarry Smith   Not Collective
1226f9244615SMatthew G. Knepley 
1227f9244615SMatthew G. Knepley   Input Parameters:
1228dce8aebaSBarry Smith + ds - The `PetscDS` object
1229f9244615SMatthew G. Knepley - f  - The field number
1230f9244615SMatthew G. Knepley 
1231f9244615SMatthew G. Knepley   Output Parameter:
1232f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1233f9244615SMatthew G. Knepley 
1234f9244615SMatthew G. Knepley   Level: developer
1235f9244615SMatthew G. Knepley 
1236dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1237f9244615SMatthew G. Knepley @*/
1238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1239d71ae5a4SJacob Faibussowitsch {
1240f9244615SMatthew G. Knepley   PetscFunctionBegin;
1241f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12424f572ea9SToby Isaac   PetscAssertPointer(k, 3);
124363a3b9bcSJacob 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);
1244f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1246f9244615SMatthew G. Knepley }
1247f9244615SMatthew G. Knepley 
1248f9244615SMatthew G. Knepley /*@
1249f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1250f9244615SMatthew G. Knepley 
125120f4b53cSBarry Smith   Not Collective
1252f9244615SMatthew G. Knepley 
1253f9244615SMatthew G. Knepley   Input Parameters:
1254dce8aebaSBarry Smith + ds - The `PetscDS` object
1255f9244615SMatthew G. Knepley . f  - The field number
1256f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1257f9244615SMatthew G. Knepley 
1258f9244615SMatthew G. Knepley   Level: developer
1259f9244615SMatthew G. Knepley 
126060225df5SJacob Faibussowitsch .seealso: ``PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1261f9244615SMatthew G. Knepley @*/
1262d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1263d71ae5a4SJacob Faibussowitsch {
1264f9244615SMatthew G. Knepley   PetscFunctionBegin;
1265f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
126663a3b9bcSJacob 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);
1267f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1269f9244615SMatthew G. Knepley }
1270f9244615SMatthew G. Knepley 
1271c8943706SMatthew G. Knepley /*@C
1272c8943706SMatthew G. Knepley   PetscDSGetObjective - Get the pointwise objective function for a given test field
1273c8943706SMatthew G. Knepley 
1274c8943706SMatthew G. Knepley   Not Collective
1275c8943706SMatthew G. Knepley 
1276c8943706SMatthew G. Knepley   Input Parameters:
1277c8943706SMatthew G. Knepley + ds - The `PetscDS`
1278c8943706SMatthew G. Knepley - f  - The test field number
1279c8943706SMatthew G. Knepley 
1280a4e35b19SJacob Faibussowitsch   Output Parameter:
1281c8943706SMatthew G. Knepley . obj - integrand for the test function term
1282c8943706SMatthew G. Knepley 
1283c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1284c8943706SMatthew G. Knepley + dim          - the spatial dimension
1285c8943706SMatthew G. Knepley . Nf           - the number of fields
1286a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1287c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1288c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1289c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1290c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1291c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1292c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1293c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1294c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1295c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1296c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1297c8943706SMatthew G. Knepley . t            - current time
1298c8943706SMatthew G. Knepley . x            - coordinates of the current point
1299c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1300c8943706SMatthew G. Knepley . constants    - constant parameters
1301c8943706SMatthew G. Knepley - obj          - output values at the current point
1302c8943706SMatthew G. Knepley 
1303c8943706SMatthew G. Knepley   Level: intermediate
1304c8943706SMatthew G. Knepley 
1305c8943706SMatthew G. Knepley   Note:
13061d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)$
1307c8943706SMatthew G. Knepley 
1308c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1309c8943706SMatthew G. Knepley @*/
1310d71ae5a4SJacob 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[]))
1311d71ae5a4SJacob Faibussowitsch {
13126528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13136528b96dSMatthew G. Knepley   PetscInt        n;
13146528b96dSMatthew G. Knepley 
13152764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13174f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
131863a3b9bcSJacob 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);
13199566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13206528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13222764a2aaSMatthew G. Knepley }
13232764a2aaSMatthew G. Knepley 
1324c8943706SMatthew G. Knepley /*@C
1325c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1326c8943706SMatthew G. Knepley 
1327c8943706SMatthew G. Knepley   Not Collective
1328c8943706SMatthew G. Knepley 
1329c8943706SMatthew G. Knepley   Input Parameters:
1330c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1331c8943706SMatthew G. Knepley . f   - The test field number
1332c8943706SMatthew G. Knepley - obj - integrand for the test function term
1333c8943706SMatthew G. Knepley 
1334c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1335c8943706SMatthew G. Knepley + dim          - the spatial dimension
1336c8943706SMatthew G. Knepley . Nf           - the number of fields
1337a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1338c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1339c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1340c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1341c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1342c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1343c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1344c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1345c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1346c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1347c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1348c8943706SMatthew G. Knepley . t            - current time
1349c8943706SMatthew G. Knepley . x            - coordinates of the current point
1350c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1351c8943706SMatthew G. Knepley . constants    - constant parameters
1352c8943706SMatthew G. Knepley - obj          - output values at the current point
1353c8943706SMatthew G. Knepley 
1354c8943706SMatthew G. Knepley   Level: intermediate
1355c8943706SMatthew G. Knepley 
1356c8943706SMatthew G. Knepley   Note:
13571d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)$
1358c8943706SMatthew G. Knepley 
1359c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1360c8943706SMatthew G. Knepley @*/
1361d71ae5a4SJacob 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[]))
1362d71ae5a4SJacob Faibussowitsch {
13632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13656528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
136663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13692764a2aaSMatthew G. Knepley }
13702764a2aaSMatthew G. Knepley 
1371194d53e6SMatthew G. Knepley /*@C
1372194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1373194d53e6SMatthew G. Knepley 
137420f4b53cSBarry Smith   Not Collective
1375194d53e6SMatthew G. Knepley 
1376194d53e6SMatthew G. Knepley   Input Parameters:
1377dce8aebaSBarry Smith + ds - The `PetscDS`
1378194d53e6SMatthew G. Knepley - f  - The test field number
1379194d53e6SMatthew G. Knepley 
1380194d53e6SMatthew G. Knepley   Output Parameters:
1381194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1382194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1383194d53e6SMatthew G. Knepley 
1384a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1385194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1386194d53e6SMatthew G. Knepley . Nf           - the number of fields
1387a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1388194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1389194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1390194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1391194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1392194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1393194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1394194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1395194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1396194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1397194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1398194d53e6SMatthew G. Knepley . t            - current time
1399194d53e6SMatthew G. Knepley . x            - coordinates of the current point
140097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
140197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1402194d53e6SMatthew G. Knepley - f0           - output values at the current point
1403194d53e6SMatthew G. Knepley 
1404194d53e6SMatthew G. Knepley   Level: intermediate
1405194d53e6SMatthew G. Knepley 
1406dce8aebaSBarry Smith   Note:
1407a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1408a4e35b19SJacob Faibussowitsch 
14091d27aa22SBarry 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)$
1410dce8aebaSBarry Smith 
1411dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1412194d53e6SMatthew G. Knepley @*/
1413a4e35b19SJacob 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[]))
1414d71ae5a4SJacob Faibussowitsch {
14156528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14166528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14176528b96dSMatthew G. Knepley 
14182764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14196528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
142063a3b9bcSJacob 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);
14219566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14226528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14236528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14252764a2aaSMatthew G. Knepley }
14262764a2aaSMatthew G. Knepley 
1427194d53e6SMatthew G. Knepley /*@C
1428194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1429194d53e6SMatthew G. Knepley 
143020f4b53cSBarry Smith   Not Collective
1431194d53e6SMatthew G. Knepley 
1432194d53e6SMatthew G. Knepley   Input Parameters:
1433dce8aebaSBarry Smith + ds - The `PetscDS`
1434194d53e6SMatthew G. Knepley . f  - The test field number
1435194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1436194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1437194d53e6SMatthew G. Knepley 
1438a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1439194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1440194d53e6SMatthew G. Knepley . Nf           - the number of fields
1441a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1442194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1443194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1444194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1445194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1446194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1447194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1448194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1449194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1450194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1451194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1452194d53e6SMatthew G. Knepley . t            - current time
1453194d53e6SMatthew G. Knepley . x            - coordinates of the current point
145497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
145597b6e6e8SMatthew G. Knepley . constants    - constant parameters
1456194d53e6SMatthew G. Knepley - f0           - output values at the current point
1457194d53e6SMatthew G. Knepley 
1458194d53e6SMatthew G. Knepley   Level: intermediate
1459194d53e6SMatthew G. Knepley 
1460dce8aebaSBarry Smith   Note:
1461a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1462a4e35b19SJacob Faibussowitsch 
14631d27aa22SBarry 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)$
1464dce8aebaSBarry Smith 
1465dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1466194d53e6SMatthew G. Knepley @*/
1467a4e35b19SJacob 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[]))
1468d71ae5a4SJacob Faibussowitsch {
14692764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14706528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1471f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1472f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
147363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14749566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14762764a2aaSMatthew G. Knepley }
14772764a2aaSMatthew G. Knepley 
14783e75805dSMatthew G. Knepley /*@C
1479cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1480cb36c0f9SMatthew G. Knepley 
148120f4b53cSBarry Smith   Not Collective
1482cb36c0f9SMatthew G. Knepley 
1483cb36c0f9SMatthew G. Knepley   Input Parameters:
1484dce8aebaSBarry Smith + ds - The `PetscDS`
1485cb36c0f9SMatthew G. Knepley - f  - The test field number
1486cb36c0f9SMatthew G. Knepley 
1487cb36c0f9SMatthew G. Knepley   Output Parameters:
1488cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1489cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1490cb36c0f9SMatthew G. Knepley 
1491a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1492cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1493cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1494a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1495cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1496cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1497cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1498cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1499cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1500cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1501cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1502cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1503cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1504cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1505cb36c0f9SMatthew G. Knepley . t            - current time
1506cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1507cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1508cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1509cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1510cb36c0f9SMatthew G. Knepley 
1511cb36c0f9SMatthew G. Knepley   Level: intermediate
1512cb36c0f9SMatthew G. Knepley 
1513dce8aebaSBarry Smith   Note:
1514a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1515a4e35b19SJacob Faibussowitsch 
15161d27aa22SBarry 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)$
1517dce8aebaSBarry Smith 
1518dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1519cb36c0f9SMatthew G. Knepley @*/
1520a4e35b19SJacob 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[]))
1521d71ae5a4SJacob Faibussowitsch {
1522cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1523cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1524cb36c0f9SMatthew G. Knepley 
1525cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1526cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
152763a3b9bcSJacob 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);
15289566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1529cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1530cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1532cb36c0f9SMatthew G. Knepley }
1533cb36c0f9SMatthew G. Knepley 
1534cb36c0f9SMatthew G. Knepley /*@C
1535cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1536cb36c0f9SMatthew G. Knepley 
153720f4b53cSBarry Smith   Not Collective
1538cb36c0f9SMatthew G. Knepley 
1539cb36c0f9SMatthew G. Knepley   Input Parameters:
1540dce8aebaSBarry Smith + ds - The `PetscDS`
1541cb36c0f9SMatthew G. Knepley . f  - The test field number
1542cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1543cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1544cb36c0f9SMatthew G. Knepley 
1545a4e35b19SJacob Faibussowitsch   Calling sequence for the callbacks `f0`:
1546cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1547cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1548a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1549cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1550cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1551cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1552cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1553cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1554cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1555cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1556cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1557cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1558cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1559cb36c0f9SMatthew G. Knepley . t            - current time
1560cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1561cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1562cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1563cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1564cb36c0f9SMatthew G. Knepley 
1565cb36c0f9SMatthew G. Knepley   Level: intermediate
1566cb36c0f9SMatthew G. Knepley 
1567dce8aebaSBarry Smith   Note:
1568a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1569a4e35b19SJacob Faibussowitsch 
15701d27aa22SBarry 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)$
1571dce8aebaSBarry Smith 
1572dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1573cb36c0f9SMatthew G. Knepley @*/
1574a4e35b19SJacob 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[]))
1575d71ae5a4SJacob Faibussowitsch {
1576cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1577cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1578cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1579cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
158063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1583cb36c0f9SMatthew G. Knepley }
1584cb36c0f9SMatthew G. Knepley 
1585cc4c1da9SBarry Smith /*@
1586dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15873e75805dSMatthew G. Knepley 
158820f4b53cSBarry Smith   Not Collective
15893e75805dSMatthew G. Knepley 
15903e75805dSMatthew G. Knepley   Input Parameter:
159160225df5SJacob Faibussowitsch . ds - The `PetscDS`
15923e75805dSMatthew G. Knepley 
15933e75805dSMatthew G. Knepley   Output Parameter:
15943e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15953e75805dSMatthew G. Knepley 
15963e75805dSMatthew G. Knepley   Level: intermediate
15973e75805dSMatthew G. Knepley 
1598dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15993e75805dSMatthew G. Knepley @*/
1600d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1601d71ae5a4SJacob Faibussowitsch {
16023e75805dSMatthew G. Knepley   PetscFunctionBegin;
16036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16049566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16063e75805dSMatthew G. Knepley }
16073e75805dSMatthew G. Knepley 
1608194d53e6SMatthew G. Knepley /*@C
1609194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1610194d53e6SMatthew G. Knepley 
161120f4b53cSBarry Smith   Not Collective
1612194d53e6SMatthew G. Knepley 
1613194d53e6SMatthew G. Knepley   Input Parameters:
1614dce8aebaSBarry Smith + ds - The `PetscDS`
1615194d53e6SMatthew G. Knepley . f  - The test field number
1616194d53e6SMatthew G. Knepley - g  - The field number
1617194d53e6SMatthew G. Knepley 
1618194d53e6SMatthew G. Knepley   Output Parameters:
1619194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1620194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1621194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1622194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1623194d53e6SMatthew G. Knepley 
1624a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1625194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1626194d53e6SMatthew G. Knepley . Nf           - the number of fields
1627a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1628194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1629194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1630194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1631194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1632194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1633194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1634194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1635194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1636194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1637194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1638194d53e6SMatthew G. Knepley . t            - current time
16392aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1640194d53e6SMatthew G. Knepley . x            - coordinates of the current point
164197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
164297b6e6e8SMatthew G. Knepley . constants    - constant parameters
1643194d53e6SMatthew G. Knepley - g0           - output values at the current point
1644194d53e6SMatthew G. Knepley 
1645194d53e6SMatthew G. Knepley   Level: intermediate
1646194d53e6SMatthew G. Knepley 
1647dce8aebaSBarry Smith   Note:
1648a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
164960225df5SJacob Faibussowitsch 
1650a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16511d27aa22SBarry Smith 
16521d27aa22SBarry Smith   $$
1653dce8aebaSBarry Smith   \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 + \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
16541d27aa22SBarry Smith   $$
1655dce8aebaSBarry Smith 
1656dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1657194d53e6SMatthew G. Knepley @*/
1658a4e35b19SJacob 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[]))
1659d71ae5a4SJacob Faibussowitsch {
16606528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16616528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16626528b96dSMatthew G. Knepley 
16632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
166563a3b9bcSJacob 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);
166663a3b9bcSJacob 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);
16679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16686528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16696528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16706528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16716528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16732764a2aaSMatthew G. Knepley }
16742764a2aaSMatthew G. Knepley 
1675194d53e6SMatthew G. Knepley /*@C
1676194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1677194d53e6SMatthew G. Knepley 
167820f4b53cSBarry Smith   Not Collective
1679194d53e6SMatthew G. Knepley 
1680194d53e6SMatthew G. Knepley   Input Parameters:
1681dce8aebaSBarry Smith + ds - The `PetscDS`
1682194d53e6SMatthew G. Knepley . f  - The test field number
1683194d53e6SMatthew G. Knepley . g  - The field number
1684194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1685194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1686194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1687194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1688194d53e6SMatthew G. Knepley 
1689a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1690194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1691194d53e6SMatthew G. Knepley . Nf           - the number of fields
1692a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1693194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1694194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1695194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1696194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1697194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1698194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1699194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1700194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1701194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1702194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1703194d53e6SMatthew G. Knepley . t            - current time
17042aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1705194d53e6SMatthew G. Knepley . x            - coordinates of the current point
170697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
170797b6e6e8SMatthew G. Knepley . constants    - constant parameters
1708194d53e6SMatthew G. Knepley - g0           - output values at the current point
1709194d53e6SMatthew G. Knepley 
1710194d53e6SMatthew G. Knepley   Level: intermediate
1711194d53e6SMatthew G. Knepley 
1712dce8aebaSBarry Smith   Note:
1713a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
171460225df5SJacob Faibussowitsch 
1715a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1716dce8aebaSBarry Smith   \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 + \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
1717dce8aebaSBarry Smith 
1718dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1719194d53e6SMatthew G. Knepley @*/
1720a4e35b19SJacob 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[]))
1721d71ae5a4SJacob Faibussowitsch {
17222764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17236528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17242764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17252764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17262764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17272764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
172863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
172963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17309566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17322764a2aaSMatthew G. Knepley }
17332764a2aaSMatthew G. Knepley 
1734cc4c1da9SBarry Smith /*@
1735dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
173655c1f793SMatthew G. Knepley 
173720f4b53cSBarry Smith   Not Collective
173855c1f793SMatthew G. Knepley 
173955c1f793SMatthew G. Knepley   Input Parameters:
1740dce8aebaSBarry Smith + prob      - The `PetscDS`
174155c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
174255c1f793SMatthew G. Knepley 
174355c1f793SMatthew G. Knepley   Level: intermediate
174455c1f793SMatthew G. Knepley 
1745cc4c1da9SBarry Smith   Developer Note:
1746cc4c1da9SBarry Smith   Should be called `PetscDSSetUseJacobianPreconditioner()`
1747cc4c1da9SBarry Smith 
1748dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
174955c1f793SMatthew G. Knepley @*/
1750d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1751d71ae5a4SJacob Faibussowitsch {
175255c1f793SMatthew G. Knepley   PetscFunctionBegin;
175355c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
175455c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
175655c1f793SMatthew G. Knepley }
175755c1f793SMatthew G. Knepley 
1758cc4c1da9SBarry Smith /*@
1759dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1760475e0ac9SMatthew G. Knepley 
176120f4b53cSBarry Smith   Not Collective
1762475e0ac9SMatthew G. Knepley 
1763475e0ac9SMatthew G. Knepley   Input Parameter:
176460225df5SJacob Faibussowitsch . ds - The `PetscDS`
1765475e0ac9SMatthew G. Knepley 
1766475e0ac9SMatthew G. Knepley   Output Parameter:
1767475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1768475e0ac9SMatthew G. Knepley 
1769475e0ac9SMatthew G. Knepley   Level: intermediate
1770475e0ac9SMatthew G. Knepley 
1771dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1772475e0ac9SMatthew G. Knepley @*/
1773d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1774d71ae5a4SJacob Faibussowitsch {
1775475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1777475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17783ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1781475e0ac9SMatthew G. Knepley }
1782475e0ac9SMatthew G. Knepley 
1783475e0ac9SMatthew G. Knepley /*@C
1784dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1785dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1786475e0ac9SMatthew G. Knepley 
178720f4b53cSBarry Smith   Not Collective
1788475e0ac9SMatthew G. Knepley 
1789475e0ac9SMatthew G. Knepley   Input Parameters:
1790dce8aebaSBarry Smith + ds - The `PetscDS`
1791475e0ac9SMatthew G. Knepley . f  - The test field number
1792475e0ac9SMatthew G. Knepley - g  - The field number
1793475e0ac9SMatthew G. Knepley 
1794475e0ac9SMatthew G. Knepley   Output Parameters:
1795475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1796475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1797475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1798475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1799475e0ac9SMatthew G. Knepley 
1800a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1801475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1802475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1803a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1804475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1805475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1806475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1807475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1808475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1809475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1810475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1811475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1812475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1813475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1814475e0ac9SMatthew G. Knepley . t            - current time
1815475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1816475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
181797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
181897b6e6e8SMatthew G. Knepley . constants    - constant parameters
1819475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1820475e0ac9SMatthew G. Knepley 
1821475e0ac9SMatthew G. Knepley   Level: intermediate
1822475e0ac9SMatthew G. Knepley 
1823dce8aebaSBarry Smith   Note:
1824a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1825a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1826dce8aebaSBarry Smith   \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 + \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
1827dce8aebaSBarry Smith 
1828dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1829475e0ac9SMatthew G. Knepley @*/
1830a4e35b19SJacob 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[]))
1831d71ae5a4SJacob Faibussowitsch {
18326528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18336528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18346528b96dSMatthew G. Knepley 
1835475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18366528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
183763a3b9bcSJacob 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);
183863a3b9bcSJacob 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);
18399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18406528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18416528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18426528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18436528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1845475e0ac9SMatthew G. Knepley }
1846475e0ac9SMatthew G. Knepley 
1847475e0ac9SMatthew G. Knepley /*@C
1848dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1849dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1850475e0ac9SMatthew G. Knepley 
185120f4b53cSBarry Smith   Not Collective
1852475e0ac9SMatthew G. Knepley 
1853475e0ac9SMatthew G. Knepley   Input Parameters:
1854dce8aebaSBarry Smith + ds - The `PetscDS`
1855475e0ac9SMatthew G. Knepley . f  - The test field number
1856475e0ac9SMatthew G. Knepley . g  - The field number
1857475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1858475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1859475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1860475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1861475e0ac9SMatthew G. Knepley 
1862a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1863475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1864475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1865a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1866475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1867475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1868475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1869475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1870475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1871475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1872475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1873475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1874475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1875475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1876475e0ac9SMatthew G. Knepley . t            - current time
1877475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1878475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
187997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
188097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1881475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1882475e0ac9SMatthew G. Knepley 
1883475e0ac9SMatthew G. Knepley   Level: intermediate
1884475e0ac9SMatthew G. Knepley 
1885dce8aebaSBarry Smith   Note:
1886a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
188760225df5SJacob Faibussowitsch 
1888a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1889dce8aebaSBarry Smith   \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 + \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
1890dce8aebaSBarry Smith 
1891dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1892475e0ac9SMatthew G. Knepley @*/
1893a4e35b19SJacob 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[]))
1894d71ae5a4SJacob Faibussowitsch {
1895475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1897475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1898475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1899475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1900475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
190163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
190263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1905475e0ac9SMatthew G. Knepley }
1906475e0ac9SMatthew G. Knepley 
1907cc4c1da9SBarry Smith /*@
1908b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1909b7e05686SMatthew G. Knepley 
191020f4b53cSBarry Smith   Not Collective
1911b7e05686SMatthew G. Knepley 
1912b7e05686SMatthew G. Knepley   Input Parameter:
1913dce8aebaSBarry Smith . ds - The `PetscDS`
1914b7e05686SMatthew G. Knepley 
1915b7e05686SMatthew G. Knepley   Output Parameter:
1916b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1917b7e05686SMatthew G. Knepley 
1918b7e05686SMatthew G. Knepley   Level: intermediate
1919b7e05686SMatthew G. Knepley 
1920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1921b7e05686SMatthew G. Knepley @*/
1922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1923d71ae5a4SJacob Faibussowitsch {
1924b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19256528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1928b7e05686SMatthew G. Knepley }
1929b7e05686SMatthew G. Knepley 
1930b7e05686SMatthew G. Knepley /*@C
1931b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1932b7e05686SMatthew G. Knepley 
193320f4b53cSBarry Smith   Not Collective
1934b7e05686SMatthew G. Knepley 
1935b7e05686SMatthew G. Knepley   Input Parameters:
1936dce8aebaSBarry Smith + ds - The `PetscDS`
1937b7e05686SMatthew G. Knepley . f  - The test field number
1938b7e05686SMatthew G. Knepley - g  - The field number
1939b7e05686SMatthew G. Knepley 
1940b7e05686SMatthew G. Knepley   Output Parameters:
1941b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1942b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1943b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1944b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1945b7e05686SMatthew G. Knepley 
1946a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1947b7e05686SMatthew G. Knepley + dim          - the spatial dimension
1948b7e05686SMatthew G. Knepley . Nf           - the number of fields
1949a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1950b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1951b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1952b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1953b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1954b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1955b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1956b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1957b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1958b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1959b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1960b7e05686SMatthew G. Knepley . t            - current time
1961b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1962b7e05686SMatthew G. Knepley . x            - coordinates of the current point
196397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
196497b6e6e8SMatthew G. Knepley . constants    - constant parameters
1965b7e05686SMatthew G. Knepley - g0           - output values at the current point
1966b7e05686SMatthew G. Knepley 
1967b7e05686SMatthew G. Knepley   Level: intermediate
1968b7e05686SMatthew G. Knepley 
1969dce8aebaSBarry Smith   Note:
1970a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
197160225df5SJacob Faibussowitsch 
1972a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1973dce8aebaSBarry Smith   \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 + \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
1974dce8aebaSBarry Smith 
1975dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1976b7e05686SMatthew G. Knepley @*/
1977a4e35b19SJacob 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[]))
1978d71ae5a4SJacob Faibussowitsch {
19796528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19806528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19816528b96dSMatthew G. Knepley 
1982b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19836528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
198463a3b9bcSJacob 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);
198563a3b9bcSJacob 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);
19869566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19876528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19886528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19896528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19906528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1992b7e05686SMatthew G. Knepley }
1993b7e05686SMatthew G. Knepley 
1994b7e05686SMatthew G. Knepley /*@C
1995b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1996b7e05686SMatthew G. Knepley 
199720f4b53cSBarry Smith   Not Collective
1998b7e05686SMatthew G. Knepley 
1999b7e05686SMatthew G. Knepley   Input Parameters:
2000dce8aebaSBarry Smith + ds - The `PetscDS`
2001b7e05686SMatthew G. Knepley . f  - The test field number
2002b7e05686SMatthew G. Knepley . g  - The field number
2003b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2004b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2005b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2006b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2007b7e05686SMatthew G. Knepley 
2008a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2009b7e05686SMatthew G. Knepley + dim          - the spatial dimension
2010b7e05686SMatthew G. Knepley . Nf           - the number of fields
2011a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2012b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2013b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2014b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2015b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2016b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2017b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2018b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2019b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2020b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2021b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2022b7e05686SMatthew G. Knepley . t            - current time
2023b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2024b7e05686SMatthew G. Knepley . x            - coordinates of the current point
202597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
202697b6e6e8SMatthew G. Knepley . constants    - constant parameters
2027b7e05686SMatthew G. Knepley - g0           - output values at the current point
2028b7e05686SMatthew G. Knepley 
2029b7e05686SMatthew G. Knepley   Level: intermediate
2030b7e05686SMatthew G. Knepley 
2031dce8aebaSBarry Smith   Note:
2032a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
203360225df5SJacob Faibussowitsch 
2034a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2035dce8aebaSBarry Smith   \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 + \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
2036dce8aebaSBarry Smith 
2037dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2038b7e05686SMatthew G. Knepley @*/
2039a4e35b19SJacob 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[]))
2040d71ae5a4SJacob Faibussowitsch {
2041b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20426528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2043b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2044b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2045b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2046b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
204763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
204863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20499566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2051b7e05686SMatthew G. Knepley }
2052b7e05686SMatthew G. Knepley 
20530c2f2876SMatthew G. Knepley /*@C
20540c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20550c2f2876SMatthew G. Knepley 
205620f4b53cSBarry Smith   Not Collective
20570c2f2876SMatthew G. Knepley 
20584165533cSJose E. Roman   Input Parameters:
2059dce8aebaSBarry Smith + ds - The `PetscDS` object
20600c2f2876SMatthew G. Knepley - f  - The field number
20610c2f2876SMatthew G. Knepley 
20624165533cSJose E. Roman   Output Parameter:
20630c2f2876SMatthew G. Knepley . r - Riemann solver
20640c2f2876SMatthew G. Knepley 
206520f4b53cSBarry Smith   Calling sequence of `r`:
20665db36cf9SMatthew G. Knepley + dim          - The spatial dimension
20675db36cf9SMatthew G. Knepley . Nf           - The number of fields
20685db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
20690c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
20700c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
20710c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
20720c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
207397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
207497b6e6e8SMatthew G. Knepley . constants    - constant parameters
20750c2f2876SMatthew G. Knepley - ctx          - optional user context
20760c2f2876SMatthew G. Knepley 
20770c2f2876SMatthew G. Knepley   Level: intermediate
20780c2f2876SMatthew G. Knepley 
2079dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20800c2f2876SMatthew G. Knepley @*/
2081d71ae5a4SJacob 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))
2082d71ae5a4SJacob Faibussowitsch {
20836528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20846528b96dSMatthew G. Knepley   PetscInt          n;
20856528b96dSMatthew G. Knepley 
20860c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20884f572ea9SToby Isaac   PetscAssertPointer(r, 3);
208963a3b9bcSJacob 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);
20909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20916528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20930c2f2876SMatthew G. Knepley }
20940c2f2876SMatthew G. Knepley 
20950c2f2876SMatthew G. Knepley /*@C
20960c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20970c2f2876SMatthew G. Knepley 
209820f4b53cSBarry Smith   Not Collective
20990c2f2876SMatthew G. Knepley 
21004165533cSJose E. Roman   Input Parameters:
2101dce8aebaSBarry Smith + ds - The `PetscDS` object
21020c2f2876SMatthew G. Knepley . f  - The field number
21030c2f2876SMatthew G. Knepley - r  - Riemann solver
21040c2f2876SMatthew G. Knepley 
210520f4b53cSBarry Smith   Calling sequence of `r`:
21065db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21075db36cf9SMatthew G. Knepley . Nf           - The number of fields
21085db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21090c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21100c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21110c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21120c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
211397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
211497b6e6e8SMatthew G. Knepley . constants    - constant parameters
21150c2f2876SMatthew G. Knepley - ctx          - optional user context
21160c2f2876SMatthew G. Knepley 
21170c2f2876SMatthew G. Knepley   Level: intermediate
21180c2f2876SMatthew G. Knepley 
2119dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21200c2f2876SMatthew G. Knepley @*/
2121d71ae5a4SJacob 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))
2122d71ae5a4SJacob Faibussowitsch {
21230c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2125de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
212663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21290c2f2876SMatthew G. Knepley }
21300c2f2876SMatthew G. Knepley 
213132d2bbc9SMatthew G. Knepley /*@C
213232d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
213332d2bbc9SMatthew G. Knepley 
213420f4b53cSBarry Smith   Not Collective
213532d2bbc9SMatthew G. Knepley 
213632d2bbc9SMatthew G. Knepley   Input Parameters:
2137dce8aebaSBarry Smith + ds - The `PetscDS`
213832d2bbc9SMatthew G. Knepley - f  - The field number
213932d2bbc9SMatthew G. Knepley 
2140f899ff85SJose E. Roman   Output Parameter:
2141a2b725a8SWilliam Gropp . update - update function
214232d2bbc9SMatthew G. Knepley 
214320f4b53cSBarry Smith   Calling sequence of `update`:
214432d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
214532d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2146a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
214732d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
214832d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
214932d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
215032d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
215132d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
215232d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
215332d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
215432d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
215532d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
215632d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
215732d2bbc9SMatthew G. Knepley . t            - current time
215832d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2159a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2160a4e35b19SJacob Faibussowitsch . constants    - constant parameters
216132d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
216232d2bbc9SMatthew G. Knepley 
216332d2bbc9SMatthew G. Knepley   Level: intermediate
216432d2bbc9SMatthew G. Knepley 
2165dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
216632d2bbc9SMatthew G. Knepley @*/
2167d71ae5a4SJacob 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[]))
2168d71ae5a4SJacob Faibussowitsch {
216932d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21706528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217163a3b9bcSJacob 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);
21729371c9d4SSatish Balay   if (update) {
21734f572ea9SToby Isaac     PetscAssertPointer(update, 3);
21749371c9d4SSatish Balay     *update = ds->update[f];
21759371c9d4SSatish Balay   }
21763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217732d2bbc9SMatthew G. Knepley }
217832d2bbc9SMatthew G. Knepley 
217932d2bbc9SMatthew G. Knepley /*@C
21803fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
218132d2bbc9SMatthew G. Knepley 
218220f4b53cSBarry Smith   Not Collective
218332d2bbc9SMatthew G. Knepley 
218432d2bbc9SMatthew G. Knepley   Input Parameters:
2185dce8aebaSBarry Smith + ds     - The `PetscDS`
218632d2bbc9SMatthew G. Knepley . f      - The field number
218732d2bbc9SMatthew G. Knepley - update - update function
218832d2bbc9SMatthew G. Knepley 
218920f4b53cSBarry Smith   Calling sequence of `update`:
219032d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
219132d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2192a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
219332d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
219432d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
219532d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
219632d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
219732d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
219832d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
219932d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
220032d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
220132d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
220232d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
220332d2bbc9SMatthew G. Knepley . t            - current time
220432d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2205a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2206a4e35b19SJacob Faibussowitsch . constants    - constant parameters
220732d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
220832d2bbc9SMatthew G. Knepley 
220932d2bbc9SMatthew G. Knepley   Level: intermediate
221032d2bbc9SMatthew G. Knepley 
2211dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
221232d2bbc9SMatthew G. Knepley @*/
2213d71ae5a4SJacob 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[]))
2214d71ae5a4SJacob Faibussowitsch {
221532d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
221732d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
221863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22199566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22206528b96dSMatthew G. Knepley   ds->update[f] = update;
22213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
222232d2bbc9SMatthew G. Knepley }
222332d2bbc9SMatthew G. Knepley 
2224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2225d71ae5a4SJacob Faibussowitsch {
22260c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22276528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
222863a3b9bcSJacob 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);
22294f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22303ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22320c2f2876SMatthew G. Knepley }
22330c2f2876SMatthew G. Knepley 
2234d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2235d71ae5a4SJacob Faibussowitsch {
22360c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22399566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22406528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22420c2f2876SMatthew G. Knepley }
22430c2f2876SMatthew G. Knepley 
2244194d53e6SMatthew G. Knepley /*@C
2245194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2246194d53e6SMatthew G. Knepley 
224720f4b53cSBarry Smith   Not Collective
2248194d53e6SMatthew G. Knepley 
2249194d53e6SMatthew G. Knepley   Input Parameters:
22506528b96dSMatthew G. Knepley + ds - The PetscDS
2251194d53e6SMatthew G. Knepley - f  - The test field number
2252194d53e6SMatthew G. Knepley 
2253194d53e6SMatthew G. Knepley   Output Parameters:
2254194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2255194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2256194d53e6SMatthew G. Knepley 
2257a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2258194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2259194d53e6SMatthew G. Knepley . Nf           - the number of fields
2260a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2261194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2262194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2263194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2264194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2265194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2266194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2267194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2268194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2269194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2270194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2271194d53e6SMatthew G. Knepley . t            - current time
2272194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2273194d53e6SMatthew G. Knepley . n            - unit normal at the current point
227497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
227597b6e6e8SMatthew G. Knepley . constants    - constant parameters
2276194d53e6SMatthew G. Knepley - f0           - output values at the current point
2277194d53e6SMatthew G. Knepley 
2278194d53e6SMatthew G. Knepley   Level: intermediate
2279194d53e6SMatthew G. Knepley 
2280dce8aebaSBarry Smith   Note:
2281a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
228260225df5SJacob Faibussowitsch 
2283a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2284dce8aebaSBarry 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
2285dce8aebaSBarry Smith 
2286dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2287194d53e6SMatthew G. Knepley @*/
2288a4e35b19SJacob 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[]))
2289d71ae5a4SJacob Faibussowitsch {
22906528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22916528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22926528b96dSMatthew G. Knepley 
22932764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22946528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229563a3b9bcSJacob 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);
22969566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22976528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22986528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23002764a2aaSMatthew G. Knepley }
23012764a2aaSMatthew G. Knepley 
2302194d53e6SMatthew G. Knepley /*@C
2303194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2304194d53e6SMatthew G. Knepley 
230520f4b53cSBarry Smith   Not Collective
2306194d53e6SMatthew G. Knepley 
2307194d53e6SMatthew G. Knepley   Input Parameters:
2308dce8aebaSBarry Smith + ds - The `PetscDS`
2309194d53e6SMatthew G. Knepley . f  - The test field number
2310194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2311194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2312194d53e6SMatthew G. Knepley 
2313a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2314194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2315194d53e6SMatthew G. Knepley . Nf           - the number of fields
2316a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2317194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2318194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2319194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2320194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2321194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2322194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2323194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2324194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2325194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2326194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2327194d53e6SMatthew G. Knepley . t            - current time
2328194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2329194d53e6SMatthew G. Knepley . n            - unit normal at the current point
233097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
233197b6e6e8SMatthew G. Knepley . constants    - constant parameters
2332194d53e6SMatthew G. Knepley - f0           - output values at the current point
2333194d53e6SMatthew G. Knepley 
2334194d53e6SMatthew G. Knepley   Level: intermediate
2335194d53e6SMatthew G. Knepley 
2336dce8aebaSBarry Smith   Note:
2337a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
233860225df5SJacob Faibussowitsch 
2339a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2340dce8aebaSBarry 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
2341dce8aebaSBarry Smith 
2342dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2343194d53e6SMatthew G. Knepley @*/
2344a4e35b19SJacob 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[]))
2345d71ae5a4SJacob Faibussowitsch {
23462764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23476528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
234863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23499566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23512764a2aaSMatthew G. Knepley }
23522764a2aaSMatthew G. Knepley 
235327f02ce8SMatthew G. Knepley /*@
2354dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
235527f02ce8SMatthew G. Knepley 
235620f4b53cSBarry Smith   Not Collective
235727f02ce8SMatthew G. Knepley 
235827f02ce8SMatthew G. Knepley   Input Parameter:
2359dce8aebaSBarry Smith . ds - The `PetscDS`
236027f02ce8SMatthew G. Knepley 
236127f02ce8SMatthew G. Knepley   Output Parameter:
236227f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
236327f02ce8SMatthew G. Knepley 
236427f02ce8SMatthew G. Knepley   Level: intermediate
236527f02ce8SMatthew G. Knepley 
2366dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
236727f02ce8SMatthew G. Knepley @*/
2368d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2369d71ae5a4SJacob Faibussowitsch {
237027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23716528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23724f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
23739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
237527f02ce8SMatthew G. Knepley }
237627f02ce8SMatthew G. Knepley 
2377194d53e6SMatthew G. Knepley /*@C
2378194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2379194d53e6SMatthew G. Knepley 
238020f4b53cSBarry Smith   Not Collective
2381194d53e6SMatthew G. Knepley 
2382194d53e6SMatthew G. Knepley   Input Parameters:
2383dce8aebaSBarry Smith + ds - The `PetscDS`
2384194d53e6SMatthew G. Knepley . f  - The test field number
2385194d53e6SMatthew G. Knepley - g  - The field number
2386194d53e6SMatthew G. Knepley 
2387194d53e6SMatthew G. Knepley   Output Parameters:
2388194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2389194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2390194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2391194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2392194d53e6SMatthew G. Knepley 
2393a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2394194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2395194d53e6SMatthew G. Knepley . Nf           - the number of fields
2396a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2397194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2398194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2399194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2400194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2401194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2402194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2403194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2404194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2405194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2406194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2407194d53e6SMatthew G. Knepley . t            - current time
24082aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2409194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2410194d53e6SMatthew G. Knepley . n            - normal at the current point
241197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
241297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2413194d53e6SMatthew G. Knepley - g0           - output values at the current point
2414194d53e6SMatthew G. Knepley 
2415194d53e6SMatthew G. Knepley   Level: intermediate
2416194d53e6SMatthew G. Knepley 
2417dce8aebaSBarry Smith   Note:
2418a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
241960225df5SJacob Faibussowitsch 
2420a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2421dce8aebaSBarry Smith   \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 + \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
2422dce8aebaSBarry Smith 
2423dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2424194d53e6SMatthew G. Knepley @*/
2425a4e35b19SJacob 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[]))
2426d71ae5a4SJacob Faibussowitsch {
24276528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24286528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24296528b96dSMatthew G. Knepley 
24302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
243263a3b9bcSJacob 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);
243363a3b9bcSJacob 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);
24349566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24356528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24366528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24376528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24386528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24402764a2aaSMatthew G. Knepley }
24412764a2aaSMatthew G. Knepley 
2442194d53e6SMatthew G. Knepley /*@C
2443194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2444194d53e6SMatthew G. Knepley 
244520f4b53cSBarry Smith   Not Collective
2446194d53e6SMatthew G. Knepley 
2447194d53e6SMatthew G. Knepley   Input Parameters:
24486528b96dSMatthew G. Knepley + ds - The PetscDS
2449194d53e6SMatthew G. Knepley . f  - The test field number
2450194d53e6SMatthew G. Knepley . g  - The field number
2451194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2452194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2453194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2454194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2455194d53e6SMatthew G. Knepley 
2456a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2457194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2458194d53e6SMatthew G. Knepley . Nf           - the number of fields
2459a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2460194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2461194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2462194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2463194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2464194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2465194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2466194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2467194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2468194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2469194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2470194d53e6SMatthew G. Knepley . t            - current time
24712aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2472194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2473194d53e6SMatthew G. Knepley . n            - normal at the current point
247497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
247597b6e6e8SMatthew G. Knepley . constants    - constant parameters
2476194d53e6SMatthew G. Knepley - g0           - output values at the current point
2477194d53e6SMatthew G. Knepley 
2478194d53e6SMatthew G. Knepley   Level: intermediate
2479194d53e6SMatthew G. Knepley 
2480dce8aebaSBarry Smith   Note:
2481a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
248260225df5SJacob Faibussowitsch 
2483a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2484dce8aebaSBarry Smith   \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 + \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
2485dce8aebaSBarry Smith 
2486dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2487194d53e6SMatthew G. Knepley @*/
2488a4e35b19SJacob 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[]))
2489d71ae5a4SJacob Faibussowitsch {
24902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24922764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24932764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24942764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24952764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
249663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
249763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25002764a2aaSMatthew G. Knepley }
25012764a2aaSMatthew G. Knepley 
250227f02ce8SMatthew G. Knepley /*@
250327f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
250427f02ce8SMatthew G. Knepley 
250520f4b53cSBarry Smith   Not Collective
250627f02ce8SMatthew G. Knepley 
250727f02ce8SMatthew G. Knepley   Input Parameter:
2508dce8aebaSBarry Smith . ds - The `PetscDS`
250927f02ce8SMatthew G. Knepley 
251027f02ce8SMatthew G. Knepley   Output Parameter:
251160225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
251227f02ce8SMatthew G. Knepley 
251327f02ce8SMatthew G. Knepley   Level: intermediate
251427f02ce8SMatthew G. Knepley 
2515dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
251627f02ce8SMatthew G. Knepley @*/
2517d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2518d71ae5a4SJacob Faibussowitsch {
251927f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25206528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25214f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
252427f02ce8SMatthew G. Knepley }
252527f02ce8SMatthew G. Knepley 
252627f02ce8SMatthew G. Knepley /*@C
252727f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
252827f02ce8SMatthew G. Knepley 
252920f4b53cSBarry Smith   Not Collective; No Fortran Support
253027f02ce8SMatthew G. Knepley 
253127f02ce8SMatthew G. Knepley   Input Parameters:
2532dce8aebaSBarry Smith + ds - The `PetscDS`
253327f02ce8SMatthew G. Knepley . f  - The test field number
253427f02ce8SMatthew G. Knepley - g  - The field number
253527f02ce8SMatthew G. Knepley 
253627f02ce8SMatthew G. Knepley   Output Parameters:
253727f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
253827f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
253927f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
254027f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
254127f02ce8SMatthew G. Knepley 
2542a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
254327f02ce8SMatthew G. Knepley + dim          - the spatial dimension
254427f02ce8SMatthew G. Knepley . Nf           - the number of fields
254527f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
254627f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
254727f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
254827f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
254927f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
255027f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
255127f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
255227f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
255327f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
255427f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
255527f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
255627f02ce8SMatthew G. Knepley . t            - current time
255727f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
255827f02ce8SMatthew G. Knepley . x            - coordinates of the current point
255927f02ce8SMatthew G. Knepley . n            - normal at the current point
256027f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
256127f02ce8SMatthew G. Knepley . constants    - constant parameters
256227f02ce8SMatthew G. Knepley - g0           - output values at the current point
256327f02ce8SMatthew G. Knepley 
256427f02ce8SMatthew G. Knepley   Level: intermediate
256527f02ce8SMatthew G. Knepley 
2566dce8aebaSBarry Smith   Note:
2567a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
256860225df5SJacob Faibussowitsch 
2569a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2570dce8aebaSBarry Smith   \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 + \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
2571dce8aebaSBarry Smith 
2572dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
257327f02ce8SMatthew G. Knepley @*/
2574a4e35b19SJacob 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[]))
2575d71ae5a4SJacob Faibussowitsch {
25766528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25776528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25786528b96dSMatthew G. Knepley 
257927f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25806528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
258163a3b9bcSJacob 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);
258263a3b9bcSJacob 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);
25839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25846528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25856528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25866528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25876528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
258927f02ce8SMatthew G. Knepley }
259027f02ce8SMatthew G. Knepley 
259127f02ce8SMatthew G. Knepley /*@C
259227f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
259327f02ce8SMatthew G. Knepley 
259420f4b53cSBarry Smith   Not Collective; No Fortran Support
259527f02ce8SMatthew G. Knepley 
259627f02ce8SMatthew G. Knepley   Input Parameters:
2597dce8aebaSBarry Smith + ds - The `PetscDS`
259827f02ce8SMatthew G. Knepley . f  - The test field number
259927f02ce8SMatthew G. Knepley . g  - The field number
260027f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
260127f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
260227f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
260327f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
260427f02ce8SMatthew G. Knepley 
2605a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
260627f02ce8SMatthew G. Knepley + dim          - the spatial dimension
260727f02ce8SMatthew G. Knepley . Nf           - the number of fields
260827f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
260927f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
261027f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
261127f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
261227f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
261327f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
261427f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
261527f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
261627f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
261727f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
261827f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
261927f02ce8SMatthew G. Knepley . t            - current time
262027f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
262127f02ce8SMatthew G. Knepley . x            - coordinates of the current point
262227f02ce8SMatthew G. Knepley . n            - normal at the current point
262327f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
262427f02ce8SMatthew G. Knepley . constants    - constant parameters
262527f02ce8SMatthew G. Knepley - g0           - output values at the current point
262627f02ce8SMatthew G. Knepley 
262727f02ce8SMatthew G. Knepley   Level: intermediate
262827f02ce8SMatthew G. Knepley 
2629dce8aebaSBarry Smith   Note:
2630a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
263160225df5SJacob Faibussowitsch 
2632a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2633dce8aebaSBarry Smith   \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 + \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
2634dce8aebaSBarry Smith 
2635dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
263627f02ce8SMatthew G. Knepley @*/
2637a4e35b19SJacob 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[]))
2638d71ae5a4SJacob Faibussowitsch {
263927f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26406528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
264127f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
264227f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
264327f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
264427f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
264563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
264663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264927f02ce8SMatthew G. Knepley }
265027f02ce8SMatthew G. Knepley 
26510d3e9b51SMatthew G. Knepley /*@C
2652c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2653c371a6d1SMatthew G. Knepley 
265420f4b53cSBarry Smith   Not Collective
2655c371a6d1SMatthew G. Knepley 
2656c371a6d1SMatthew G. Knepley   Input Parameters:
2657c371a6d1SMatthew G. Knepley + prob - The PetscDS
2658c371a6d1SMatthew G. Knepley - f    - The test field number
2659c371a6d1SMatthew G. Knepley 
2660d8d19677SJose E. Roman   Output Parameters:
2661a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2662a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2663c371a6d1SMatthew G. Knepley 
266420f4b53cSBarry Smith   Calling sequence of `exactSol`:
2665c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2666c371a6d1SMatthew G. Knepley . t   - current time
2667c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2668c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2669a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2670c371a6d1SMatthew G. Knepley - ctx - a user context
2671c371a6d1SMatthew G. Knepley 
2672c371a6d1SMatthew G. Knepley   Level: intermediate
2673c371a6d1SMatthew G. Knepley 
2674dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2675c371a6d1SMatthew G. Knepley @*/
2676d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2677d71ae5a4SJacob Faibussowitsch {
2678c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2679c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
268063a3b9bcSJacob 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);
26819371c9d4SSatish Balay   if (sol) {
26824f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
26839371c9d4SSatish Balay     *sol = prob->exactSol[f];
26849371c9d4SSatish Balay   }
26859371c9d4SSatish Balay   if (ctx) {
26864f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
26879371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26889371c9d4SSatish Balay   }
26893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2690c371a6d1SMatthew G. Knepley }
2691c371a6d1SMatthew G. Knepley 
2692c371a6d1SMatthew G. Knepley /*@C
2693578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2694c371a6d1SMatthew G. Knepley 
269520f4b53cSBarry Smith   Not Collective
2696c371a6d1SMatthew G. Knepley 
2697c371a6d1SMatthew G. Knepley   Input Parameters:
2698dce8aebaSBarry Smith + prob - The `PetscDS`
2699c371a6d1SMatthew G. Knepley . f    - The test field number
270095cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
270120f4b53cSBarry Smith - ctx  - solution context or `NULL`
2702c371a6d1SMatthew G. Knepley 
270320f4b53cSBarry Smith   Calling sequence of `sol`:
2704c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2705c371a6d1SMatthew G. Knepley . t   - current time
2706c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2707c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2708c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2709c371a6d1SMatthew G. Knepley - ctx - a user context
2710c371a6d1SMatthew G. Knepley 
2711c371a6d1SMatthew G. Knepley   Level: intermediate
2712c371a6d1SMatthew G. Knepley 
2713dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2714c371a6d1SMatthew G. Knepley @*/
2715d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2716d71ae5a4SJacob Faibussowitsch {
2717c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2718c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
271963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27209566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27219371c9d4SSatish Balay   if (sol) {
27229371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27239371c9d4SSatish Balay     prob->exactSol[f] = sol;
27249371c9d4SSatish Balay   }
27259371c9d4SSatish Balay   if (ctx) {
27269371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27279371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27289371c9d4SSatish Balay   }
27293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2730c371a6d1SMatthew G. Knepley }
2731c371a6d1SMatthew G. Knepley 
27325638fd0eSMatthew G. Knepley /*@C
2733f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2734f2cacb80SMatthew G. Knepley 
273520f4b53cSBarry Smith   Not Collective
2736f2cacb80SMatthew G. Knepley 
2737f2cacb80SMatthew G. Knepley   Input Parameters:
2738dce8aebaSBarry Smith + prob - The `PetscDS`
2739f2cacb80SMatthew G. Knepley - f    - The test field number
2740f2cacb80SMatthew G. Knepley 
2741d8d19677SJose E. Roman   Output Parameters:
2742a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2743a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2744f2cacb80SMatthew G. Knepley 
274520f4b53cSBarry Smith   Calling sequence of `exactSol`:
2746f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2747f2cacb80SMatthew G. Knepley . t   - current time
2748f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2749f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2750a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2751f2cacb80SMatthew G. Knepley - ctx - a user context
2752f2cacb80SMatthew G. Knepley 
2753f2cacb80SMatthew G. Knepley   Level: intermediate
2754f2cacb80SMatthew G. Knepley 
2755dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2756f2cacb80SMatthew G. Knepley @*/
2757d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2758d71ae5a4SJacob Faibussowitsch {
2759f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2760f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
276163a3b9bcSJacob 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);
27629371c9d4SSatish Balay   if (sol) {
27634f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27649371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27659371c9d4SSatish Balay   }
27669371c9d4SSatish Balay   if (ctx) {
27674f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27689371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27699371c9d4SSatish Balay   }
27703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2771f2cacb80SMatthew G. Knepley }
2772f2cacb80SMatthew G. Knepley 
2773f2cacb80SMatthew G. Knepley /*@C
2774f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2775f2cacb80SMatthew G. Knepley 
277620f4b53cSBarry Smith   Not Collective
2777f2cacb80SMatthew G. Knepley 
2778f2cacb80SMatthew G. Knepley   Input Parameters:
2779dce8aebaSBarry Smith + prob - The `PetscDS`
2780f2cacb80SMatthew G. Knepley . f    - The test field number
2781f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
278220f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2783f2cacb80SMatthew G. Knepley 
278420f4b53cSBarry Smith   Calling sequence of `sol`:
2785f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2786f2cacb80SMatthew G. Knepley . t   - current time
2787f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2788f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2789f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2790f2cacb80SMatthew G. Knepley - ctx - a user context
2791f2cacb80SMatthew G. Knepley 
2792f2cacb80SMatthew G. Knepley   Level: intermediate
2793f2cacb80SMatthew G. Knepley 
2794dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2795f2cacb80SMatthew G. Knepley @*/
2796d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2797d71ae5a4SJacob Faibussowitsch {
2798f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2799f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
280063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28019566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28029371c9d4SSatish Balay   if (sol) {
28039371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28049371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28059371c9d4SSatish Balay   }
28069371c9d4SSatish Balay   if (ctx) {
28079371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28089371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28099371c9d4SSatish Balay   }
28103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2811f2cacb80SMatthew G. Knepley }
2812f2cacb80SMatthew G. Knepley 
2813f2cacb80SMatthew G. Knepley /*@C
281497b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
281597b6e6e8SMatthew G. Knepley 
281620f4b53cSBarry Smith   Not Collective
281797b6e6e8SMatthew G. Knepley 
281897b6e6e8SMatthew G. Knepley   Input Parameter:
2819dce8aebaSBarry Smith . prob - The `PetscDS` object
282097b6e6e8SMatthew G. Knepley 
282197b6e6e8SMatthew G. Knepley   Output Parameters:
282297b6e6e8SMatthew G. Knepley + numConstants - The number of constants
282397b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
282497b6e6e8SMatthew G. Knepley 
282597b6e6e8SMatthew G. Knepley   Level: intermediate
282697b6e6e8SMatthew G. Knepley 
2827dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
282897b6e6e8SMatthew G. Knepley @*/
2829d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2830d71ae5a4SJacob Faibussowitsch {
283197b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
283297b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28339371c9d4SSatish Balay   if (numConstants) {
28344f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
28359371c9d4SSatish Balay     *numConstants = prob->numConstants;
28369371c9d4SSatish Balay   }
28379371c9d4SSatish Balay   if (constants) {
28384f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28399371c9d4SSatish Balay     *constants = prob->constants;
28409371c9d4SSatish Balay   }
28413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
284297b6e6e8SMatthew G. Knepley }
284397b6e6e8SMatthew G. Knepley 
28440d3e9b51SMatthew G. Knepley /*@C
284597b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
284697b6e6e8SMatthew G. Knepley 
284720f4b53cSBarry Smith   Not Collective
284897b6e6e8SMatthew G. Knepley 
284997b6e6e8SMatthew G. Knepley   Input Parameters:
2850dce8aebaSBarry Smith + prob         - The `PetscDS` object
285197b6e6e8SMatthew G. Knepley . numConstants - The number of constants
2852a3b724e8SBarry Smith - constants    - The array of constants, `NULL` if there are none
285397b6e6e8SMatthew G. Knepley 
285497b6e6e8SMatthew G. Knepley   Level: intermediate
285597b6e6e8SMatthew G. Knepley 
2856dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
285797b6e6e8SMatthew G. Knepley @*/
2858d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2859d71ae5a4SJacob Faibussowitsch {
286097b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
286197b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
286297b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28639566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
286497b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
286597b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28669566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
286720be0f5bSMatthew G. Knepley     } else {
286820be0f5bSMatthew G. Knepley       prob->constants = NULL;
286920be0f5bSMatthew G. Knepley     }
287020be0f5bSMatthew G. Knepley   }
287120be0f5bSMatthew G. Knepley   if (prob->numConstants) {
28724f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28739566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
287497b6e6e8SMatthew G. Knepley   }
28753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
287697b6e6e8SMatthew G. Knepley }
287797b6e6e8SMatthew G. Knepley 
28784cd1e086SMatthew G. Knepley /*@
28794cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28804cd1e086SMatthew G. Knepley 
288120f4b53cSBarry Smith   Not Collective
28824cd1e086SMatthew G. Knepley 
28834cd1e086SMatthew G. Knepley   Input Parameters:
2884dce8aebaSBarry Smith + prob - The `PetscDS` object
28854cd1e086SMatthew G. Knepley - disc - The discretization object
28864cd1e086SMatthew G. Knepley 
28874cd1e086SMatthew G. Knepley   Output Parameter:
28884cd1e086SMatthew G. Knepley . f - The field number
28894cd1e086SMatthew G. Knepley 
28904cd1e086SMatthew G. Knepley   Level: beginner
28914cd1e086SMatthew G. Knepley 
2892dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28934cd1e086SMatthew G. Knepley @*/
2894d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2895d71ae5a4SJacob Faibussowitsch {
28964cd1e086SMatthew G. Knepley   PetscInt g;
28974cd1e086SMatthew G. Knepley 
28984cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28994cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29004f572ea9SToby Isaac   PetscAssertPointer(f, 3);
29014cd1e086SMatthew G. Knepley   *f = -1;
29029371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
29039371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
29049371c9d4SSatish Balay   }
290508401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
29064cd1e086SMatthew G. Knepley   *f = g;
29073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29084cd1e086SMatthew G. Knepley }
29094cd1e086SMatthew G. Knepley 
29104cd1e086SMatthew G. Knepley /*@
29114cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29124cd1e086SMatthew G. Knepley 
291320f4b53cSBarry Smith   Not Collective
29144cd1e086SMatthew G. Knepley 
29154cd1e086SMatthew G. Knepley   Input Parameters:
2916dce8aebaSBarry Smith + prob - The `PetscDS` object
29174cd1e086SMatthew G. Knepley - f    - The field number
29184cd1e086SMatthew G. Knepley 
29194cd1e086SMatthew G. Knepley   Output Parameter:
29204cd1e086SMatthew G. Knepley . size - The size
29214cd1e086SMatthew G. Knepley 
29224cd1e086SMatthew G. Knepley   Level: beginner
29234cd1e086SMatthew G. Knepley 
2924dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29254cd1e086SMatthew G. Knepley @*/
2926d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2927d71ae5a4SJacob Faibussowitsch {
29284cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29294cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29304f572ea9SToby Isaac   PetscAssertPointer(size, 3);
293163a3b9bcSJacob 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);
29329566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2933d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29354cd1e086SMatthew G. Knepley }
29364cd1e086SMatthew G. Knepley 
2937bc4ae4beSMatthew G. Knepley /*@
2938bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2939bc4ae4beSMatthew G. Knepley 
294020f4b53cSBarry Smith   Not Collective
2941bc4ae4beSMatthew G. Knepley 
2942bc4ae4beSMatthew G. Knepley   Input Parameters:
2943dce8aebaSBarry Smith + prob - The `PetscDS` object
2944bc4ae4beSMatthew G. Knepley - f    - The field number
2945bc4ae4beSMatthew G. Knepley 
2946bc4ae4beSMatthew G. Knepley   Output Parameter:
2947bc4ae4beSMatthew G. Knepley . off - The offset
2948bc4ae4beSMatthew G. Knepley 
2949bc4ae4beSMatthew G. Knepley   Level: beginner
2950bc4ae4beSMatthew G. Knepley 
2951dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2952bc4ae4beSMatthew G. Knepley @*/
2953d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2954d71ae5a4SJacob Faibussowitsch {
29554cd1e086SMatthew G. Knepley   PetscInt size, g;
29562764a2aaSMatthew G. Knepley 
29572764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29582764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29594f572ea9SToby Isaac   PetscAssertPointer(off, 3);
296063a3b9bcSJacob 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);
29612764a2aaSMatthew G. Knepley   *off = 0;
29622764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29639566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29644cd1e086SMatthew G. Knepley     *off += size;
29652764a2aaSMatthew G. Knepley   }
29663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29672764a2aaSMatthew G. Knepley }
29682764a2aaSMatthew G. Knepley 
2969bc4ae4beSMatthew G. Knepley /*@
29705fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29715fedec97SMatthew G. Knepley 
297220f4b53cSBarry Smith   Not Collective
29735fedec97SMatthew G. Knepley 
29745fedec97SMatthew G. Knepley   Input Parameters:
297560225df5SJacob Faibussowitsch + ds - The `PetscDS` object
29765fedec97SMatthew G. Knepley - f  - The field number
29775fedec97SMatthew G. Knepley 
29785fedec97SMatthew G. Knepley   Output Parameter:
29795fedec97SMatthew G. Knepley . off - The offset
29805fedec97SMatthew G. Knepley 
29815fedec97SMatthew G. Knepley   Level: beginner
29825fedec97SMatthew G. Knepley 
2983dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29845fedec97SMatthew G. Knepley @*/
2985d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2986d71ae5a4SJacob Faibussowitsch {
29875fedec97SMatthew G. Knepley   PetscInt size, g;
29885fedec97SMatthew G. Knepley 
29895fedec97SMatthew G. Knepley   PetscFunctionBegin;
29905fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
29914f572ea9SToby Isaac   PetscAssertPointer(off, 3);
299263a3b9bcSJacob 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);
29935fedec97SMatthew G. Knepley   *off = 0;
29945fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29955fedec97SMatthew G. Knepley     PetscBool cohesive;
29965fedec97SMatthew G. Knepley 
29979566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29989566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29995fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
30005fedec97SMatthew G. Knepley   }
30013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30025fedec97SMatthew G. Knepley }
30035fedec97SMatthew G. Knepley 
30045fedec97SMatthew G. Knepley /*@
300547e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3006bc4ae4beSMatthew G. Knepley 
300720f4b53cSBarry Smith   Not Collective
3008bc4ae4beSMatthew G. Knepley 
300947e57110SSander Arens   Input Parameter:
3010dce8aebaSBarry Smith . prob - The `PetscDS` object
3011bc4ae4beSMatthew G. Knepley 
3012bc4ae4beSMatthew G. Knepley   Output Parameter:
301347e57110SSander Arens . dimensions - The number of dimensions
3014bc4ae4beSMatthew G. Knepley 
3015bc4ae4beSMatthew G. Knepley   Level: beginner
3016bc4ae4beSMatthew G. Knepley 
3017dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3018bc4ae4beSMatthew G. Knepley @*/
3019d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3020d71ae5a4SJacob Faibussowitsch {
30212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30222764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30239566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30244f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
302547e57110SSander Arens   *dimensions = prob->Nb;
30263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30276ce16762SMatthew G. Knepley }
302847e57110SSander Arens 
302947e57110SSander Arens /*@
303047e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
303147e57110SSander Arens 
303220f4b53cSBarry Smith   Not Collective
303347e57110SSander Arens 
303447e57110SSander Arens   Input Parameter:
3035dce8aebaSBarry Smith . prob - The `PetscDS` object
303647e57110SSander Arens 
303747e57110SSander Arens   Output Parameter:
303847e57110SSander Arens . components - The number of components
303947e57110SSander Arens 
304047e57110SSander Arens   Level: beginner
304147e57110SSander Arens 
3042dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
304347e57110SSander Arens @*/
3044d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3045d71ae5a4SJacob Faibussowitsch {
304647e57110SSander Arens   PetscFunctionBegin;
304747e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30489566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30494f572ea9SToby Isaac   PetscAssertPointer(components, 2);
305047e57110SSander Arens   *components = prob->Nc;
30513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30526ce16762SMatthew G. Knepley }
30536ce16762SMatthew G. Knepley 
30546ce16762SMatthew G. Knepley /*@
30556ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30566ce16762SMatthew G. Knepley 
305720f4b53cSBarry Smith   Not Collective
30586ce16762SMatthew G. Knepley 
30596ce16762SMatthew G. Knepley   Input Parameters:
3060dce8aebaSBarry Smith + prob - The `PetscDS` object
30616ce16762SMatthew G. Knepley - f    - The field number
30626ce16762SMatthew G. Knepley 
30636ce16762SMatthew G. Knepley   Output Parameter:
30646ce16762SMatthew G. Knepley . off - The offset
30656ce16762SMatthew G. Knepley 
30666ce16762SMatthew G. Knepley   Level: beginner
30676ce16762SMatthew G. Knepley 
3068dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30696ce16762SMatthew G. Knepley @*/
3070d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3071d71ae5a4SJacob Faibussowitsch {
30726ce16762SMatthew G. Knepley   PetscFunctionBegin;
30736ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30744f572ea9SToby Isaac   PetscAssertPointer(off, 3);
307563a3b9bcSJacob 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);
30769566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
307747e57110SSander Arens   *off = prob->off[f];
30783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30792764a2aaSMatthew G. Knepley }
30802764a2aaSMatthew G. Knepley 
3081194d53e6SMatthew G. Knepley /*@
3082194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3083194d53e6SMatthew G. Knepley 
308420f4b53cSBarry Smith   Not Collective
3085194d53e6SMatthew G. Knepley 
3086194d53e6SMatthew G. Knepley   Input Parameter:
3087dce8aebaSBarry Smith . prob - The `PetscDS` object
3088194d53e6SMatthew G. Knepley 
3089194d53e6SMatthew G. Knepley   Output Parameter:
3090194d53e6SMatthew G. Knepley . offsets - The offsets
3091194d53e6SMatthew G. Knepley 
3092194d53e6SMatthew G. Knepley   Level: beginner
3093194d53e6SMatthew G. Knepley 
3094dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3095194d53e6SMatthew G. Knepley @*/
3096d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3097d71ae5a4SJacob Faibussowitsch {
3098194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3099194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31004f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
31019566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3102194d53e6SMatthew G. Knepley   *offsets = prob->off;
31033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3104194d53e6SMatthew G. Knepley }
3105194d53e6SMatthew G. Knepley 
3106194d53e6SMatthew G. Knepley /*@
3107194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3108194d53e6SMatthew G. Knepley 
310920f4b53cSBarry Smith   Not Collective
3110194d53e6SMatthew G. Knepley 
3111194d53e6SMatthew G. Knepley   Input Parameter:
3112dce8aebaSBarry Smith . prob - The `PetscDS` object
3113194d53e6SMatthew G. Knepley 
3114194d53e6SMatthew G. Knepley   Output Parameter:
3115194d53e6SMatthew G. Knepley . offsets - The offsets
3116194d53e6SMatthew G. Knepley 
3117194d53e6SMatthew G. Knepley   Level: beginner
3118194d53e6SMatthew G. Knepley 
3119dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3120194d53e6SMatthew G. Knepley @*/
3121d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3122d71ae5a4SJacob Faibussowitsch {
3123194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3124194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31254f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
31269566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3127194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3129194d53e6SMatthew G. Knepley }
3130194d53e6SMatthew G. Knepley 
31319ee2af8cSMatthew G. Knepley /*@
31329ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31339ee2af8cSMatthew G. Knepley 
313420f4b53cSBarry Smith   Not Collective
31359ee2af8cSMatthew G. Knepley 
31369ee2af8cSMatthew G. Knepley   Input Parameters:
3137dce8aebaSBarry Smith + ds - The `PetscDS` object
31389ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31399ee2af8cSMatthew G. Knepley 
31409ee2af8cSMatthew G. Knepley   Output Parameter:
31419ee2af8cSMatthew G. Knepley . offsets - The offsets
31429ee2af8cSMatthew G. Knepley 
31439ee2af8cSMatthew G. Knepley   Level: beginner
31449ee2af8cSMatthew G. Knepley 
3145dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31469ee2af8cSMatthew G. Knepley @*/
3147d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3148d71ae5a4SJacob Faibussowitsch {
31499ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31509ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31514f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
315228b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
315363a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31549566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31559ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31579ee2af8cSMatthew G. Knepley }
31589ee2af8cSMatthew G. Knepley 
31599ee2af8cSMatthew G. Knepley /*@
31609ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31619ee2af8cSMatthew G. Knepley 
316220f4b53cSBarry Smith   Not Collective
31639ee2af8cSMatthew G. Knepley 
31649ee2af8cSMatthew G. Knepley   Input Parameters:
3165dce8aebaSBarry Smith + ds - The `PetscDS` object
31669ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31679ee2af8cSMatthew G. Knepley 
31689ee2af8cSMatthew G. Knepley   Output Parameter:
31699ee2af8cSMatthew G. Knepley . offsets - The offsets
31709ee2af8cSMatthew G. Knepley 
31719ee2af8cSMatthew G. Knepley   Level: beginner
31729ee2af8cSMatthew G. Knepley 
3173dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31749ee2af8cSMatthew G. Knepley @*/
3175d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3176d71ae5a4SJacob Faibussowitsch {
31779ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31789ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31794f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
318028b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
318163a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31829566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31839ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31859ee2af8cSMatthew G. Knepley }
31869ee2af8cSMatthew G. Knepley 
318768c9edb9SMatthew G. Knepley /*@C
318868c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
318968c9edb9SMatthew G. Knepley 
319020f4b53cSBarry Smith   Not Collective
319168c9edb9SMatthew G. Knepley 
319268c9edb9SMatthew G. Knepley   Input Parameter:
3193dce8aebaSBarry Smith . prob - The `PetscDS` object
319468c9edb9SMatthew G. Knepley 
3195ef0bb6c7SMatthew G. Knepley   Output Parameter:
3196ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
319768c9edb9SMatthew G. Knepley 
319868c9edb9SMatthew G. Knepley   Level: intermediate
319968c9edb9SMatthew G. Knepley 
3200dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
320168c9edb9SMatthew G. Knepley @*/
3202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3203d71ae5a4SJacob Faibussowitsch {
32042764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32052764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32064f572ea9SToby Isaac   PetscAssertPointer(T, 2);
32079566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3208ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32102764a2aaSMatthew G. Knepley }
32112764a2aaSMatthew G. Knepley 
321268c9edb9SMatthew G. Knepley /*@C
32134d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
321468c9edb9SMatthew G. Knepley 
321520f4b53cSBarry Smith   Not Collective
321668c9edb9SMatthew G. Knepley 
321768c9edb9SMatthew G. Knepley   Input Parameter:
3218dce8aebaSBarry Smith . prob - The `PetscDS` object
321968c9edb9SMatthew G. Knepley 
3220ef0bb6c7SMatthew G. Knepley   Output Parameter:
3221a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
322268c9edb9SMatthew G. Knepley 
322368c9edb9SMatthew G. Knepley   Level: intermediate
322468c9edb9SMatthew G. Knepley 
3225dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
322668c9edb9SMatthew G. Knepley @*/
3227d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3228d71ae5a4SJacob Faibussowitsch {
32292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32302764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32314f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
32329566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3233ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32352764a2aaSMatthew G. Knepley }
32362764a2aaSMatthew G. Knepley 
3237d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3238d71ae5a4SJacob Faibussowitsch {
32392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32402764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32419566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32429371c9d4SSatish Balay   if (u) {
32434f572ea9SToby Isaac     PetscAssertPointer(u, 2);
32449371c9d4SSatish Balay     *u = prob->u;
32459371c9d4SSatish Balay   }
32469371c9d4SSatish Balay   if (u_t) {
32474f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
32489371c9d4SSatish Balay     *u_t = prob->u_t;
32499371c9d4SSatish Balay   }
32509371c9d4SSatish Balay   if (u_x) {
32514f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
32529371c9d4SSatish Balay     *u_x = prob->u_x;
32539371c9d4SSatish Balay   }
32543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32552764a2aaSMatthew G. Knepley }
32562764a2aaSMatthew G. Knepley 
3257d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3258d71ae5a4SJacob Faibussowitsch {
32592764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32602764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32619566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32629371c9d4SSatish Balay   if (f0) {
32634f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
32649371c9d4SSatish Balay     *f0 = prob->f0;
32659371c9d4SSatish Balay   }
32669371c9d4SSatish Balay   if (f1) {
32674f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
32689371c9d4SSatish Balay     *f1 = prob->f1;
32699371c9d4SSatish Balay   }
32709371c9d4SSatish Balay   if (g0) {
32714f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
32729371c9d4SSatish Balay     *g0 = prob->g0;
32739371c9d4SSatish Balay   }
32749371c9d4SSatish Balay   if (g1) {
32754f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
32769371c9d4SSatish Balay     *g1 = prob->g1;
32779371c9d4SSatish Balay   }
32789371c9d4SSatish Balay   if (g2) {
32794f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
32809371c9d4SSatish Balay     *g2 = prob->g2;
32819371c9d4SSatish Balay   }
32829371c9d4SSatish Balay   if (g3) {
32834f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
32849371c9d4SSatish Balay     *g3 = prob->g3;
32859371c9d4SSatish Balay   }
32863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32872764a2aaSMatthew G. Knepley }
32882764a2aaSMatthew G. Knepley 
3289d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3290d71ae5a4SJacob Faibussowitsch {
32912764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32922764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32939566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32949371c9d4SSatish Balay   if (x) {
32954f572ea9SToby Isaac     PetscAssertPointer(x, 2);
32969371c9d4SSatish Balay     *x = prob->x;
32979371c9d4SSatish Balay   }
32989371c9d4SSatish Balay   if (basisReal) {
32994f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
33009371c9d4SSatish Balay     *basisReal = prob->basisReal;
33019371c9d4SSatish Balay   }
33029371c9d4SSatish Balay   if (basisDerReal) {
33034f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
33049371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
33059371c9d4SSatish Balay   }
33069371c9d4SSatish Balay   if (testReal) {
33074f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
33089371c9d4SSatish Balay     *testReal = prob->testReal;
33099371c9d4SSatish Balay   }
33109371c9d4SSatish Balay   if (testDerReal) {
33114f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
33129371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33139371c9d4SSatish Balay   }
33143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33152764a2aaSMatthew G. Knepley }
33162764a2aaSMatthew G. Knepley 
331758ebd649SToby Isaac /*@C
3318a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
331958ebd649SToby Isaac 
332020f4b53cSBarry Smith   Collective
3321783e2ec8SMatthew G. Knepley 
332258ebd649SToby Isaac   Input Parameters:
332358ebd649SToby Isaac + ds       - The PetscDS object
3324dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
332558ebd649SToby Isaac . name     - The BC name
332645480ffeSMatthew G. Knepley . label    - The label defining constrained points
3327dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
332845480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
332958ebd649SToby Isaac . field    - The field to constrain
333045480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
333158ebd649SToby Isaac . comps    - An array of constrained component numbers
333258ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3333a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
333458ebd649SToby Isaac - ctx      - An optional user context for bcFunc
333558ebd649SToby Isaac 
33362fe279fdSBarry Smith   Output Parameter:
333760225df5SJacob Faibussowitsch . bd - The boundary number
333845480ffeSMatthew G. Knepley 
333958ebd649SToby Isaac   Options Database Keys:
334058ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
334158ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
334258ebd649SToby Isaac 
3343dce8aebaSBarry Smith   Level: developer
3344dce8aebaSBarry Smith 
334556cf3b9cSMatthew G. Knepley   Note:
3346a4e35b19SJacob 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\:
334756cf3b9cSMatthew G. Knepley 
334820f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
334956cf3b9cSMatthew G. Knepley 
3350a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3351dce8aebaSBarry Smith .vb
335220f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3353dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3354dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3355dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3356dce8aebaSBarry Smith .ve
335756cf3b9cSMatthew G. Knepley + dim - the spatial dimension
335856cf3b9cSMatthew G. Knepley . Nf - the number of fields
335956cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
336056cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
336156cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
336256cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
336356cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
336456cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
336556cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
336656cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
336756cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
336856cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
336956cf3b9cSMatthew G. Knepley . t - current time
337056cf3b9cSMatthew G. Knepley . x - coordinates of the current point
337156cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
337256cf3b9cSMatthew G. Knepley . constants - constant parameters
337356cf3b9cSMatthew G. Knepley - bcval - output values at the current point
337456cf3b9cSMatthew G. Knepley 
3375a4e35b19SJacob Faibussowitsch   Notes:
3376a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3377a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3378a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3379a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3380a4e35b19SJacob Faibussowitsch 
3381dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
338258ebd649SToby Isaac @*/
3383d71ae5a4SJacob 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)
3384d71ae5a4SJacob Faibussowitsch {
338545480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
338645480ffeSMatthew G. Knepley   PetscInt    n    = 0;
338745480ffeSMatthew G. Knepley   const char *lname;
338858ebd649SToby Isaac 
338958ebd649SToby Isaac   PetscFunctionBegin;
339058ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3391783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
33924f572ea9SToby Isaac   PetscAssertPointer(name, 3);
339345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
339445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
339545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
339645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3397dce9da9cSMatthew 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);
3398d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3399d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3400d57bb9dbSMatthew G. Knepley     PetscInt  c;
3401d57bb9dbSMatthew G. Knepley 
34029566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
340363a3b9bcSJacob 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);
3404d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
34051dca8a05SBarry 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);
3406d57bb9dbSMatthew G. Knepley     }
3407d57bb9dbSMatthew G. Knepley   }
34089566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34099566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34139566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34159566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34179566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3418f971fd6bSMatthew G. Knepley   b->type   = type;
341945480ffeSMatthew G. Knepley   b->label  = label;
342045480ffeSMatthew G. Knepley   b->Nv     = Nv;
342158ebd649SToby Isaac   b->field  = field;
342245480ffeSMatthew G. Knepley   b->Nc     = Nc;
342358ebd649SToby Isaac   b->func   = bcFunc;
342456cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
342558ebd649SToby Isaac   b->ctx    = ctx;
342645480ffeSMatthew G. Knepley   b->next   = NULL;
342745480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
342845480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
342945480ffeSMatthew G. Knepley   while (head) {
343045480ffeSMatthew G. Knepley     if (!head->next) {
343145480ffeSMatthew G. Knepley       head->next = b;
343245480ffeSMatthew G. Knepley       head       = b;
343345480ffeSMatthew G. Knepley     }
343445480ffeSMatthew G. Knepley     head = head->next;
343545480ffeSMatthew G. Knepley     ++n;
343645480ffeSMatthew G. Knepley   }
34379371c9d4SSatish Balay   if (bd) {
34384f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
34399371c9d4SSatish Balay     *bd = n;
34409371c9d4SSatish Balay   }
34413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
344245480ffeSMatthew G. Knepley }
344345480ffeSMatthew G. Knepley 
3444a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
344545480ffeSMatthew G. Knepley /*@C
3446a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
344745480ffeSMatthew G. Knepley 
344820f4b53cSBarry Smith   Collective
344945480ffeSMatthew G. Knepley 
345045480ffeSMatthew G. Knepley   Input Parameters:
3451dce8aebaSBarry Smith + ds       - The `PetscDS` object
3452dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
345345480ffeSMatthew G. Knepley . name     - The BC name
345445480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3455dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
345645480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
345745480ffeSMatthew G. Knepley . field    - The field to constrain
345845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
345945480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
346045480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3461a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
346245480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
346345480ffeSMatthew G. Knepley 
34642fe279fdSBarry Smith   Output Parameter:
346560225df5SJacob Faibussowitsch . bd - The boundary number
346645480ffeSMatthew G. Knepley 
346745480ffeSMatthew G. Knepley   Options Database Keys:
346845480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
346945480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
347045480ffeSMatthew G. Knepley 
347120f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3472dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3473dce8aebaSBarry Smith .vb
347420f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3475dce8aebaSBarry Smith .ve
3476dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3477dce8aebaSBarry Smith .vb
347820f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3479dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3480dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3481dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3482dce8aebaSBarry Smith .ve
348345480ffeSMatthew G. Knepley + dim - the spatial dimension
348445480ffeSMatthew G. Knepley . Nf - the number of fields
348545480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
348645480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
348745480ffeSMatthew G. Knepley . u - each field evaluated at the current point
348845480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
348945480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
349045480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
349145480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
349245480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
349345480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
349445480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
349545480ffeSMatthew G. Knepley . t - current time
349645480ffeSMatthew G. Knepley . x - coordinates of the current point
349745480ffeSMatthew G. Knepley . numConstants - number of constant parameters
349845480ffeSMatthew G. Knepley . constants - constant parameters
349945480ffeSMatthew G. Knepley - bcval - output values at the current point
350045480ffeSMatthew G. Knepley 
350145480ffeSMatthew G. Knepley   Level: developer
350245480ffeSMatthew G. Knepley 
3503a4e35b19SJacob Faibussowitsch   Notes:
3504a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3505a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3506a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3507a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3508a4e35b19SJacob Faibussowitsch 
3509dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3510dce8aebaSBarry Smith 
3511dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
351245480ffeSMatthew G. Knepley @*/
3513d71ae5a4SJacob 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)
3514d71ae5a4SJacob Faibussowitsch {
351545480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
351645480ffeSMatthew G. Knepley   PetscInt   n    = 0;
351745480ffeSMatthew G. Knepley 
351845480ffeSMatthew G. Knepley   PetscFunctionBegin;
351945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
352045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
35214f572ea9SToby Isaac   PetscAssertPointer(name, 3);
35224f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
352345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
352445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
352545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35269566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35279566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35289566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35309566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35319566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35329566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35339566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35349566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
353545480ffeSMatthew G. Knepley   b->type   = type;
353645480ffeSMatthew G. Knepley   b->label  = NULL;
353745480ffeSMatthew G. Knepley   b->Nv     = Nv;
353845480ffeSMatthew G. Knepley   b->field  = field;
353945480ffeSMatthew G. Knepley   b->Nc     = Nc;
354045480ffeSMatthew G. Knepley   b->func   = bcFunc;
354145480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
354245480ffeSMatthew G. Knepley   b->ctx    = ctx;
354345480ffeSMatthew G. Knepley   b->next   = NULL;
354445480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
354545480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
354645480ffeSMatthew G. Knepley   while (head) {
354745480ffeSMatthew G. Knepley     if (!head->next) {
354845480ffeSMatthew G. Knepley       head->next = b;
354945480ffeSMatthew G. Knepley       head       = b;
355045480ffeSMatthew G. Knepley     }
355145480ffeSMatthew G. Knepley     head = head->next;
355245480ffeSMatthew G. Knepley     ++n;
355345480ffeSMatthew G. Knepley   }
35549371c9d4SSatish Balay   if (bd) {
35554f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
35569371c9d4SSatish Balay     *bd = n;
35579371c9d4SSatish Balay   }
35583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355958ebd649SToby Isaac }
356058ebd649SToby Isaac 
3561b67eacb3SMatthew G. Knepley /*@C
3562a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3563b67eacb3SMatthew G. Knepley 
3564b67eacb3SMatthew G. Knepley   Input Parameters:
3565dce8aebaSBarry Smith + ds       - The `PetscDS` object
3566b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3567dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3568b67eacb3SMatthew G. Knepley . name     - The BC name
356945480ffeSMatthew G. Knepley . label    - The label defining constrained points
3570dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
357145480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3572b67eacb3SMatthew G. Knepley . field    - The field to constrain
357345480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3574b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3575b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3576a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3577b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3578b67eacb3SMatthew G. Knepley 
3579b67eacb3SMatthew G. Knepley   Level: developer
3580b67eacb3SMatthew G. Knepley 
3581a4e35b19SJacob Faibussowitsch   Notes:
3582a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3583a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3584a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3585a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3586a4e35b19SJacob Faibussowitsch 
3587dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3588dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3589dce8aebaSBarry Smith 
3590dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3591b67eacb3SMatthew G. Knepley @*/
3592d71ae5a4SJacob 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)
3593d71ae5a4SJacob Faibussowitsch {
3594b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3595b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3596b67eacb3SMatthew G. Knepley 
3597b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3598b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3599b67eacb3SMatthew G. Knepley   while (b) {
3600b67eacb3SMatthew G. Knepley     if (n == bd) break;
3601b67eacb3SMatthew G. Knepley     b = b->next;
3602b67eacb3SMatthew G. Knepley     ++n;
3603b67eacb3SMatthew G. Knepley   }
360463a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3605b67eacb3SMatthew G. Knepley   if (name) {
36069566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36079566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3608b67eacb3SMatthew G. Knepley   }
3609b67eacb3SMatthew G. Knepley   b->type = type;
361045480ffeSMatthew G. Knepley   if (label) {
361145480ffeSMatthew G. Knepley     const char *name;
361245480ffeSMatthew G. Knepley 
361345480ffeSMatthew G. Knepley     b->label = label;
36149566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36159566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
36169566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
361745480ffeSMatthew G. Knepley   }
361845480ffeSMatthew G. Knepley   if (Nv >= 0) {
361945480ffeSMatthew G. Knepley     b->Nv = Nv;
36209566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36219566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
36229566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
362345480ffeSMatthew G. Knepley   }
362445480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
362545480ffeSMatthew G. Knepley   if (Nc >= 0) {
362645480ffeSMatthew G. Knepley     b->Nc = Nc;
36279566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36289566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36299566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
363045480ffeSMatthew G. Knepley   }
363145480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
363245480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
363345480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3635b67eacb3SMatthew G. Knepley }
3636b67eacb3SMatthew G. Knepley 
363758ebd649SToby Isaac /*@
363858ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
363958ebd649SToby Isaac 
36402fe279fdSBarry Smith   Input Parameter:
3641dce8aebaSBarry Smith . ds - The `PetscDS` object
364258ebd649SToby Isaac 
36432fe279fdSBarry Smith   Output Parameter:
364458ebd649SToby Isaac . numBd - The number of BC
364558ebd649SToby Isaac 
364658ebd649SToby Isaac   Level: intermediate
364758ebd649SToby Isaac 
3648dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
364958ebd649SToby Isaac @*/
3650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3651d71ae5a4SJacob Faibussowitsch {
365258ebd649SToby Isaac   DSBoundary b = ds->boundary;
365358ebd649SToby Isaac 
365458ebd649SToby Isaac   PetscFunctionBegin;
365558ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
36564f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
365758ebd649SToby Isaac   *numBd = 0;
36589371c9d4SSatish Balay   while (b) {
36599371c9d4SSatish Balay     ++(*numBd);
36609371c9d4SSatish Balay     b = b->next;
36619371c9d4SSatish Balay   }
36623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
366358ebd649SToby Isaac }
366458ebd649SToby Isaac 
366558ebd649SToby Isaac /*@C
36669a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
366758ebd649SToby Isaac 
366858ebd649SToby Isaac   Input Parameters:
3669dce8aebaSBarry Smith + ds - The `PetscDS` object
367058ebd649SToby Isaac - bd - The BC number
367158ebd649SToby Isaac 
367258ebd649SToby Isaac   Output Parameters:
3673dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3674dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
367558ebd649SToby Isaac . name   - The BC name
367645480ffeSMatthew G. Knepley . label  - The label defining constrained points
3677dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
367845480ffeSMatthew G. Knepley . values - An array of ids for constrained points
367958ebd649SToby Isaac . field  - The field to constrain
368045480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
368158ebd649SToby Isaac . comps  - An array of constrained component numbers
368260225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
368360225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
368458ebd649SToby Isaac - ctx    - An optional user context for bcFunc
368558ebd649SToby Isaac 
368658ebd649SToby Isaac   Options Database Keys:
368758ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
368858ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
368958ebd649SToby Isaac 
369058ebd649SToby Isaac   Level: developer
369158ebd649SToby Isaac 
3692dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
369358ebd649SToby Isaac @*/
3694d71ae5a4SJacob 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)
3695d71ae5a4SJacob Faibussowitsch {
369658ebd649SToby Isaac   DSBoundary b = ds->boundary;
369758ebd649SToby Isaac   PetscInt   n = 0;
369858ebd649SToby Isaac 
369958ebd649SToby Isaac   PetscFunctionBegin;
370058ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
370158ebd649SToby Isaac   while (b) {
370258ebd649SToby Isaac     if (n == bd) break;
370358ebd649SToby Isaac     b = b->next;
370458ebd649SToby Isaac     ++n;
370558ebd649SToby Isaac   }
370663a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
370745480ffeSMatthew G. Knepley   if (wf) {
37084f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
370945480ffeSMatthew G. Knepley     *wf = b->wf;
371045480ffeSMatthew G. Knepley   }
3711f971fd6bSMatthew G. Knepley   if (type) {
37124f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3713f971fd6bSMatthew G. Knepley     *type = b->type;
371458ebd649SToby Isaac   }
371558ebd649SToby Isaac   if (name) {
37164f572ea9SToby Isaac     PetscAssertPointer(name, 5);
371758ebd649SToby Isaac     *name = b->name;
371858ebd649SToby Isaac   }
371945480ffeSMatthew G. Knepley   if (label) {
37204f572ea9SToby Isaac     PetscAssertPointer(label, 6);
372145480ffeSMatthew G. Knepley     *label = b->label;
372245480ffeSMatthew G. Knepley   }
372345480ffeSMatthew G. Knepley   if (Nv) {
37244f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
372545480ffeSMatthew G. Knepley     *Nv = b->Nv;
372645480ffeSMatthew G. Knepley   }
372745480ffeSMatthew G. Knepley   if (values) {
37284f572ea9SToby Isaac     PetscAssertPointer(values, 8);
372945480ffeSMatthew G. Knepley     *values = b->values;
373058ebd649SToby Isaac   }
373158ebd649SToby Isaac   if (field) {
37324f572ea9SToby Isaac     PetscAssertPointer(field, 9);
373358ebd649SToby Isaac     *field = b->field;
373458ebd649SToby Isaac   }
373545480ffeSMatthew G. Knepley   if (Nc) {
37364f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
373745480ffeSMatthew G. Knepley     *Nc = b->Nc;
373858ebd649SToby Isaac   }
373958ebd649SToby Isaac   if (comps) {
37404f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
374158ebd649SToby Isaac     *comps = b->comps;
374258ebd649SToby Isaac   }
374358ebd649SToby Isaac   if (func) {
37444f572ea9SToby Isaac     PetscAssertPointer(func, 12);
374558ebd649SToby Isaac     *func = b->func;
374658ebd649SToby Isaac   }
374756cf3b9cSMatthew G. Knepley   if (func_t) {
37484f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
374956cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
375056cf3b9cSMatthew G. Knepley   }
375158ebd649SToby Isaac   if (ctx) {
37524f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
375358ebd649SToby Isaac     *ctx = b->ctx;
375458ebd649SToby Isaac   }
37553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375658ebd649SToby Isaac }
375758ebd649SToby Isaac 
375810af620dSMatthew G. Knepley /*@
375910af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
376010af620dSMatthew G. Knepley 
376110af620dSMatthew G. Knepley   Not Collective
376210af620dSMatthew G. Knepley 
376310af620dSMatthew G. Knepley   Input Parameters:
376410af620dSMatthew G. Knepley + ds - The source `PetscDS` object
376510af620dSMatthew G. Knepley - dm - The `DM` holding labels
376610af620dSMatthew G. Knepley 
376710af620dSMatthew G. Knepley   Level: intermediate
376810af620dSMatthew G. Knepley 
376910af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
377010af620dSMatthew G. Knepley @*/
377110af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
377210af620dSMatthew G. Knepley {
377310af620dSMatthew G. Knepley   DSBoundary b;
377410af620dSMatthew G. Knepley 
377510af620dSMatthew G. Knepley   PetscFunctionBegin;
377610af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
377710af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
377810af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
377910af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
378010af620dSMatthew G. Knepley   }
378110af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
378210af620dSMatthew G. Knepley }
378310af620dSMatthew G. Knepley 
3784d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3785d71ae5a4SJacob Faibussowitsch {
378645480ffeSMatthew G. Knepley   PetscFunctionBegin;
37879566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37889566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37909566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37919566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
379245480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
379345480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
379445480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37959566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37969566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
379745480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
379845480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
38009566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
380145480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
380245480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
380345480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
38043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
380545480ffeSMatthew G. Knepley }
380645480ffeSMatthew G. Knepley 
38079252d075SMatthew G. Knepley /*@
38089252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
38099252d075SMatthew G. Knepley 
381020f4b53cSBarry Smith   Not Collective
38119252d075SMatthew G. Knepley 
381236951cb5SMatthew G. Knepley   Input Parameters:
3813dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3814dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
381536951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
38169252d075SMatthew G. Knepley 
38179252d075SMatthew G. Knepley   Output Parameter:
3818dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
38199252d075SMatthew G. Knepley 
38209252d075SMatthew G. Knepley   Level: intermediate
38219252d075SMatthew G. Knepley 
3822dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38239252d075SMatthew G. Knepley @*/
3824d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3825d71ae5a4SJacob Faibussowitsch {
382645480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3827dff059c6SToby Isaac 
3828dff059c6SToby Isaac   PetscFunctionBegin;
382936951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
383036951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
38313ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
38329566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
3833f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
383436951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3835dff059c6SToby Isaac     DSBoundary bNew;
383636951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3837dff059c6SToby Isaac 
383836951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
383936951cb5SMatthew G. Knepley       PetscInt f;
384036951cb5SMatthew G. Knepley 
38419371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
38429371c9d4SSatish Balay         if (b->field == fields[f]) break;
384336951cb5SMatthew G. Knepley       if (f == numFields) continue;
384436951cb5SMatthew G. Knepley       fieldNew = f;
384536951cb5SMatthew G. Knepley     }
38469566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
384736951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3848dff059c6SToby Isaac     *lastnext   = bNew;
3849f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
3850dff059c6SToby Isaac   }
38513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3852dff059c6SToby Isaac }
3853dff059c6SToby Isaac 
38546c1eb96dSMatthew G. Knepley /*@
3855dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
385645480ffeSMatthew G. Knepley 
385720f4b53cSBarry Smith   Not Collective
385845480ffeSMatthew G. Knepley 
385945480ffeSMatthew G. Knepley   Input Parameter:
3860dce8aebaSBarry Smith . ds - The `PetscDS` object
386145480ffeSMatthew G. Knepley 
386245480ffeSMatthew G. Knepley   Level: intermediate
386345480ffeSMatthew G. Knepley 
3864dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
386545480ffeSMatthew G. Knepley @*/
3866d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3867d71ae5a4SJacob Faibussowitsch {
386845480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
386945480ffeSMatthew G. Knepley 
387045480ffeSMatthew G. Knepley   PetscFunctionBegin;
387145480ffeSMatthew G. Knepley   while (next) {
387245480ffeSMatthew G. Knepley     DSBoundary b = next;
387345480ffeSMatthew G. Knepley 
387445480ffeSMatthew G. Knepley     next = b->next;
38759566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38769566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38779566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38789566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38799566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38809566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
388145480ffeSMatthew G. Knepley   }
38823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
388345480ffeSMatthew G. Knepley }
388445480ffeSMatthew G. Knepley 
388545480ffeSMatthew G. Knepley /*@
38866c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38876c1eb96dSMatthew G. Knepley 
388820f4b53cSBarry Smith   Not Collective
38896c1eb96dSMatthew G. Knepley 
3890d8d19677SJose E. Roman   Input Parameters:
3891dce8aebaSBarry Smith + prob      - The `PetscDS` object
38926c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38936c1eb96dSMatthew G. Knepley - fields    - Old field number for each new field
38946c1eb96dSMatthew G. Knepley 
38956c1eb96dSMatthew G. Knepley   Output Parameter:
3896dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38976c1eb96dSMatthew G. Knepley 
38986c1eb96dSMatthew G. Knepley   Level: intermediate
38996c1eb96dSMatthew G. Knepley 
3900dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39016c1eb96dSMatthew G. Knepley @*/
3902d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3903d71ae5a4SJacob Faibussowitsch {
39046c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
39056c1eb96dSMatthew G. Knepley 
39066c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
39076c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39084f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39096c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39109566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39119566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
391245480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
39136c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39146c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
39156c1eb96dSMatthew G. Knepley     PetscObject    disc;
39166c1eb96dSMatthew G. Knepley 
39176c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
39189566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
39199566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
39206c1eb96dSMatthew G. Knepley   }
39213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39226c1eb96dSMatthew G. Knepley }
39236c1eb96dSMatthew G. Knepley 
39246c1eb96dSMatthew G. Knepley /*@
39259252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
39269252d075SMatthew G. Knepley 
392720f4b53cSBarry Smith   Not Collective
39289252d075SMatthew G. Knepley 
3929d8d19677SJose E. Roman   Input Parameters:
3930dce8aebaSBarry Smith + prob      - The `PetscDS` object
39319252d075SMatthew G. Knepley . numFields - Number of new fields
39329252d075SMatthew G. Knepley - fields    - Old field number for each new field
39339252d075SMatthew G. Knepley 
39349252d075SMatthew G. Knepley   Output Parameter:
3935dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39369252d075SMatthew G. Knepley 
39379252d075SMatthew G. Knepley   Level: intermediate
39389252d075SMatthew G. Knepley 
3939dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39409252d075SMatthew G. Knepley @*/
3941d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3942d71ae5a4SJacob Faibussowitsch {
39439252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
39449252d075SMatthew G. Knepley 
39459252d075SMatthew G. Knepley   PetscFunctionBegin;
39469252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39474f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39489252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39499566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39509566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
395163a3b9bcSJacob 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);
39529252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39539252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39549252d075SMatthew G. Knepley     PetscPointFunc   obj;
39559252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39569252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39579252d075SMatthew G. Knepley     PetscRiemannFunc r;
39589252d075SMatthew G. Knepley 
3959c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39609566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39619566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39629566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39639566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39659566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39689252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39699252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39709252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39719252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39729252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39739252d075SMatthew G. Knepley 
3974c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39759566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39769566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39779566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39789566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39799566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39809566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39819252d075SMatthew G. Knepley     }
39829252d075SMatthew G. Knepley   }
39833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39849252d075SMatthew G. Knepley }
39859252d075SMatthew G. Knepley 
3986da51fcedSMatthew G. Knepley /*@
3987dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3988da51fcedSMatthew G. Knepley 
398920f4b53cSBarry Smith   Not Collective
3990da51fcedSMatthew G. Knepley 
3991da51fcedSMatthew G. Knepley   Input Parameter:
3992dce8aebaSBarry Smith . prob - The `PetscDS` object
3993da51fcedSMatthew G. Knepley 
3994da51fcedSMatthew G. Knepley   Output Parameter:
3995dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3996da51fcedSMatthew G. Knepley 
3997da51fcedSMatthew G. Knepley   Level: intermediate
3998da51fcedSMatthew G. Knepley 
3999dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4000da51fcedSMatthew G. Knepley @*/
4001d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
4002d71ae5a4SJacob Faibussowitsch {
4003b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
40049252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4005da51fcedSMatthew G. Knepley 
4006da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4007da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4008da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40099566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40109566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
401163a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
40129566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
40139566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
40149566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
40153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40169252d075SMatthew G. Knepley }
401745480ffeSMatthew G. Knepley 
40189252d075SMatthew G. Knepley /*@
4019dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4020da51fcedSMatthew G. Knepley 
402120f4b53cSBarry Smith   Not Collective
40229252d075SMatthew G. Knepley 
40239252d075SMatthew G. Knepley   Input Parameter:
4024dce8aebaSBarry Smith . prob - The `PetscDS` object
40259252d075SMatthew G. Knepley 
40269252d075SMatthew G. Knepley   Output Parameter:
4027dce8aebaSBarry Smith . newprob - The `PetscDS` copy
40289252d075SMatthew G. Knepley 
40299252d075SMatthew G. Knepley   Level: intermediate
40309252d075SMatthew G. Knepley 
4031dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40329252d075SMatthew G. Knepley @*/
4033d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4034d71ae5a4SJacob Faibussowitsch {
40359252d075SMatthew G. Knepley   PetscInt           Nc;
40369252d075SMatthew G. Knepley   const PetscScalar *constants;
40379252d075SMatthew G. Knepley 
40389252d075SMatthew G. Knepley   PetscFunctionBegin;
40399252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
40409252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
40429566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
40433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4044da51fcedSMatthew G. Knepley }
4045da51fcedSMatthew G. Knepley 
404645480ffeSMatthew G. Knepley /*@
4047dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
404845480ffeSMatthew G. Knepley 
404920f4b53cSBarry Smith   Not Collective
405045480ffeSMatthew G. Knepley 
405145480ffeSMatthew G. Knepley   Input Parameter:
4052dce8aebaSBarry Smith . ds - The `PetscDS` object
405345480ffeSMatthew G. Knepley 
405445480ffeSMatthew G. Knepley   Output Parameter:
4055dce8aebaSBarry Smith . newds - The `PetscDS` copy
405645480ffeSMatthew G. Knepley 
405745480ffeSMatthew G. Knepley   Level: intermediate
405845480ffeSMatthew G. Knepley 
4059dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
406045480ffeSMatthew G. Knepley @*/
4061d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4062d71ae5a4SJacob Faibussowitsch {
40638434afd1SBarry Smith   PetscSimplePointFn *sol;
406445480ffeSMatthew G. Knepley   void               *ctx;
406545480ffeSMatthew G. Knepley   PetscInt            Nf, f;
406645480ffeSMatthew G. Knepley 
406745480ffeSMatthew G. Knepley   PetscFunctionBegin;
406845480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
406945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40709566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
407145480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40729566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40739566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40749566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40759566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
407645480ffeSMatthew G. Knepley   }
40773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
407845480ffeSMatthew G. Knepley }
407945480ffeSMatthew G. Knepley 
408007218a29SMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, DM dmNew, PetscDS dsNew)
408107218a29SMatthew G. Knepley {
408207218a29SMatthew G. Knepley   DSBoundary b;
408307218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
408407218a29SMatthew G. Knepley   PetscBool  isCohesive;
408507218a29SMatthew G. Knepley   void      *ctx;
408607218a29SMatthew G. Knepley 
408707218a29SMatthew G. Knepley   PetscFunctionBegin;
408807218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
408907218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
409007218a29SMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew));
409107218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
409207218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
409307218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
409407218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
409507218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
409607218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
409707218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
409807218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
409907218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
410007218a29SMatthew G. Knepley   }
410107218a29SMatthew G. Knepley   if (Nf) {
410207218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
410307218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
410407218a29SMatthew G. Knepley   }
410507218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
410607218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
410707218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
410807218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
410907218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
411007218a29SMatthew G. Knepley   }
411107218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
411207218a29SMatthew G. Knepley }
411307218a29SMatthew G. Knepley 
4114d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4115d71ae5a4SJacob Faibussowitsch {
4116df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4117b1353e8eSMatthew G. Knepley 
4118b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4119b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41204f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
41219371c9d4SSatish Balay   if (height == 0) {
41229371c9d4SSatish Balay     *subprob = prob;
41233ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
41249371c9d4SSatish Balay   }
41259566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41269566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
412763a3b9bcSJacob 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);
41289566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4129df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4130b1353e8eSMatthew G. Knepley     PetscInt cdim;
4131b1353e8eSMatthew G. Knepley 
41329566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
41339566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
41349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4135b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4136b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4137b1353e8eSMatthew G. Knepley       PetscObject  obj;
4138b1353e8eSMatthew G. Knepley       PetscClassId id;
4139b1353e8eSMatthew G. Knepley 
41409566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41419566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
41429566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
414363a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
41449566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4145b1353e8eSMatthew G. Knepley     }
4146b1353e8eSMatthew G. Knepley   }
4147df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
41483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4149b1353e8eSMatthew G. Knepley }
4150b1353e8eSMatthew G. Knepley 
41514366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
41524366bac7SMatthew G. Knepley {
41534366bac7SMatthew G. Knepley   IS              permIS;
41544366bac7SMatthew G. Knepley   PetscQuadrature quad;
41554366bac7SMatthew G. Knepley   DMPolytopeType  ct;
41564366bac7SMatthew G. Knepley   const PetscInt *perm;
41574366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
41584366bac7SMatthew G. Knepley 
41594366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
41604366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
41614366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
41624366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
41634366bac7SMatthew 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);
416485036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
41654366bac7SMatthew 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);
41664366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
41674366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
41684366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
41694366bac7SMatthew G. Knepley   *qperm = perm[q];
41704366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
41714366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
41724366bac7SMatthew G. Knepley }
41734366bac7SMatthew G. Knepley 
4174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4175d71ae5a4SJacob Faibussowitsch {
4176c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4177c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4178c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4179c7bd5f0bSMatthew G. Knepley 
4180c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4181c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41824f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4183665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
41849566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
418563a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
41869566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4187665f567fSMatthew G. Knepley   if (obj) {
41889566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4189665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4190665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4191665f567fSMatthew G. Knepley   }
41923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4193c7bd5f0bSMatthew G. Knepley }
4194c7bd5f0bSMatthew G. Knepley 
4195d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4196d71ae5a4SJacob Faibussowitsch {
41972764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41989566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
41993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42002764a2aaSMatthew G. Knepley }
42012764a2aaSMatthew G. Knepley 
4202d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4203d71ae5a4SJacob Faibussowitsch {
42042764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42056528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
42066528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
42076528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
42086528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
42093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42102764a2aaSMatthew G. Knepley }
42112764a2aaSMatthew G. Knepley 
42122764a2aaSMatthew G. Knepley /*MC
42132764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
42142764a2aaSMatthew G. Knepley 
42152764a2aaSMatthew G. Knepley   Level: intermediate
42162764a2aaSMatthew G. Knepley 
4217db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
42182764a2aaSMatthew G. Knepley M*/
42192764a2aaSMatthew G. Knepley 
4220d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4221d71ae5a4SJacob Faibussowitsch {
42222764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
42232764a2aaSMatthew G. Knepley 
42242764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42256528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
42264dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
42276528b96dSMatthew G. Knepley   ds->data = b;
42282764a2aaSMatthew G. Knepley 
42299566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
42303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42312764a2aaSMatthew G. Knepley }
4232