xref: /petsc/src/dm/dt/interface/dtds.c (revision b2deab974997777d2904fb5b4ce8bb26cde3bd61)
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 
592764a2aaSMatthew G. Knepley /*@C
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 
972764a2aaSMatthew G. Knepley /*@C
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 
2342764a2aaSMatthew G. Knepley /*@C
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 
256fe2efc57SMark /*@C
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));
353*b2deab97SMatthew 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 
3622764a2aaSMatthew G. Knepley /*@C
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 
1585cb36c0f9SMatthew G. Knepley /*@C
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 
1734475e0ac9SMatthew G. Knepley /*@C
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 
1745dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
174655c1f793SMatthew G. Knepley @*/
1747d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1748d71ae5a4SJacob Faibussowitsch {
174955c1f793SMatthew G. Knepley   PetscFunctionBegin;
175055c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
175155c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
175355c1f793SMatthew G. Knepley }
175455c1f793SMatthew G. Knepley 
175555c1f793SMatthew G. Knepley /*@C
1756dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1757475e0ac9SMatthew G. Knepley 
175820f4b53cSBarry Smith   Not Collective
1759475e0ac9SMatthew G. Knepley 
1760475e0ac9SMatthew G. Knepley   Input Parameter:
176160225df5SJacob Faibussowitsch . ds - The `PetscDS`
1762475e0ac9SMatthew G. Knepley 
1763475e0ac9SMatthew G. Knepley   Output Parameter:
1764475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1765475e0ac9SMatthew G. Knepley 
1766475e0ac9SMatthew G. Knepley   Level: intermediate
1767475e0ac9SMatthew G. Knepley 
1768dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1769475e0ac9SMatthew G. Knepley @*/
1770d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1771d71ae5a4SJacob Faibussowitsch {
1772475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17736528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1774475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17753ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17769566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1778475e0ac9SMatthew G. Knepley }
1779475e0ac9SMatthew G. Knepley 
1780475e0ac9SMatthew G. Knepley /*@C
1781dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1782dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1783475e0ac9SMatthew G. Knepley 
178420f4b53cSBarry Smith   Not Collective
1785475e0ac9SMatthew G. Knepley 
1786475e0ac9SMatthew G. Knepley   Input Parameters:
1787dce8aebaSBarry Smith + ds - The `PetscDS`
1788475e0ac9SMatthew G. Knepley . f  - The test field number
1789475e0ac9SMatthew G. Knepley - g  - The field number
1790475e0ac9SMatthew G. Knepley 
1791475e0ac9SMatthew G. Knepley   Output Parameters:
1792475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1793475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1794475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1795475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1796475e0ac9SMatthew G. Knepley 
1797a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1798475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1799475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1800a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1801475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1802475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1803475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1804475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1805475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1806475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1807475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1808475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1809475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1810475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1811475e0ac9SMatthew G. Knepley . t            - current time
1812475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1813475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
181497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
181597b6e6e8SMatthew G. Knepley . constants    - constant parameters
1816475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1817475e0ac9SMatthew G. Knepley 
1818475e0ac9SMatthew G. Knepley   Level: intermediate
1819475e0ac9SMatthew G. Knepley 
1820dce8aebaSBarry Smith   Note:
1821a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1822a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1823dce8aebaSBarry 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
1824dce8aebaSBarry Smith 
1825dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1826475e0ac9SMatthew G. Knepley @*/
1827a4e35b19SJacob 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[]))
1828d71ae5a4SJacob Faibussowitsch {
18296528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18306528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18316528b96dSMatthew G. Knepley 
1832475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18336528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
183463a3b9bcSJacob 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);
183563a3b9bcSJacob 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);
18369566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18376528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18386528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18396528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18406528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1842475e0ac9SMatthew G. Knepley }
1843475e0ac9SMatthew G. Knepley 
1844475e0ac9SMatthew G. Knepley /*@C
1845dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1846dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1847475e0ac9SMatthew G. Knepley 
184820f4b53cSBarry Smith   Not Collective
1849475e0ac9SMatthew G. Knepley 
1850475e0ac9SMatthew G. Knepley   Input Parameters:
1851dce8aebaSBarry Smith + ds - The `PetscDS`
1852475e0ac9SMatthew G. Knepley . f  - The test field number
1853475e0ac9SMatthew G. Knepley . g  - The field number
1854475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1855475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1856475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1857475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1858475e0ac9SMatthew G. Knepley 
1859a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1860475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1861475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1862a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1863475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1864475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1865475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1866475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1867475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1868475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1869475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1870475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1871475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1872475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1873475e0ac9SMatthew G. Knepley . t            - current time
1874475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1875475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
187697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
187797b6e6e8SMatthew G. Knepley . constants    - constant parameters
1878475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1879475e0ac9SMatthew G. Knepley 
1880475e0ac9SMatthew G. Knepley   Level: intermediate
1881475e0ac9SMatthew G. Knepley 
1882dce8aebaSBarry Smith   Note:
1883a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
188460225df5SJacob Faibussowitsch 
1885a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1886dce8aebaSBarry 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
1887dce8aebaSBarry Smith 
1888dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1889475e0ac9SMatthew G. Knepley @*/
1890a4e35b19SJacob 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[]))
1891d71ae5a4SJacob Faibussowitsch {
1892475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18936528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1894475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1895475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1896475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1897475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
189863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
189963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19009566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1902475e0ac9SMatthew G. Knepley }
1903475e0ac9SMatthew G. Knepley 
1904b7e05686SMatthew G. Knepley /*@C
1905b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1906b7e05686SMatthew G. Knepley 
190720f4b53cSBarry Smith   Not Collective
1908b7e05686SMatthew G. Knepley 
1909b7e05686SMatthew G. Knepley   Input Parameter:
1910dce8aebaSBarry Smith . ds - The `PetscDS`
1911b7e05686SMatthew G. Knepley 
1912b7e05686SMatthew G. Knepley   Output Parameter:
1913b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1914b7e05686SMatthew G. Knepley 
1915b7e05686SMatthew G. Knepley   Level: intermediate
1916b7e05686SMatthew G. Knepley 
1917dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1918b7e05686SMatthew G. Knepley @*/
1919d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1920d71ae5a4SJacob Faibussowitsch {
1921b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19239566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1925b7e05686SMatthew G. Knepley }
1926b7e05686SMatthew G. Knepley 
1927b7e05686SMatthew G. Knepley /*@C
1928b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1929b7e05686SMatthew G. Knepley 
193020f4b53cSBarry Smith   Not Collective
1931b7e05686SMatthew G. Knepley 
1932b7e05686SMatthew G. Knepley   Input Parameters:
1933dce8aebaSBarry Smith + ds - The `PetscDS`
1934b7e05686SMatthew G. Knepley . f  - The test field number
1935b7e05686SMatthew G. Knepley - g  - The field number
1936b7e05686SMatthew G. Knepley 
1937b7e05686SMatthew G. Knepley   Output Parameters:
1938b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1939b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1940b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1941b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1942b7e05686SMatthew G. Knepley 
1943a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1944b7e05686SMatthew G. Knepley + dim          - the spatial dimension
1945b7e05686SMatthew G. Knepley . Nf           - the number of fields
1946a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1947b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1948b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1949b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1950b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1951b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1952b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1953b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1954b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1955b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1956b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1957b7e05686SMatthew G. Knepley . t            - current time
1958b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1959b7e05686SMatthew G. Knepley . x            - coordinates of the current point
196097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
196197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1962b7e05686SMatthew G. Knepley - g0           - output values at the current point
1963b7e05686SMatthew G. Knepley 
1964b7e05686SMatthew G. Knepley   Level: intermediate
1965b7e05686SMatthew G. Knepley 
1966dce8aebaSBarry Smith   Note:
1967a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
196860225df5SJacob Faibussowitsch 
1969a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1970dce8aebaSBarry 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
1971dce8aebaSBarry Smith 
1972dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1973b7e05686SMatthew G. Knepley @*/
1974a4e35b19SJacob 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[]))
1975d71ae5a4SJacob Faibussowitsch {
19766528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19776528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19786528b96dSMatthew G. Knepley 
1979b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19806528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
198163a3b9bcSJacob 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);
198263a3b9bcSJacob 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);
19839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19846528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19856528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19866528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19876528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1989b7e05686SMatthew G. Knepley }
1990b7e05686SMatthew G. Knepley 
1991b7e05686SMatthew G. Knepley /*@C
1992b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1993b7e05686SMatthew G. Knepley 
199420f4b53cSBarry Smith   Not Collective
1995b7e05686SMatthew G. Knepley 
1996b7e05686SMatthew G. Knepley   Input Parameters:
1997dce8aebaSBarry Smith + ds - The `PetscDS`
1998b7e05686SMatthew G. Knepley . f  - The test field number
1999b7e05686SMatthew G. Knepley . g  - The field number
2000b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2001b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2002b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2003b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2004b7e05686SMatthew G. Knepley 
2005a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2006b7e05686SMatthew G. Knepley + dim          - the spatial dimension
2007b7e05686SMatthew G. Knepley . Nf           - the number of fields
2008a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2009b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2010b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2011b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2012b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2013b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2014b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2015b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2016b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2017b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2018b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2019b7e05686SMatthew G. Knepley . t            - current time
2020b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2021b7e05686SMatthew G. Knepley . x            - coordinates of the current point
202297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
202397b6e6e8SMatthew G. Knepley . constants    - constant parameters
2024b7e05686SMatthew G. Knepley - g0           - output values at the current point
2025b7e05686SMatthew G. Knepley 
2026b7e05686SMatthew G. Knepley   Level: intermediate
2027b7e05686SMatthew G. Knepley 
2028dce8aebaSBarry Smith   Note:
2029a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
203060225df5SJacob Faibussowitsch 
2031a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2032dce8aebaSBarry 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
2033dce8aebaSBarry Smith 
2034dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2035b7e05686SMatthew G. Knepley @*/
2036a4e35b19SJacob 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[]))
2037d71ae5a4SJacob Faibussowitsch {
2038b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20396528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2040b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2041b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2042b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2043b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
204463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
204563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2048b7e05686SMatthew G. Knepley }
2049b7e05686SMatthew G. Knepley 
20500c2f2876SMatthew G. Knepley /*@C
20510c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20520c2f2876SMatthew G. Knepley 
205320f4b53cSBarry Smith   Not Collective
20540c2f2876SMatthew G. Knepley 
20554165533cSJose E. Roman   Input Parameters:
2056dce8aebaSBarry Smith + ds - The `PetscDS` object
20570c2f2876SMatthew G. Knepley - f  - The field number
20580c2f2876SMatthew G. Knepley 
20594165533cSJose E. Roman   Output Parameter:
20600c2f2876SMatthew G. Knepley . r - Riemann solver
20610c2f2876SMatthew G. Knepley 
206220f4b53cSBarry Smith   Calling sequence of `r`:
20635db36cf9SMatthew G. Knepley + dim          - The spatial dimension
20645db36cf9SMatthew G. Knepley . Nf           - The number of fields
20655db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
20660c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
20670c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
20680c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
20690c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
207097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
207197b6e6e8SMatthew G. Knepley . constants    - constant parameters
20720c2f2876SMatthew G. Knepley - ctx          - optional user context
20730c2f2876SMatthew G. Knepley 
20740c2f2876SMatthew G. Knepley   Level: intermediate
20750c2f2876SMatthew G. Knepley 
2076dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20770c2f2876SMatthew G. Knepley @*/
2078d71ae5a4SJacob 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))
2079d71ae5a4SJacob Faibussowitsch {
20806528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20816528b96dSMatthew G. Knepley   PetscInt          n;
20826528b96dSMatthew G. Knepley 
20830c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20846528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20854f572ea9SToby Isaac   PetscAssertPointer(r, 3);
208663a3b9bcSJacob 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);
20879566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20886528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20900c2f2876SMatthew G. Knepley }
20910c2f2876SMatthew G. Knepley 
20920c2f2876SMatthew G. Knepley /*@C
20930c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20940c2f2876SMatthew G. Knepley 
209520f4b53cSBarry Smith   Not Collective
20960c2f2876SMatthew G. Knepley 
20974165533cSJose E. Roman   Input Parameters:
2098dce8aebaSBarry Smith + ds - The `PetscDS` object
20990c2f2876SMatthew G. Knepley . f  - The field number
21000c2f2876SMatthew G. Knepley - r  - Riemann solver
21010c2f2876SMatthew G. Knepley 
210220f4b53cSBarry Smith   Calling sequence of `r`:
21035db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21045db36cf9SMatthew G. Knepley . Nf           - The number of fields
21055db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21060c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21070c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21080c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21090c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
211097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
211197b6e6e8SMatthew G. Knepley . constants    - constant parameters
21120c2f2876SMatthew G. Knepley - ctx          - optional user context
21130c2f2876SMatthew G. Knepley 
21140c2f2876SMatthew G. Knepley   Level: intermediate
21150c2f2876SMatthew G. Knepley 
2116dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21170c2f2876SMatthew G. Knepley @*/
2118d71ae5a4SJacob 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))
2119d71ae5a4SJacob Faibussowitsch {
21200c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2122de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
212363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21260c2f2876SMatthew G. Knepley }
21270c2f2876SMatthew G. Knepley 
212832d2bbc9SMatthew G. Knepley /*@C
212932d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
213032d2bbc9SMatthew G. Knepley 
213120f4b53cSBarry Smith   Not Collective
213232d2bbc9SMatthew G. Knepley 
213332d2bbc9SMatthew G. Knepley   Input Parameters:
2134dce8aebaSBarry Smith + ds - The `PetscDS`
213532d2bbc9SMatthew G. Knepley - f  - The field number
213632d2bbc9SMatthew G. Knepley 
2137f899ff85SJose E. Roman   Output Parameter:
2138a2b725a8SWilliam Gropp . update - update function
213932d2bbc9SMatthew G. Knepley 
214020f4b53cSBarry Smith   Calling sequence of `update`:
214132d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
214232d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2143a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
214432d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
214532d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
214632d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
214732d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
214832d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
214932d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
215032d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
215132d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
215232d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
215332d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
215432d2bbc9SMatthew G. Knepley . t            - current time
215532d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2156a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2157a4e35b19SJacob Faibussowitsch . constants    - constant parameters
215832d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
215932d2bbc9SMatthew G. Knepley 
216032d2bbc9SMatthew G. Knepley   Level: intermediate
216132d2bbc9SMatthew G. Knepley 
2162dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
216332d2bbc9SMatthew G. Knepley @*/
2164d71ae5a4SJacob 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[]))
2165d71ae5a4SJacob Faibussowitsch {
216632d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216863a3b9bcSJacob 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);
21699371c9d4SSatish Balay   if (update) {
21704f572ea9SToby Isaac     PetscAssertPointer(update, 3);
21719371c9d4SSatish Balay     *update = ds->update[f];
21729371c9d4SSatish Balay   }
21733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217432d2bbc9SMatthew G. Knepley }
217532d2bbc9SMatthew G. Knepley 
217632d2bbc9SMatthew G. Knepley /*@C
21773fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
217832d2bbc9SMatthew G. Knepley 
217920f4b53cSBarry Smith   Not Collective
218032d2bbc9SMatthew G. Knepley 
218132d2bbc9SMatthew G. Knepley   Input Parameters:
2182dce8aebaSBarry Smith + ds     - The `PetscDS`
218332d2bbc9SMatthew G. Knepley . f      - The field number
218432d2bbc9SMatthew G. Knepley - update - update function
218532d2bbc9SMatthew G. Knepley 
218620f4b53cSBarry Smith   Calling sequence of `update`:
218732d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
218832d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2189a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
219032d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
219132d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
219232d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
219332d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
219432d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
219532d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
219632d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
219732d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
219832d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
219932d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
220032d2bbc9SMatthew G. Knepley . t            - current time
220132d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2202a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2203a4e35b19SJacob Faibussowitsch . constants    - constant parameters
220432d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
220532d2bbc9SMatthew G. Knepley 
220632d2bbc9SMatthew G. Knepley   Level: intermediate
220732d2bbc9SMatthew G. Knepley 
2208dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
220932d2bbc9SMatthew G. Knepley @*/
2210d71ae5a4SJacob 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[]))
2211d71ae5a4SJacob Faibussowitsch {
221232d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
221432d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
221563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22169566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22176528b96dSMatthew G. Knepley   ds->update[f] = update;
22183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
221932d2bbc9SMatthew G. Knepley }
222032d2bbc9SMatthew G. Knepley 
2221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2222d71ae5a4SJacob Faibussowitsch {
22230c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
222563a3b9bcSJacob 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);
22264f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22273ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22290c2f2876SMatthew G. Knepley }
22300c2f2876SMatthew G. Knepley 
2231d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2232d71ae5a4SJacob Faibussowitsch {
22330c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22346528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22369566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22376528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22390c2f2876SMatthew G. Knepley }
22400c2f2876SMatthew G. Knepley 
2241194d53e6SMatthew G. Knepley /*@C
2242194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2243194d53e6SMatthew G. Knepley 
224420f4b53cSBarry Smith   Not Collective
2245194d53e6SMatthew G. Knepley 
2246194d53e6SMatthew G. Knepley   Input Parameters:
22476528b96dSMatthew G. Knepley + ds - The PetscDS
2248194d53e6SMatthew G. Knepley - f  - The test field number
2249194d53e6SMatthew G. Knepley 
2250194d53e6SMatthew G. Knepley   Output Parameters:
2251194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2252194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2253194d53e6SMatthew G. Knepley 
2254a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2255194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2256194d53e6SMatthew G. Knepley . Nf           - the number of fields
2257a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2258194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2259194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2260194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2261194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2262194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2263194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2264194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2265194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2266194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2267194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2268194d53e6SMatthew G. Knepley . t            - current time
2269194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2270194d53e6SMatthew G. Knepley . n            - unit normal at the current point
227197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
227297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2273194d53e6SMatthew G. Knepley - f0           - output values at the current point
2274194d53e6SMatthew G. Knepley 
2275194d53e6SMatthew G. Knepley   Level: intermediate
2276194d53e6SMatthew G. Knepley 
2277dce8aebaSBarry Smith   Note:
2278a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
227960225df5SJacob Faibussowitsch 
2280a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2281dce8aebaSBarry 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
2282dce8aebaSBarry Smith 
2283dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2284194d53e6SMatthew G. Knepley @*/
2285a4e35b19SJacob 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[]))
2286d71ae5a4SJacob Faibussowitsch {
22876528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22886528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22896528b96dSMatthew G. Knepley 
22902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229263a3b9bcSJacob 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);
22939566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22946528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22956528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22972764a2aaSMatthew G. Knepley }
22982764a2aaSMatthew G. Knepley 
2299194d53e6SMatthew G. Knepley /*@C
2300194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2301194d53e6SMatthew G. Knepley 
230220f4b53cSBarry Smith   Not Collective
2303194d53e6SMatthew G. Knepley 
2304194d53e6SMatthew G. Knepley   Input Parameters:
2305dce8aebaSBarry Smith + ds - The `PetscDS`
2306194d53e6SMatthew G. Knepley . f  - The test field number
2307194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2308194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2309194d53e6SMatthew G. Knepley 
2310a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2311194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2312194d53e6SMatthew G. Knepley . Nf           - the number of fields
2313a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2314194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2315194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2316194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2317194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2318194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2319194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2320194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2321194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2322194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2323194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2324194d53e6SMatthew G. Knepley . t            - current time
2325194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2326194d53e6SMatthew G. Knepley . n            - unit normal at the current point
232797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
232897b6e6e8SMatthew G. Knepley . constants    - constant parameters
2329194d53e6SMatthew G. Knepley - f0           - output values at the current point
2330194d53e6SMatthew G. Knepley 
2331194d53e6SMatthew G. Knepley   Level: intermediate
2332194d53e6SMatthew G. Knepley 
2333dce8aebaSBarry Smith   Note:
2334a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
233560225df5SJacob Faibussowitsch 
2336a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2337dce8aebaSBarry 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
2338dce8aebaSBarry Smith 
2339dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2340194d53e6SMatthew G. Knepley @*/
2341a4e35b19SJacob 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[]))
2342d71ae5a4SJacob Faibussowitsch {
23432764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23446528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
234563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23482764a2aaSMatthew G. Knepley }
23492764a2aaSMatthew G. Knepley 
235027f02ce8SMatthew G. Knepley /*@
2351dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
235227f02ce8SMatthew G. Knepley 
235320f4b53cSBarry Smith   Not Collective
235427f02ce8SMatthew G. Knepley 
235527f02ce8SMatthew G. Knepley   Input Parameter:
2356dce8aebaSBarry Smith . ds - The `PetscDS`
235727f02ce8SMatthew G. Knepley 
235827f02ce8SMatthew G. Knepley   Output Parameter:
235927f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
236027f02ce8SMatthew G. Knepley 
236127f02ce8SMatthew G. Knepley   Level: intermediate
236227f02ce8SMatthew G. Knepley 
2363dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
236427f02ce8SMatthew G. Knepley @*/
2365d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2366d71ae5a4SJacob Faibussowitsch {
236727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23694f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
23709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
237227f02ce8SMatthew G. Knepley }
237327f02ce8SMatthew G. Knepley 
2374194d53e6SMatthew G. Knepley /*@C
2375194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2376194d53e6SMatthew G. Knepley 
237720f4b53cSBarry Smith   Not Collective
2378194d53e6SMatthew G. Knepley 
2379194d53e6SMatthew G. Knepley   Input Parameters:
2380dce8aebaSBarry Smith + ds - The `PetscDS`
2381194d53e6SMatthew G. Knepley . f  - The test field number
2382194d53e6SMatthew G. Knepley - g  - The field number
2383194d53e6SMatthew G. Knepley 
2384194d53e6SMatthew G. Knepley   Output Parameters:
2385194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2386194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2387194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2388194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2389194d53e6SMatthew G. Knepley 
2390a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2391194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2392194d53e6SMatthew G. Knepley . Nf           - the number of fields
2393a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2394194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2395194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2396194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2397194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2398194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2399194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2400194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2401194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2402194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2403194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2404194d53e6SMatthew G. Knepley . t            - current time
24052aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2406194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2407194d53e6SMatthew G. Knepley . n            - normal at the current point
240897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
240997b6e6e8SMatthew G. Knepley . constants    - constant parameters
2410194d53e6SMatthew G. Knepley - g0           - output values at the current point
2411194d53e6SMatthew G. Knepley 
2412194d53e6SMatthew G. Knepley   Level: intermediate
2413194d53e6SMatthew G. Knepley 
2414dce8aebaSBarry Smith   Note:
2415a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
241660225df5SJacob Faibussowitsch 
2417a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2418dce8aebaSBarry 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
2419dce8aebaSBarry Smith 
2420dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2421194d53e6SMatthew G. Knepley @*/
2422a4e35b19SJacob 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[]))
2423d71ae5a4SJacob Faibussowitsch {
24246528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24256528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24266528b96dSMatthew G. Knepley 
24272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
242963a3b9bcSJacob 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);
243063a3b9bcSJacob 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);
24319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24326528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24336528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24346528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24356528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24372764a2aaSMatthew G. Knepley }
24382764a2aaSMatthew G. Knepley 
2439194d53e6SMatthew G. Knepley /*@C
2440194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2441194d53e6SMatthew G. Knepley 
244220f4b53cSBarry Smith   Not Collective
2443194d53e6SMatthew G. Knepley 
2444194d53e6SMatthew G. Knepley   Input Parameters:
24456528b96dSMatthew G. Knepley + ds - The PetscDS
2446194d53e6SMatthew G. Knepley . f  - The test field number
2447194d53e6SMatthew G. Knepley . g  - The field number
2448194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2449194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2450194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2451194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2452194d53e6SMatthew G. Knepley 
2453a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2454194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2455194d53e6SMatthew G. Knepley . Nf           - the number of fields
2456a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2457194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2458194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2459194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2460194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2461194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2462194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2463194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2464194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2465194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2466194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2467194d53e6SMatthew G. Knepley . t            - current time
24682aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2469194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2470194d53e6SMatthew G. Knepley . n            - normal at the current point
247197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
247297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2473194d53e6SMatthew G. Knepley - g0           - output values at the current point
2474194d53e6SMatthew G. Knepley 
2475194d53e6SMatthew G. Knepley   Level: intermediate
2476194d53e6SMatthew G. Knepley 
2477dce8aebaSBarry Smith   Note:
2478a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
247960225df5SJacob Faibussowitsch 
2480a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2481dce8aebaSBarry 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
2482dce8aebaSBarry Smith 
2483dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2484194d53e6SMatthew G. Knepley @*/
2485a4e35b19SJacob 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[]))
2486d71ae5a4SJacob Faibussowitsch {
24872764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24886528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24892764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24902764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24912764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24922764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
249363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
249463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24972764a2aaSMatthew G. Knepley }
24982764a2aaSMatthew G. Knepley 
249927f02ce8SMatthew G. Knepley /*@
250027f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
250127f02ce8SMatthew G. Knepley 
250220f4b53cSBarry Smith   Not Collective
250327f02ce8SMatthew G. Knepley 
250427f02ce8SMatthew G. Knepley   Input Parameter:
2505dce8aebaSBarry Smith . ds - The `PetscDS`
250627f02ce8SMatthew G. Knepley 
250727f02ce8SMatthew G. Knepley   Output Parameter:
250860225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
250927f02ce8SMatthew G. Knepley 
251027f02ce8SMatthew G. Knepley   Level: intermediate
251127f02ce8SMatthew G. Knepley 
2512dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
251327f02ce8SMatthew G. Knepley @*/
2514d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2515d71ae5a4SJacob Faibussowitsch {
251627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25176528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25184f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25199566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
252127f02ce8SMatthew G. Knepley }
252227f02ce8SMatthew G. Knepley 
252327f02ce8SMatthew G. Knepley /*@C
252427f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
252527f02ce8SMatthew G. Knepley 
252620f4b53cSBarry Smith   Not Collective; No Fortran Support
252727f02ce8SMatthew G. Knepley 
252827f02ce8SMatthew G. Knepley   Input Parameters:
2529dce8aebaSBarry Smith + ds - The `PetscDS`
253027f02ce8SMatthew G. Knepley . f  - The test field number
253127f02ce8SMatthew G. Knepley - g  - The field number
253227f02ce8SMatthew G. Knepley 
253327f02ce8SMatthew G. Knepley   Output Parameters:
253427f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
253527f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
253627f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
253727f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
253827f02ce8SMatthew G. Knepley 
2539a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
254027f02ce8SMatthew G. Knepley + dim          - the spatial dimension
254127f02ce8SMatthew G. Knepley . Nf           - the number of fields
254227f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
254327f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
254427f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
254527f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
254627f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
254727f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
254827f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
254927f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
255027f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
255127f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
255227f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
255327f02ce8SMatthew G. Knepley . t            - current time
255427f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
255527f02ce8SMatthew G. Knepley . x            - coordinates of the current point
255627f02ce8SMatthew G. Knepley . n            - normal at the current point
255727f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
255827f02ce8SMatthew G. Knepley . constants    - constant parameters
255927f02ce8SMatthew G. Knepley - g0           - output values at the current point
256027f02ce8SMatthew G. Knepley 
256127f02ce8SMatthew G. Knepley   Level: intermediate
256227f02ce8SMatthew G. Knepley 
2563dce8aebaSBarry Smith   Note:
2564a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
256560225df5SJacob Faibussowitsch 
2566a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2567dce8aebaSBarry 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
2568dce8aebaSBarry Smith 
2569dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
257027f02ce8SMatthew G. Knepley @*/
2571a4e35b19SJacob 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[]))
2572d71ae5a4SJacob Faibussowitsch {
25736528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25746528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25756528b96dSMatthew G. Knepley 
257627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
257863a3b9bcSJacob 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);
257963a3b9bcSJacob 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);
25809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25816528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25826528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25836528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25846528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
258627f02ce8SMatthew G. Knepley }
258727f02ce8SMatthew G. Knepley 
258827f02ce8SMatthew G. Knepley /*@C
258927f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
259027f02ce8SMatthew G. Knepley 
259120f4b53cSBarry Smith   Not Collective; No Fortran Support
259227f02ce8SMatthew G. Knepley 
259327f02ce8SMatthew G. Knepley   Input Parameters:
2594dce8aebaSBarry Smith + ds - The `PetscDS`
259527f02ce8SMatthew G. Knepley . f  - The test field number
259627f02ce8SMatthew G. Knepley . g  - The field number
259727f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
259827f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
259927f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
260027f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
260127f02ce8SMatthew G. Knepley 
2602a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
260327f02ce8SMatthew G. Knepley + dim          - the spatial dimension
260427f02ce8SMatthew G. Knepley . Nf           - the number of fields
260527f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
260627f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
260727f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
260827f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
260927f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
261027f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
261127f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
261227f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
261327f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
261427f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
261527f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
261627f02ce8SMatthew G. Knepley . t            - current time
261727f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
261827f02ce8SMatthew G. Knepley . x            - coordinates of the current point
261927f02ce8SMatthew G. Knepley . n            - normal at the current point
262027f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
262127f02ce8SMatthew G. Knepley . constants    - constant parameters
262227f02ce8SMatthew G. Knepley - g0           - output values at the current point
262327f02ce8SMatthew G. Knepley 
262427f02ce8SMatthew G. Knepley   Level: intermediate
262527f02ce8SMatthew G. Knepley 
2626dce8aebaSBarry Smith   Note:
2627a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
262860225df5SJacob Faibussowitsch 
2629a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2630dce8aebaSBarry 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
2631dce8aebaSBarry Smith 
2632dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
263327f02ce8SMatthew G. Knepley @*/
2634a4e35b19SJacob 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[]))
2635d71ae5a4SJacob Faibussowitsch {
263627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
263827f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
263927f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
264027f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
264127f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
264263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
264363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264627f02ce8SMatthew G. Knepley }
264727f02ce8SMatthew G. Knepley 
26480d3e9b51SMatthew G. Knepley /*@C
2649c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2650c371a6d1SMatthew G. Knepley 
265120f4b53cSBarry Smith   Not Collective
2652c371a6d1SMatthew G. Knepley 
2653c371a6d1SMatthew G. Knepley   Input Parameters:
2654c371a6d1SMatthew G. Knepley + prob - The PetscDS
2655c371a6d1SMatthew G. Knepley - f    - The test field number
2656c371a6d1SMatthew G. Knepley 
2657d8d19677SJose E. Roman   Output Parameters:
2658a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2659a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2660c371a6d1SMatthew G. Knepley 
266120f4b53cSBarry Smith   Calling sequence of `exactSol`:
2662c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2663c371a6d1SMatthew G. Knepley . t   - current time
2664c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2665c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2666a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2667c371a6d1SMatthew G. Knepley - ctx - a user context
2668c371a6d1SMatthew G. Knepley 
2669c371a6d1SMatthew G. Knepley   Level: intermediate
2670c371a6d1SMatthew G. Knepley 
2671dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2672c371a6d1SMatthew G. Knepley @*/
2673d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2674d71ae5a4SJacob Faibussowitsch {
2675c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2676c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
267763a3b9bcSJacob 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);
26789371c9d4SSatish Balay   if (sol) {
26794f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
26809371c9d4SSatish Balay     *sol = prob->exactSol[f];
26819371c9d4SSatish Balay   }
26829371c9d4SSatish Balay   if (ctx) {
26834f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
26849371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26859371c9d4SSatish Balay   }
26863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2687c371a6d1SMatthew G. Knepley }
2688c371a6d1SMatthew G. Knepley 
2689c371a6d1SMatthew G. Knepley /*@C
2690578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2691c371a6d1SMatthew G. Knepley 
269220f4b53cSBarry Smith   Not Collective
2693c371a6d1SMatthew G. Knepley 
2694c371a6d1SMatthew G. Knepley   Input Parameters:
2695dce8aebaSBarry Smith + prob - The `PetscDS`
2696c371a6d1SMatthew G. Knepley . f    - The test field number
269795cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
269820f4b53cSBarry Smith - ctx  - solution context or `NULL`
2699c371a6d1SMatthew G. Knepley 
270020f4b53cSBarry Smith   Calling sequence of `sol`:
2701c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2702c371a6d1SMatthew G. Knepley . t   - current time
2703c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2704c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2705c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2706c371a6d1SMatthew G. Knepley - ctx - a user context
2707c371a6d1SMatthew G. Knepley 
2708c371a6d1SMatthew G. Knepley   Level: intermediate
2709c371a6d1SMatthew G. Knepley 
2710dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2711c371a6d1SMatthew G. Knepley @*/
2712d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2713d71ae5a4SJacob Faibussowitsch {
2714c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2715c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
271663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27179566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27189371c9d4SSatish Balay   if (sol) {
27199371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27209371c9d4SSatish Balay     prob->exactSol[f] = sol;
27219371c9d4SSatish Balay   }
27229371c9d4SSatish Balay   if (ctx) {
27239371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27249371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27259371c9d4SSatish Balay   }
27263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2727c371a6d1SMatthew G. Knepley }
2728c371a6d1SMatthew G. Knepley 
27295638fd0eSMatthew G. Knepley /*@C
2730f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2731f2cacb80SMatthew G. Knepley 
273220f4b53cSBarry Smith   Not Collective
2733f2cacb80SMatthew G. Knepley 
2734f2cacb80SMatthew G. Knepley   Input Parameters:
2735dce8aebaSBarry Smith + prob - The `PetscDS`
2736f2cacb80SMatthew G. Knepley - f    - The test field number
2737f2cacb80SMatthew G. Knepley 
2738d8d19677SJose E. Roman   Output Parameters:
2739a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2740a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2741f2cacb80SMatthew G. Knepley 
274220f4b53cSBarry Smith   Calling sequence of `exactSol`:
2743f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2744f2cacb80SMatthew G. Knepley . t   - current time
2745f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2746f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2747a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2748f2cacb80SMatthew G. Knepley - ctx - a user context
2749f2cacb80SMatthew G. Knepley 
2750f2cacb80SMatthew G. Knepley   Level: intermediate
2751f2cacb80SMatthew G. Knepley 
2752dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2753f2cacb80SMatthew G. Knepley @*/
2754d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2755d71ae5a4SJacob Faibussowitsch {
2756f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2757f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
275863a3b9bcSJacob 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);
27599371c9d4SSatish Balay   if (sol) {
27604f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27619371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27629371c9d4SSatish Balay   }
27639371c9d4SSatish Balay   if (ctx) {
27644f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27659371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27669371c9d4SSatish Balay   }
27673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2768f2cacb80SMatthew G. Knepley }
2769f2cacb80SMatthew G. Knepley 
2770f2cacb80SMatthew G. Knepley /*@C
2771f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2772f2cacb80SMatthew G. Knepley 
277320f4b53cSBarry Smith   Not Collective
2774f2cacb80SMatthew G. Knepley 
2775f2cacb80SMatthew G. Knepley   Input Parameters:
2776dce8aebaSBarry Smith + prob - The `PetscDS`
2777f2cacb80SMatthew G. Knepley . f    - The test field number
2778f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
277920f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2780f2cacb80SMatthew G. Knepley 
278120f4b53cSBarry Smith   Calling sequence of `sol`:
2782f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2783f2cacb80SMatthew G. Knepley . t   - current time
2784f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2785f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2786f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2787f2cacb80SMatthew G. Knepley - ctx - a user context
2788f2cacb80SMatthew G. Knepley 
2789f2cacb80SMatthew G. Knepley   Level: intermediate
2790f2cacb80SMatthew G. Knepley 
2791dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2792f2cacb80SMatthew G. Knepley @*/
2793d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2794d71ae5a4SJacob Faibussowitsch {
2795f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2796f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
279763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27989566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27999371c9d4SSatish Balay   if (sol) {
28009371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28019371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28029371c9d4SSatish Balay   }
28039371c9d4SSatish Balay   if (ctx) {
28049371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28059371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28069371c9d4SSatish Balay   }
28073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2808f2cacb80SMatthew G. Knepley }
2809f2cacb80SMatthew G. Knepley 
2810f2cacb80SMatthew G. Knepley /*@C
281197b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
281297b6e6e8SMatthew G. Knepley 
281320f4b53cSBarry Smith   Not Collective
281497b6e6e8SMatthew G. Knepley 
281597b6e6e8SMatthew G. Knepley   Input Parameter:
2816dce8aebaSBarry Smith . prob - The `PetscDS` object
281797b6e6e8SMatthew G. Knepley 
281897b6e6e8SMatthew G. Knepley   Output Parameters:
281997b6e6e8SMatthew G. Knepley + numConstants - The number of constants
282097b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
282197b6e6e8SMatthew G. Knepley 
282297b6e6e8SMatthew G. Knepley   Level: intermediate
282397b6e6e8SMatthew G. Knepley 
2824dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
282597b6e6e8SMatthew G. Knepley @*/
2826d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2827d71ae5a4SJacob Faibussowitsch {
282897b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
282997b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28309371c9d4SSatish Balay   if (numConstants) {
28314f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
28329371c9d4SSatish Balay     *numConstants = prob->numConstants;
28339371c9d4SSatish Balay   }
28349371c9d4SSatish Balay   if (constants) {
28354f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28369371c9d4SSatish Balay     *constants = prob->constants;
28379371c9d4SSatish Balay   }
28383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
283997b6e6e8SMatthew G. Knepley }
284097b6e6e8SMatthew G. Knepley 
28410d3e9b51SMatthew G. Knepley /*@C
284297b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
284397b6e6e8SMatthew G. Knepley 
284420f4b53cSBarry Smith   Not Collective
284597b6e6e8SMatthew G. Knepley 
284697b6e6e8SMatthew G. Knepley   Input Parameters:
2847dce8aebaSBarry Smith + prob         - The `PetscDS` object
284897b6e6e8SMatthew G. Knepley . numConstants - The number of constants
284997b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
285097b6e6e8SMatthew G. Knepley 
285197b6e6e8SMatthew G. Knepley   Level: intermediate
285297b6e6e8SMatthew G. Knepley 
2853dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
285497b6e6e8SMatthew G. Knepley @*/
2855d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2856d71ae5a4SJacob Faibussowitsch {
285797b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
285897b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285997b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28609566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
286197b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
286297b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28639566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
286420be0f5bSMatthew G. Knepley     } else {
286520be0f5bSMatthew G. Knepley       prob->constants = NULL;
286620be0f5bSMatthew G. Knepley     }
286720be0f5bSMatthew G. Knepley   }
286820be0f5bSMatthew G. Knepley   if (prob->numConstants) {
28694f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28709566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
287197b6e6e8SMatthew G. Knepley   }
28723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
287397b6e6e8SMatthew G. Knepley }
287497b6e6e8SMatthew G. Knepley 
28754cd1e086SMatthew G. Knepley /*@
28764cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28774cd1e086SMatthew G. Knepley 
287820f4b53cSBarry Smith   Not Collective
28794cd1e086SMatthew G. Knepley 
28804cd1e086SMatthew G. Knepley   Input Parameters:
2881dce8aebaSBarry Smith + prob - The `PetscDS` object
28824cd1e086SMatthew G. Knepley - disc - The discretization object
28834cd1e086SMatthew G. Knepley 
28844cd1e086SMatthew G. Knepley   Output Parameter:
28854cd1e086SMatthew G. Knepley . f - The field number
28864cd1e086SMatthew G. Knepley 
28874cd1e086SMatthew G. Knepley   Level: beginner
28884cd1e086SMatthew G. Knepley 
2889dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28904cd1e086SMatthew G. Knepley @*/
2891d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2892d71ae5a4SJacob Faibussowitsch {
28934cd1e086SMatthew G. Knepley   PetscInt g;
28944cd1e086SMatthew G. Knepley 
28954cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28964cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28974f572ea9SToby Isaac   PetscAssertPointer(f, 3);
28984cd1e086SMatthew G. Knepley   *f = -1;
28999371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
29009371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
29019371c9d4SSatish Balay   }
290208401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
29034cd1e086SMatthew G. Knepley   *f = g;
29043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29054cd1e086SMatthew G. Knepley }
29064cd1e086SMatthew G. Knepley 
29074cd1e086SMatthew G. Knepley /*@
29084cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29094cd1e086SMatthew G. Knepley 
291020f4b53cSBarry Smith   Not Collective
29114cd1e086SMatthew G. Knepley 
29124cd1e086SMatthew G. Knepley   Input Parameters:
2913dce8aebaSBarry Smith + prob - The `PetscDS` object
29144cd1e086SMatthew G. Knepley - f    - The field number
29154cd1e086SMatthew G. Knepley 
29164cd1e086SMatthew G. Knepley   Output Parameter:
29174cd1e086SMatthew G. Knepley . size - The size
29184cd1e086SMatthew G. Knepley 
29194cd1e086SMatthew G. Knepley   Level: beginner
29204cd1e086SMatthew G. Knepley 
2921dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29224cd1e086SMatthew G. Knepley @*/
2923d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2924d71ae5a4SJacob Faibussowitsch {
29254cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29264cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29274f572ea9SToby Isaac   PetscAssertPointer(size, 3);
292863a3b9bcSJacob 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);
29299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2930d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29324cd1e086SMatthew G. Knepley }
29334cd1e086SMatthew G. Knepley 
2934bc4ae4beSMatthew G. Knepley /*@
2935bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2936bc4ae4beSMatthew G. Knepley 
293720f4b53cSBarry Smith   Not Collective
2938bc4ae4beSMatthew G. Knepley 
2939bc4ae4beSMatthew G. Knepley   Input Parameters:
2940dce8aebaSBarry Smith + prob - The `PetscDS` object
2941bc4ae4beSMatthew G. Knepley - f    - The field number
2942bc4ae4beSMatthew G. Knepley 
2943bc4ae4beSMatthew G. Knepley   Output Parameter:
2944bc4ae4beSMatthew G. Knepley . off - The offset
2945bc4ae4beSMatthew G. Knepley 
2946bc4ae4beSMatthew G. Knepley   Level: beginner
2947bc4ae4beSMatthew G. Knepley 
2948dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2949bc4ae4beSMatthew G. Knepley @*/
2950d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2951d71ae5a4SJacob Faibussowitsch {
29524cd1e086SMatthew G. Knepley   PetscInt size, g;
29532764a2aaSMatthew G. Knepley 
29542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29552764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29564f572ea9SToby Isaac   PetscAssertPointer(off, 3);
295763a3b9bcSJacob 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);
29582764a2aaSMatthew G. Knepley   *off = 0;
29592764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29609566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29614cd1e086SMatthew G. Knepley     *off += size;
29622764a2aaSMatthew G. Knepley   }
29633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29642764a2aaSMatthew G. Knepley }
29652764a2aaSMatthew G. Knepley 
2966bc4ae4beSMatthew G. Knepley /*@
29675fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29685fedec97SMatthew G. Knepley 
296920f4b53cSBarry Smith   Not Collective
29705fedec97SMatthew G. Knepley 
29715fedec97SMatthew G. Knepley   Input Parameters:
297260225df5SJacob Faibussowitsch + ds - The `PetscDS` object
29735fedec97SMatthew G. Knepley - f  - The field number
29745fedec97SMatthew G. Knepley 
29755fedec97SMatthew G. Knepley   Output Parameter:
29765fedec97SMatthew G. Knepley . off - The offset
29775fedec97SMatthew G. Knepley 
29785fedec97SMatthew G. Knepley   Level: beginner
29795fedec97SMatthew G. Knepley 
2980dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29815fedec97SMatthew G. Knepley @*/
2982d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2983d71ae5a4SJacob Faibussowitsch {
29845fedec97SMatthew G. Knepley   PetscInt size, g;
29855fedec97SMatthew G. Knepley 
29865fedec97SMatthew G. Knepley   PetscFunctionBegin;
29875fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
29884f572ea9SToby Isaac   PetscAssertPointer(off, 3);
298963a3b9bcSJacob 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);
29905fedec97SMatthew G. Knepley   *off = 0;
29915fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29925fedec97SMatthew G. Knepley     PetscBool cohesive;
29935fedec97SMatthew G. Knepley 
29949566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29959566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29965fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29975fedec97SMatthew G. Knepley   }
29983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29995fedec97SMatthew G. Knepley }
30005fedec97SMatthew G. Knepley 
30015fedec97SMatthew G. Knepley /*@
300247e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3003bc4ae4beSMatthew G. Knepley 
300420f4b53cSBarry Smith   Not Collective
3005bc4ae4beSMatthew G. Knepley 
300647e57110SSander Arens   Input Parameter:
3007dce8aebaSBarry Smith . prob - The `PetscDS` object
3008bc4ae4beSMatthew G. Knepley 
3009bc4ae4beSMatthew G. Knepley   Output Parameter:
301047e57110SSander Arens . dimensions - The number of dimensions
3011bc4ae4beSMatthew G. Knepley 
3012bc4ae4beSMatthew G. Knepley   Level: beginner
3013bc4ae4beSMatthew G. Knepley 
3014dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3015bc4ae4beSMatthew G. Knepley @*/
3016d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3017d71ae5a4SJacob Faibussowitsch {
30182764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30192764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30209566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30214f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
302247e57110SSander Arens   *dimensions = prob->Nb;
30233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30246ce16762SMatthew G. Knepley }
302547e57110SSander Arens 
302647e57110SSander Arens /*@
302747e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
302847e57110SSander Arens 
302920f4b53cSBarry Smith   Not Collective
303047e57110SSander Arens 
303147e57110SSander Arens   Input Parameter:
3032dce8aebaSBarry Smith . prob - The `PetscDS` object
303347e57110SSander Arens 
303447e57110SSander Arens   Output Parameter:
303547e57110SSander Arens . components - The number of components
303647e57110SSander Arens 
303747e57110SSander Arens   Level: beginner
303847e57110SSander Arens 
3039dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
304047e57110SSander Arens @*/
3041d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3042d71ae5a4SJacob Faibussowitsch {
304347e57110SSander Arens   PetscFunctionBegin;
304447e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30459566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30464f572ea9SToby Isaac   PetscAssertPointer(components, 2);
304747e57110SSander Arens   *components = prob->Nc;
30483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30496ce16762SMatthew G. Knepley }
30506ce16762SMatthew G. Knepley 
30516ce16762SMatthew G. Knepley /*@
30526ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30536ce16762SMatthew G. Knepley 
305420f4b53cSBarry Smith   Not Collective
30556ce16762SMatthew G. Knepley 
30566ce16762SMatthew G. Knepley   Input Parameters:
3057dce8aebaSBarry Smith + prob - The `PetscDS` object
30586ce16762SMatthew G. Knepley - f    - The field number
30596ce16762SMatthew G. Knepley 
30606ce16762SMatthew G. Knepley   Output Parameter:
30616ce16762SMatthew G. Knepley . off - The offset
30626ce16762SMatthew G. Knepley 
30636ce16762SMatthew G. Knepley   Level: beginner
30646ce16762SMatthew G. Knepley 
3065dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30666ce16762SMatthew G. Knepley @*/
3067d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3068d71ae5a4SJacob Faibussowitsch {
30696ce16762SMatthew G. Knepley   PetscFunctionBegin;
30706ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30714f572ea9SToby Isaac   PetscAssertPointer(off, 3);
307263a3b9bcSJacob 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);
30739566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
307447e57110SSander Arens   *off = prob->off[f];
30753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30762764a2aaSMatthew G. Knepley }
30772764a2aaSMatthew G. Knepley 
3078194d53e6SMatthew G. Knepley /*@
3079194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3080194d53e6SMatthew G. Knepley 
308120f4b53cSBarry Smith   Not Collective
3082194d53e6SMatthew G. Knepley 
3083194d53e6SMatthew G. Knepley   Input Parameter:
3084dce8aebaSBarry Smith . prob - The `PetscDS` object
3085194d53e6SMatthew G. Knepley 
3086194d53e6SMatthew G. Knepley   Output Parameter:
3087194d53e6SMatthew G. Knepley . offsets - The offsets
3088194d53e6SMatthew G. Knepley 
3089194d53e6SMatthew G. Knepley   Level: beginner
3090194d53e6SMatthew G. Knepley 
3091dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3092194d53e6SMatthew G. Knepley @*/
3093d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3094d71ae5a4SJacob Faibussowitsch {
3095194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3096194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30974f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
30989566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3099194d53e6SMatthew G. Knepley   *offsets = prob->off;
31003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3101194d53e6SMatthew G. Knepley }
3102194d53e6SMatthew G. Knepley 
3103194d53e6SMatthew G. Knepley /*@
3104194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3105194d53e6SMatthew G. Knepley 
310620f4b53cSBarry Smith   Not Collective
3107194d53e6SMatthew G. Knepley 
3108194d53e6SMatthew G. Knepley   Input Parameter:
3109dce8aebaSBarry Smith . prob - The `PetscDS` object
3110194d53e6SMatthew G. Knepley 
3111194d53e6SMatthew G. Knepley   Output Parameter:
3112194d53e6SMatthew G. Knepley . offsets - The offsets
3113194d53e6SMatthew G. Knepley 
3114194d53e6SMatthew G. Knepley   Level: beginner
3115194d53e6SMatthew G. Knepley 
3116dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3117194d53e6SMatthew G. Knepley @*/
3118d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3119d71ae5a4SJacob Faibussowitsch {
3120194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3121194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31224f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
31239566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3124194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3126194d53e6SMatthew G. Knepley }
3127194d53e6SMatthew G. Knepley 
31289ee2af8cSMatthew G. Knepley /*@
31299ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31309ee2af8cSMatthew G. Knepley 
313120f4b53cSBarry Smith   Not Collective
31329ee2af8cSMatthew G. Knepley 
31339ee2af8cSMatthew G. Knepley   Input Parameters:
3134dce8aebaSBarry Smith + ds - The `PetscDS` object
31359ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31369ee2af8cSMatthew G. Knepley 
31379ee2af8cSMatthew G. Knepley   Output Parameter:
31389ee2af8cSMatthew G. Knepley . offsets - The offsets
31399ee2af8cSMatthew G. Knepley 
31409ee2af8cSMatthew G. Knepley   Level: beginner
31419ee2af8cSMatthew G. Knepley 
3142dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31439ee2af8cSMatthew G. Knepley @*/
3144d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3145d71ae5a4SJacob Faibussowitsch {
31469ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31479ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31484f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
314928b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
315063a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31529ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31549ee2af8cSMatthew G. Knepley }
31559ee2af8cSMatthew G. Knepley 
31569ee2af8cSMatthew G. Knepley /*@
31579ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31589ee2af8cSMatthew G. Knepley 
315920f4b53cSBarry Smith   Not Collective
31609ee2af8cSMatthew G. Knepley 
31619ee2af8cSMatthew G. Knepley   Input Parameters:
3162dce8aebaSBarry Smith + ds - The `PetscDS` object
31639ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31649ee2af8cSMatthew G. Knepley 
31659ee2af8cSMatthew G. Knepley   Output Parameter:
31669ee2af8cSMatthew G. Knepley . offsets - The offsets
31679ee2af8cSMatthew G. Knepley 
31689ee2af8cSMatthew G. Knepley   Level: beginner
31699ee2af8cSMatthew G. Knepley 
3170dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31719ee2af8cSMatthew G. Knepley @*/
3172d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3173d71ae5a4SJacob Faibussowitsch {
31749ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31759ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31764f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
317728b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
317863a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31799566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31809ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31829ee2af8cSMatthew G. Knepley }
31839ee2af8cSMatthew G. Knepley 
318468c9edb9SMatthew G. Knepley /*@C
318568c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
318668c9edb9SMatthew G. Knepley 
318720f4b53cSBarry Smith   Not Collective
318868c9edb9SMatthew G. Knepley 
318968c9edb9SMatthew G. Knepley   Input Parameter:
3190dce8aebaSBarry Smith . prob - The `PetscDS` object
319168c9edb9SMatthew G. Knepley 
3192ef0bb6c7SMatthew G. Knepley   Output Parameter:
3193ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
319468c9edb9SMatthew G. Knepley 
319568c9edb9SMatthew G. Knepley   Level: intermediate
319668c9edb9SMatthew G. Knepley 
3197dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
319868c9edb9SMatthew G. Knepley @*/
3199d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3200d71ae5a4SJacob Faibussowitsch {
32012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32022764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32034f572ea9SToby Isaac   PetscAssertPointer(T, 2);
32049566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3205ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32072764a2aaSMatthew G. Knepley }
32082764a2aaSMatthew G. Knepley 
320968c9edb9SMatthew G. Knepley /*@C
32104d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
321168c9edb9SMatthew G. Knepley 
321220f4b53cSBarry Smith   Not Collective
321368c9edb9SMatthew G. Knepley 
321468c9edb9SMatthew G. Knepley   Input Parameter:
3215dce8aebaSBarry Smith . prob - The `PetscDS` object
321668c9edb9SMatthew G. Knepley 
3217ef0bb6c7SMatthew G. Knepley   Output Parameter:
3218a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
321968c9edb9SMatthew G. Knepley 
322068c9edb9SMatthew G. Knepley   Level: intermediate
322168c9edb9SMatthew G. Knepley 
3222dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
322368c9edb9SMatthew G. Knepley @*/
3224d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3225d71ae5a4SJacob Faibussowitsch {
32262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32272764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32284f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
32299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3230ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32322764a2aaSMatthew G. Knepley }
32332764a2aaSMatthew G. Knepley 
3234d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3235d71ae5a4SJacob Faibussowitsch {
32362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32372764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32399371c9d4SSatish Balay   if (u) {
32404f572ea9SToby Isaac     PetscAssertPointer(u, 2);
32419371c9d4SSatish Balay     *u = prob->u;
32429371c9d4SSatish Balay   }
32439371c9d4SSatish Balay   if (u_t) {
32444f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
32459371c9d4SSatish Balay     *u_t = prob->u_t;
32469371c9d4SSatish Balay   }
32479371c9d4SSatish Balay   if (u_x) {
32484f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
32499371c9d4SSatish Balay     *u_x = prob->u_x;
32509371c9d4SSatish Balay   }
32513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32522764a2aaSMatthew G. Knepley }
32532764a2aaSMatthew G. Knepley 
3254d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3255d71ae5a4SJacob Faibussowitsch {
32562764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32572764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32589566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32599371c9d4SSatish Balay   if (f0) {
32604f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
32619371c9d4SSatish Balay     *f0 = prob->f0;
32629371c9d4SSatish Balay   }
32639371c9d4SSatish Balay   if (f1) {
32644f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
32659371c9d4SSatish Balay     *f1 = prob->f1;
32669371c9d4SSatish Balay   }
32679371c9d4SSatish Balay   if (g0) {
32684f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
32699371c9d4SSatish Balay     *g0 = prob->g0;
32709371c9d4SSatish Balay   }
32719371c9d4SSatish Balay   if (g1) {
32724f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
32739371c9d4SSatish Balay     *g1 = prob->g1;
32749371c9d4SSatish Balay   }
32759371c9d4SSatish Balay   if (g2) {
32764f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
32779371c9d4SSatish Balay     *g2 = prob->g2;
32789371c9d4SSatish Balay   }
32799371c9d4SSatish Balay   if (g3) {
32804f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
32819371c9d4SSatish Balay     *g3 = prob->g3;
32829371c9d4SSatish Balay   }
32833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32842764a2aaSMatthew G. Knepley }
32852764a2aaSMatthew G. Knepley 
3286d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3287d71ae5a4SJacob Faibussowitsch {
32882764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32892764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32909566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32919371c9d4SSatish Balay   if (x) {
32924f572ea9SToby Isaac     PetscAssertPointer(x, 2);
32939371c9d4SSatish Balay     *x = prob->x;
32949371c9d4SSatish Balay   }
32959371c9d4SSatish Balay   if (basisReal) {
32964f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
32979371c9d4SSatish Balay     *basisReal = prob->basisReal;
32989371c9d4SSatish Balay   }
32999371c9d4SSatish Balay   if (basisDerReal) {
33004f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
33019371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
33029371c9d4SSatish Balay   }
33039371c9d4SSatish Balay   if (testReal) {
33044f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
33059371c9d4SSatish Balay     *testReal = prob->testReal;
33069371c9d4SSatish Balay   }
33079371c9d4SSatish Balay   if (testDerReal) {
33084f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
33099371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33109371c9d4SSatish Balay   }
33113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33122764a2aaSMatthew G. Knepley }
33132764a2aaSMatthew G. Knepley 
331458ebd649SToby Isaac /*@C
3315a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
331658ebd649SToby Isaac 
331720f4b53cSBarry Smith   Collective
3318783e2ec8SMatthew G. Knepley 
331958ebd649SToby Isaac   Input Parameters:
332058ebd649SToby Isaac + ds       - The PetscDS object
3321dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
332258ebd649SToby Isaac . name     - The BC name
332345480ffeSMatthew G. Knepley . label    - The label defining constrained points
3324dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
332545480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
332658ebd649SToby Isaac . field    - The field to constrain
332745480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
332858ebd649SToby Isaac . comps    - An array of constrained component numbers
332958ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3330a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
333158ebd649SToby Isaac - ctx      - An optional user context for bcFunc
333258ebd649SToby Isaac 
33332fe279fdSBarry Smith   Output Parameter:
333460225df5SJacob Faibussowitsch . bd - The boundary number
333545480ffeSMatthew G. Knepley 
333658ebd649SToby Isaac   Options Database Keys:
333758ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
333858ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
333958ebd649SToby Isaac 
3340dce8aebaSBarry Smith   Level: developer
3341dce8aebaSBarry Smith 
334256cf3b9cSMatthew G. Knepley   Note:
3343a4e35b19SJacob 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\:
334456cf3b9cSMatthew G. Knepley 
334520f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
334656cf3b9cSMatthew G. Knepley 
3347a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3348dce8aebaSBarry Smith .vb
334920f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3350dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3351dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3352dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3353dce8aebaSBarry Smith .ve
335456cf3b9cSMatthew G. Knepley + dim - the spatial dimension
335556cf3b9cSMatthew G. Knepley . Nf - the number of fields
335656cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
335756cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
335856cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
335956cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
336056cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
336156cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
336256cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
336356cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
336456cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
336556cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
336656cf3b9cSMatthew G. Knepley . t - current time
336756cf3b9cSMatthew G. Knepley . x - coordinates of the current point
336856cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
336956cf3b9cSMatthew G. Knepley . constants - constant parameters
337056cf3b9cSMatthew G. Knepley - bcval - output values at the current point
337156cf3b9cSMatthew G. Knepley 
3372a4e35b19SJacob Faibussowitsch   Notes:
3373a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3374a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3375a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3376a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3377a4e35b19SJacob Faibussowitsch 
3378dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
337958ebd649SToby Isaac @*/
3380d71ae5a4SJacob 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)
3381d71ae5a4SJacob Faibussowitsch {
338245480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
338345480ffeSMatthew G. Knepley   PetscInt    n    = 0;
338445480ffeSMatthew G. Knepley   const char *lname;
338558ebd649SToby Isaac 
338658ebd649SToby Isaac   PetscFunctionBegin;
338758ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3388783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
33894f572ea9SToby Isaac   PetscAssertPointer(name, 3);
339045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
339145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
339245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
339345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3394dce9da9cSMatthew 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);
3395d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3396d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3397d57bb9dbSMatthew G. Knepley     PetscInt  c;
3398d57bb9dbSMatthew G. Knepley 
33999566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
340063a3b9bcSJacob 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);
3401d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
34021dca8a05SBarry 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);
3403d57bb9dbSMatthew G. Knepley     }
3404d57bb9dbSMatthew G. Knepley   }
34059566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34069566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34079566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34099566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34109566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34119566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34129566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34139566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34149566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3415f971fd6bSMatthew G. Knepley   b->type   = type;
341645480ffeSMatthew G. Knepley   b->label  = label;
341745480ffeSMatthew G. Knepley   b->Nv     = Nv;
341858ebd649SToby Isaac   b->field  = field;
341945480ffeSMatthew G. Knepley   b->Nc     = Nc;
342058ebd649SToby Isaac   b->func   = bcFunc;
342156cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
342258ebd649SToby Isaac   b->ctx    = ctx;
342345480ffeSMatthew G. Knepley   b->next   = NULL;
342445480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
342545480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
342645480ffeSMatthew G. Knepley   while (head) {
342745480ffeSMatthew G. Knepley     if (!head->next) {
342845480ffeSMatthew G. Knepley       head->next = b;
342945480ffeSMatthew G. Knepley       head       = b;
343045480ffeSMatthew G. Knepley     }
343145480ffeSMatthew G. Knepley     head = head->next;
343245480ffeSMatthew G. Knepley     ++n;
343345480ffeSMatthew G. Knepley   }
34349371c9d4SSatish Balay   if (bd) {
34354f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
34369371c9d4SSatish Balay     *bd = n;
34379371c9d4SSatish Balay   }
34383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
343945480ffeSMatthew G. Knepley }
344045480ffeSMatthew G. Knepley 
3441a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
344245480ffeSMatthew G. Knepley /*@C
3443a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
344445480ffeSMatthew G. Knepley 
344520f4b53cSBarry Smith   Collective
344645480ffeSMatthew G. Knepley 
344745480ffeSMatthew G. Knepley   Input Parameters:
3448dce8aebaSBarry Smith + ds       - The `PetscDS` object
3449dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
345045480ffeSMatthew G. Knepley . name     - The BC name
345145480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3452dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
345345480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
345445480ffeSMatthew G. Knepley . field    - The field to constrain
345545480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
345645480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
345745480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3458a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
345945480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
346045480ffeSMatthew G. Knepley 
34612fe279fdSBarry Smith   Output Parameter:
346260225df5SJacob Faibussowitsch . bd - The boundary number
346345480ffeSMatthew G. Knepley 
346445480ffeSMatthew G. Knepley   Options Database Keys:
346545480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
346645480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
346745480ffeSMatthew G. Knepley 
346820f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3469dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3470dce8aebaSBarry Smith .vb
347120f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3472dce8aebaSBarry Smith .ve
3473dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3474dce8aebaSBarry Smith .vb
347520f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3476dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3477dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3478dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3479dce8aebaSBarry Smith .ve
348045480ffeSMatthew G. Knepley + dim - the spatial dimension
348145480ffeSMatthew G. Knepley . Nf - the number of fields
348245480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
348345480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
348445480ffeSMatthew G. Knepley . u - each field evaluated at the current point
348545480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
348645480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
348745480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
348845480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
348945480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
349045480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
349145480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
349245480ffeSMatthew G. Knepley . t - current time
349345480ffeSMatthew G. Knepley . x - coordinates of the current point
349445480ffeSMatthew G. Knepley . numConstants - number of constant parameters
349545480ffeSMatthew G. Knepley . constants - constant parameters
349645480ffeSMatthew G. Knepley - bcval - output values at the current point
349745480ffeSMatthew G. Knepley 
349845480ffeSMatthew G. Knepley   Level: developer
349945480ffeSMatthew G. Knepley 
3500a4e35b19SJacob Faibussowitsch   Notes:
3501a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3502a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3503a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3504a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3505a4e35b19SJacob Faibussowitsch 
3506dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3507dce8aebaSBarry Smith 
3508dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
350945480ffeSMatthew G. Knepley @*/
3510d71ae5a4SJacob 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)
3511d71ae5a4SJacob Faibussowitsch {
351245480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
351345480ffeSMatthew G. Knepley   PetscInt   n    = 0;
351445480ffeSMatthew G. Knepley 
351545480ffeSMatthew G. Knepley   PetscFunctionBegin;
351645480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
351745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
35184f572ea9SToby Isaac   PetscAssertPointer(name, 3);
35194f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
352045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
352145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
352245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35239566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35249566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35279566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35289566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35309566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35319566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
353245480ffeSMatthew G. Knepley   b->type   = type;
353345480ffeSMatthew G. Knepley   b->label  = NULL;
353445480ffeSMatthew G. Knepley   b->Nv     = Nv;
353545480ffeSMatthew G. Knepley   b->field  = field;
353645480ffeSMatthew G. Knepley   b->Nc     = Nc;
353745480ffeSMatthew G. Knepley   b->func   = bcFunc;
353845480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
353945480ffeSMatthew G. Knepley   b->ctx    = ctx;
354045480ffeSMatthew G. Knepley   b->next   = NULL;
354145480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
354245480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
354345480ffeSMatthew G. Knepley   while (head) {
354445480ffeSMatthew G. Knepley     if (!head->next) {
354545480ffeSMatthew G. Knepley       head->next = b;
354645480ffeSMatthew G. Knepley       head       = b;
354745480ffeSMatthew G. Knepley     }
354845480ffeSMatthew G. Knepley     head = head->next;
354945480ffeSMatthew G. Knepley     ++n;
355045480ffeSMatthew G. Knepley   }
35519371c9d4SSatish Balay   if (bd) {
35524f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
35539371c9d4SSatish Balay     *bd = n;
35549371c9d4SSatish Balay   }
35553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355658ebd649SToby Isaac }
355758ebd649SToby Isaac 
3558b67eacb3SMatthew G. Knepley /*@C
3559a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3560b67eacb3SMatthew G. Knepley 
3561b67eacb3SMatthew G. Knepley   Input Parameters:
3562dce8aebaSBarry Smith + ds       - The `PetscDS` object
3563b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3564dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3565b67eacb3SMatthew G. Knepley . name     - The BC name
356645480ffeSMatthew G. Knepley . label    - The label defining constrained points
3567dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
356845480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3569b67eacb3SMatthew G. Knepley . field    - The field to constrain
357045480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3571b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3572b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3573a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3574b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3575b67eacb3SMatthew G. Knepley 
3576b67eacb3SMatthew G. Knepley   Level: developer
3577b67eacb3SMatthew G. Knepley 
3578a4e35b19SJacob Faibussowitsch   Notes:
3579a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3580a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3581a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3582a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3583a4e35b19SJacob Faibussowitsch 
3584dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3585dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3586dce8aebaSBarry Smith 
3587dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3588b67eacb3SMatthew G. Knepley @*/
3589d71ae5a4SJacob 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)
3590d71ae5a4SJacob Faibussowitsch {
3591b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3592b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3593b67eacb3SMatthew G. Knepley 
3594b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3595b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3596b67eacb3SMatthew G. Knepley   while (b) {
3597b67eacb3SMatthew G. Knepley     if (n == bd) break;
3598b67eacb3SMatthew G. Knepley     b = b->next;
3599b67eacb3SMatthew G. Knepley     ++n;
3600b67eacb3SMatthew G. Knepley   }
360163a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3602b67eacb3SMatthew G. Knepley   if (name) {
36039566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36049566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3605b67eacb3SMatthew G. Knepley   }
3606b67eacb3SMatthew G. Knepley   b->type = type;
360745480ffeSMatthew G. Knepley   if (label) {
360845480ffeSMatthew G. Knepley     const char *name;
360945480ffeSMatthew G. Knepley 
361045480ffeSMatthew G. Knepley     b->label = label;
36119566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36129566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
36139566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
361445480ffeSMatthew G. Knepley   }
361545480ffeSMatthew G. Knepley   if (Nv >= 0) {
361645480ffeSMatthew G. Knepley     b->Nv = Nv;
36179566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36189566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
36199566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
362045480ffeSMatthew G. Knepley   }
362145480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
362245480ffeSMatthew G. Knepley   if (Nc >= 0) {
362345480ffeSMatthew G. Knepley     b->Nc = Nc;
36249566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36259566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36269566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
362745480ffeSMatthew G. Knepley   }
362845480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
362945480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
363045480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3632b67eacb3SMatthew G. Knepley }
3633b67eacb3SMatthew G. Knepley 
363458ebd649SToby Isaac /*@
363558ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
363658ebd649SToby Isaac 
36372fe279fdSBarry Smith   Input Parameter:
3638dce8aebaSBarry Smith . ds - The `PetscDS` object
363958ebd649SToby Isaac 
36402fe279fdSBarry Smith   Output Parameter:
364158ebd649SToby Isaac . numBd - The number of BC
364258ebd649SToby Isaac 
364358ebd649SToby Isaac   Level: intermediate
364458ebd649SToby Isaac 
3645dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
364658ebd649SToby Isaac @*/
3647d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3648d71ae5a4SJacob Faibussowitsch {
364958ebd649SToby Isaac   DSBoundary b = ds->boundary;
365058ebd649SToby Isaac 
365158ebd649SToby Isaac   PetscFunctionBegin;
365258ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
36534f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
365458ebd649SToby Isaac   *numBd = 0;
36559371c9d4SSatish Balay   while (b) {
36569371c9d4SSatish Balay     ++(*numBd);
36579371c9d4SSatish Balay     b = b->next;
36589371c9d4SSatish Balay   }
36593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
366058ebd649SToby Isaac }
366158ebd649SToby Isaac 
366258ebd649SToby Isaac /*@C
36639a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
366458ebd649SToby Isaac 
366558ebd649SToby Isaac   Input Parameters:
3666dce8aebaSBarry Smith + ds - The `PetscDS` object
366758ebd649SToby Isaac - bd - The BC number
366858ebd649SToby Isaac 
366958ebd649SToby Isaac   Output Parameters:
3670dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3671dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
367258ebd649SToby Isaac . name   - The BC name
367345480ffeSMatthew G. Knepley . label  - The label defining constrained points
3674dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
367545480ffeSMatthew G. Knepley . values - An array of ids for constrained points
367658ebd649SToby Isaac . field  - The field to constrain
367745480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
367858ebd649SToby Isaac . comps  - An array of constrained component numbers
367960225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
368060225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
368158ebd649SToby Isaac - ctx    - An optional user context for bcFunc
368258ebd649SToby Isaac 
368358ebd649SToby Isaac   Options Database Keys:
368458ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
368558ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
368658ebd649SToby Isaac 
368758ebd649SToby Isaac   Level: developer
368858ebd649SToby Isaac 
3689dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
369058ebd649SToby Isaac @*/
3691d71ae5a4SJacob 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)
3692d71ae5a4SJacob Faibussowitsch {
369358ebd649SToby Isaac   DSBoundary b = ds->boundary;
369458ebd649SToby Isaac   PetscInt   n = 0;
369558ebd649SToby Isaac 
369658ebd649SToby Isaac   PetscFunctionBegin;
369758ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
369858ebd649SToby Isaac   while (b) {
369958ebd649SToby Isaac     if (n == bd) break;
370058ebd649SToby Isaac     b = b->next;
370158ebd649SToby Isaac     ++n;
370258ebd649SToby Isaac   }
370363a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
370445480ffeSMatthew G. Knepley   if (wf) {
37054f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
370645480ffeSMatthew G. Knepley     *wf = b->wf;
370745480ffeSMatthew G. Knepley   }
3708f971fd6bSMatthew G. Knepley   if (type) {
37094f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3710f971fd6bSMatthew G. Knepley     *type = b->type;
371158ebd649SToby Isaac   }
371258ebd649SToby Isaac   if (name) {
37134f572ea9SToby Isaac     PetscAssertPointer(name, 5);
371458ebd649SToby Isaac     *name = b->name;
371558ebd649SToby Isaac   }
371645480ffeSMatthew G. Knepley   if (label) {
37174f572ea9SToby Isaac     PetscAssertPointer(label, 6);
371845480ffeSMatthew G. Knepley     *label = b->label;
371945480ffeSMatthew G. Knepley   }
372045480ffeSMatthew G. Knepley   if (Nv) {
37214f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
372245480ffeSMatthew G. Knepley     *Nv = b->Nv;
372345480ffeSMatthew G. Knepley   }
372445480ffeSMatthew G. Knepley   if (values) {
37254f572ea9SToby Isaac     PetscAssertPointer(values, 8);
372645480ffeSMatthew G. Knepley     *values = b->values;
372758ebd649SToby Isaac   }
372858ebd649SToby Isaac   if (field) {
37294f572ea9SToby Isaac     PetscAssertPointer(field, 9);
373058ebd649SToby Isaac     *field = b->field;
373158ebd649SToby Isaac   }
373245480ffeSMatthew G. Knepley   if (Nc) {
37334f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
373445480ffeSMatthew G. Knepley     *Nc = b->Nc;
373558ebd649SToby Isaac   }
373658ebd649SToby Isaac   if (comps) {
37374f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
373858ebd649SToby Isaac     *comps = b->comps;
373958ebd649SToby Isaac   }
374058ebd649SToby Isaac   if (func) {
37414f572ea9SToby Isaac     PetscAssertPointer(func, 12);
374258ebd649SToby Isaac     *func = b->func;
374358ebd649SToby Isaac   }
374456cf3b9cSMatthew G. Knepley   if (func_t) {
37454f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
374656cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
374756cf3b9cSMatthew G. Knepley   }
374858ebd649SToby Isaac   if (ctx) {
37494f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
375058ebd649SToby Isaac     *ctx = b->ctx;
375158ebd649SToby Isaac   }
37523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375358ebd649SToby Isaac }
375458ebd649SToby Isaac 
375510af620dSMatthew G. Knepley /*@
375610af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
375710af620dSMatthew G. Knepley 
375810af620dSMatthew G. Knepley   Not Collective
375910af620dSMatthew G. Knepley 
376010af620dSMatthew G. Knepley   Input Parameters:
376110af620dSMatthew G. Knepley + ds - The source `PetscDS` object
376210af620dSMatthew G. Knepley - dm - The `DM` holding labels
376310af620dSMatthew G. Knepley 
376410af620dSMatthew G. Knepley   Level: intermediate
376510af620dSMatthew G. Knepley 
376610af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
376710af620dSMatthew G. Knepley @*/
376810af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
376910af620dSMatthew G. Knepley {
377010af620dSMatthew G. Knepley   DSBoundary b;
377110af620dSMatthew G. Knepley 
377210af620dSMatthew G. Knepley   PetscFunctionBegin;
377310af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
377410af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
377510af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
377610af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
377710af620dSMatthew G. Knepley   }
377810af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
377910af620dSMatthew G. Knepley }
378010af620dSMatthew G. Knepley 
3781d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3782d71ae5a4SJacob Faibussowitsch {
378345480ffeSMatthew G. Knepley   PetscFunctionBegin;
37849566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37859566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37869566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37879566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37889566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
378945480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
379045480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
379145480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37929566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37939566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
379445480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
379545480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37979566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
379845480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
379945480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
380045480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
38013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
380245480ffeSMatthew G. Knepley }
380345480ffeSMatthew G. Knepley 
38049252d075SMatthew G. Knepley /*@
38059252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
38069252d075SMatthew G. Knepley 
380720f4b53cSBarry Smith   Not Collective
38089252d075SMatthew G. Knepley 
380936951cb5SMatthew G. Knepley   Input Parameters:
3810dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3811dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
381236951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
38139252d075SMatthew G. Knepley 
38149252d075SMatthew G. Knepley   Output Parameter:
3815dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
38169252d075SMatthew G. Knepley 
38179252d075SMatthew G. Knepley   Level: intermediate
38189252d075SMatthew G. Knepley 
3819dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38209252d075SMatthew G. Knepley @*/
3821d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3822d71ae5a4SJacob Faibussowitsch {
382345480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3824dff059c6SToby Isaac 
3825dff059c6SToby Isaac   PetscFunctionBegin;
382636951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
382736951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
38283ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
38299566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
3830f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
383136951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3832dff059c6SToby Isaac     DSBoundary bNew;
383336951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3834dff059c6SToby Isaac 
383536951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
383636951cb5SMatthew G. Knepley       PetscInt f;
383736951cb5SMatthew G. Knepley 
38389371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
38399371c9d4SSatish Balay         if (b->field == fields[f]) break;
384036951cb5SMatthew G. Knepley       if (f == numFields) continue;
384136951cb5SMatthew G. Knepley       fieldNew = f;
384236951cb5SMatthew G. Knepley     }
38439566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
384436951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3845dff059c6SToby Isaac     *lastnext   = bNew;
3846f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
3847dff059c6SToby Isaac   }
38483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3849dff059c6SToby Isaac }
3850dff059c6SToby Isaac 
38516c1eb96dSMatthew G. Knepley /*@
3852dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
385345480ffeSMatthew G. Knepley 
385420f4b53cSBarry Smith   Not Collective
385545480ffeSMatthew G. Knepley 
385645480ffeSMatthew G. Knepley   Input Parameter:
3857dce8aebaSBarry Smith . ds - The `PetscDS` object
385845480ffeSMatthew G. Knepley 
385945480ffeSMatthew G. Knepley   Level: intermediate
386045480ffeSMatthew G. Knepley 
3861dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
386245480ffeSMatthew G. Knepley @*/
3863d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3864d71ae5a4SJacob Faibussowitsch {
386545480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
386645480ffeSMatthew G. Knepley 
386745480ffeSMatthew G. Knepley   PetscFunctionBegin;
386845480ffeSMatthew G. Knepley   while (next) {
386945480ffeSMatthew G. Knepley     DSBoundary b = next;
387045480ffeSMatthew G. Knepley 
387145480ffeSMatthew G. Knepley     next = b->next;
38729566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38739566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38749566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38759566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38769566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38779566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
387845480ffeSMatthew G. Knepley   }
38793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
388045480ffeSMatthew G. Knepley }
388145480ffeSMatthew G. Knepley 
388245480ffeSMatthew G. Knepley /*@
38836c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38846c1eb96dSMatthew G. Knepley 
388520f4b53cSBarry Smith   Not Collective
38866c1eb96dSMatthew G. Knepley 
3887d8d19677SJose E. Roman   Input Parameters:
3888dce8aebaSBarry Smith + prob      - The `PetscDS` object
38896c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38906c1eb96dSMatthew G. Knepley - fields    - Old field number for each new field
38916c1eb96dSMatthew G. Knepley 
38926c1eb96dSMatthew G. Knepley   Output Parameter:
3893dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38946c1eb96dSMatthew G. Knepley 
38956c1eb96dSMatthew G. Knepley   Level: intermediate
38966c1eb96dSMatthew G. Knepley 
3897dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38986c1eb96dSMatthew G. Knepley @*/
3899d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3900d71ae5a4SJacob Faibussowitsch {
39016c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
39026c1eb96dSMatthew G. Knepley 
39036c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
39046c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39054f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39066c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39079566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39089566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
390945480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
39106c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39116c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
39126c1eb96dSMatthew G. Knepley     PetscObject    disc;
39136c1eb96dSMatthew G. Knepley 
39146c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
39159566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
39169566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
39176c1eb96dSMatthew G. Knepley   }
39183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39196c1eb96dSMatthew G. Knepley }
39206c1eb96dSMatthew G. Knepley 
39216c1eb96dSMatthew G. Knepley /*@
39229252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
39239252d075SMatthew G. Knepley 
392420f4b53cSBarry Smith   Not Collective
39259252d075SMatthew G. Knepley 
3926d8d19677SJose E. Roman   Input Parameters:
3927dce8aebaSBarry Smith + prob      - The `PetscDS` object
39289252d075SMatthew G. Knepley . numFields - Number of new fields
39299252d075SMatthew G. Knepley - fields    - Old field number for each new field
39309252d075SMatthew G. Knepley 
39319252d075SMatthew G. Knepley   Output Parameter:
3932dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39339252d075SMatthew G. Knepley 
39349252d075SMatthew G. Knepley   Level: intermediate
39359252d075SMatthew G. Knepley 
3936dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39379252d075SMatthew G. Knepley @*/
3938d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3939d71ae5a4SJacob Faibussowitsch {
39409252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
39419252d075SMatthew G. Knepley 
39429252d075SMatthew G. Knepley   PetscFunctionBegin;
39439252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39444f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39459252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39469566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39479566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
394863a3b9bcSJacob 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);
39499252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39509252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39519252d075SMatthew G. Knepley     PetscPointFunc   obj;
39529252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39539252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39549252d075SMatthew G. Knepley     PetscRiemannFunc r;
39559252d075SMatthew G. Knepley 
3956c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39579566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39589566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39599566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39609566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39659252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39669252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39679252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39689252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39699252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39709252d075SMatthew G. Knepley 
3971c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39729566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39739566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39749566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39759566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39769566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39779566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39789252d075SMatthew G. Knepley     }
39799252d075SMatthew G. Knepley   }
39803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39819252d075SMatthew G. Knepley }
39829252d075SMatthew G. Knepley 
3983da51fcedSMatthew G. Knepley /*@
3984dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3985da51fcedSMatthew G. Knepley 
398620f4b53cSBarry Smith   Not Collective
3987da51fcedSMatthew G. Knepley 
3988da51fcedSMatthew G. Knepley   Input Parameter:
3989dce8aebaSBarry Smith . prob - The `PetscDS` object
3990da51fcedSMatthew G. Knepley 
3991da51fcedSMatthew G. Knepley   Output Parameter:
3992dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3993da51fcedSMatthew G. Knepley 
3994da51fcedSMatthew G. Knepley   Level: intermediate
3995da51fcedSMatthew G. Knepley 
3996dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3997da51fcedSMatthew G. Knepley @*/
3998d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3999d71ae5a4SJacob Faibussowitsch {
4000b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
40019252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4002da51fcedSMatthew G. Knepley 
4003da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4004da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4005da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40069566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40079566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
400863a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
40099566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
40109566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
40119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
40123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40139252d075SMatthew G. Knepley }
401445480ffeSMatthew G. Knepley 
40159252d075SMatthew G. Knepley /*@
4016dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4017da51fcedSMatthew G. Knepley 
401820f4b53cSBarry Smith   Not Collective
40199252d075SMatthew G. Knepley 
40209252d075SMatthew G. Knepley   Input Parameter:
4021dce8aebaSBarry Smith . prob - The `PetscDS` object
40229252d075SMatthew G. Knepley 
40239252d075SMatthew G. Knepley   Output Parameter:
4024dce8aebaSBarry Smith . newprob - The `PetscDS` copy
40259252d075SMatthew G. Knepley 
40269252d075SMatthew G. Knepley   Level: intermediate
40279252d075SMatthew G. Knepley 
4028dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40299252d075SMatthew G. Knepley @*/
4030d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4031d71ae5a4SJacob Faibussowitsch {
40329252d075SMatthew G. Knepley   PetscInt           Nc;
40339252d075SMatthew G. Knepley   const PetscScalar *constants;
40349252d075SMatthew G. Knepley 
40359252d075SMatthew G. Knepley   PetscFunctionBegin;
40369252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
40379252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
40399566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
40403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4041da51fcedSMatthew G. Knepley }
4042da51fcedSMatthew G. Knepley 
404345480ffeSMatthew G. Knepley /*@
4044dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
404545480ffeSMatthew G. Knepley 
404620f4b53cSBarry Smith   Not Collective
404745480ffeSMatthew G. Knepley 
404845480ffeSMatthew G. Knepley   Input Parameter:
4049dce8aebaSBarry Smith . ds - The `PetscDS` object
405045480ffeSMatthew G. Knepley 
405145480ffeSMatthew G. Knepley   Output Parameter:
4052dce8aebaSBarry Smith . newds - The `PetscDS` copy
405345480ffeSMatthew G. Knepley 
405445480ffeSMatthew G. Knepley   Level: intermediate
405545480ffeSMatthew G. Knepley 
4056dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
405745480ffeSMatthew G. Knepley @*/
4058d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4059d71ae5a4SJacob Faibussowitsch {
40608434afd1SBarry Smith   PetscSimplePointFn *sol;
406145480ffeSMatthew G. Knepley   void               *ctx;
406245480ffeSMatthew G. Knepley   PetscInt            Nf, f;
406345480ffeSMatthew G. Knepley 
406445480ffeSMatthew G. Knepley   PetscFunctionBegin;
406545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
406645480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40679566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
406845480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40699566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40709566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40719566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40729566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
407345480ffeSMatthew G. Knepley   }
40743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
407545480ffeSMatthew G. Knepley }
407645480ffeSMatthew G. Knepley 
407707218a29SMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, DM dmNew, PetscDS dsNew)
407807218a29SMatthew G. Knepley {
407907218a29SMatthew G. Knepley   DSBoundary b;
408007218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
408107218a29SMatthew G. Knepley   PetscBool  isCohesive;
408207218a29SMatthew G. Knepley   void      *ctx;
408307218a29SMatthew G. Knepley 
408407218a29SMatthew G. Knepley   PetscFunctionBegin;
408507218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
408607218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
408707218a29SMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew));
408807218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
408907218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
409007218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
409107218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
409207218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
409307218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
409407218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
409507218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
409607218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
409707218a29SMatthew G. Knepley   }
409807218a29SMatthew G. Knepley   if (Nf) {
409907218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
410007218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
410107218a29SMatthew G. Knepley   }
410207218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
410307218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
410407218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
410507218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
410607218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
410707218a29SMatthew G. Knepley   }
410807218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
410907218a29SMatthew G. Knepley }
411007218a29SMatthew G. Knepley 
4111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4112d71ae5a4SJacob Faibussowitsch {
4113df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4114b1353e8eSMatthew G. Knepley 
4115b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4116b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41174f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
41189371c9d4SSatish Balay   if (height == 0) {
41199371c9d4SSatish Balay     *subprob = prob;
41203ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
41219371c9d4SSatish Balay   }
41229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
412463a3b9bcSJacob 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);
41259566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4126df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4127b1353e8eSMatthew G. Knepley     PetscInt cdim;
4128b1353e8eSMatthew G. Knepley 
41299566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
41309566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
41319566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4132b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4133b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4134b1353e8eSMatthew G. Knepley       PetscObject  obj;
4135b1353e8eSMatthew G. Knepley       PetscClassId id;
4136b1353e8eSMatthew G. Knepley 
41379566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41389566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
41399566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
414063a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
41419566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4142b1353e8eSMatthew G. Knepley     }
4143b1353e8eSMatthew G. Knepley   }
4144df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
41453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4146b1353e8eSMatthew G. Knepley }
4147b1353e8eSMatthew G. Knepley 
41484366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
41494366bac7SMatthew G. Knepley {
41504366bac7SMatthew G. Knepley   IS              permIS;
41514366bac7SMatthew G. Knepley   PetscQuadrature quad;
41524366bac7SMatthew G. Knepley   DMPolytopeType  ct;
41534366bac7SMatthew G. Knepley   const PetscInt *perm;
41544366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
41554366bac7SMatthew G. Knepley 
41564366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
41574366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
41584366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
41594366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
41604366bac7SMatthew 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);
416185036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
41624366bac7SMatthew 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);
41634366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
41644366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
41654366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
41664366bac7SMatthew G. Knepley   *qperm = perm[q];
41674366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
41684366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
41694366bac7SMatthew G. Knepley }
41704366bac7SMatthew G. Knepley 
4171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4172d71ae5a4SJacob Faibussowitsch {
4173c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4174c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4175c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4176c7bd5f0bSMatthew G. Knepley 
4177c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4178c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41794f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4180665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
41819566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
418263a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
41839566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4184665f567fSMatthew G. Knepley   if (obj) {
41859566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4186665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4187665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4188665f567fSMatthew G. Knepley   }
41893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4190c7bd5f0bSMatthew G. Knepley }
4191c7bd5f0bSMatthew G. Knepley 
4192d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4193d71ae5a4SJacob Faibussowitsch {
41942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41959566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
41963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41972764a2aaSMatthew G. Knepley }
41982764a2aaSMatthew G. Knepley 
4199d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4200d71ae5a4SJacob Faibussowitsch {
42012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42026528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
42036528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
42046528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
42056528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
42063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42072764a2aaSMatthew G. Knepley }
42082764a2aaSMatthew G. Knepley 
42092764a2aaSMatthew G. Knepley /*MC
42102764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
42112764a2aaSMatthew G. Knepley 
42122764a2aaSMatthew G. Knepley   Level: intermediate
42132764a2aaSMatthew G. Knepley 
4214db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
42152764a2aaSMatthew G. Knepley M*/
42162764a2aaSMatthew G. Knepley 
4217d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4218d71ae5a4SJacob Faibussowitsch {
42192764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
42202764a2aaSMatthew G. Knepley 
42212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
42234dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
42246528b96dSMatthew G. Knepley   ds->data = b;
42252764a2aaSMatthew G. Knepley 
42269566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
42273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42282764a2aaSMatthew G. Knepley }
4229