xref: /petsc/src/dm/dt/interface/dtds.c (revision 12fc5b223091c94d5732fdf6b2ff0a471caa899e)
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 
242764a2aaSMatthew G. Knepley   Not Collective
252764a2aaSMatthew G. Knepley 
262764a2aaSMatthew G. Knepley   Input Parameters:
272764a2aaSMatthew G. Knepley + name        - The name of a new user-defined creation routine
282764a2aaSMatthew G. Knepley - create_func - The creation routine itself
292764a2aaSMatthew G. Knepley 
302764a2aaSMatthew G. Knepley   Sample 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   Fortran Note:
51f5f57ec0SBarry Smith   Not available from Fortran
52f5f57ec0SBarry Smith 
53dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
542764a2aaSMatthew G. Knepley @*/
55d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
56d71ae5a4SJacob Faibussowitsch {
572764a2aaSMatthew G. Knepley   PetscFunctionBegin;
589566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
602764a2aaSMatthew G. Knepley }
612764a2aaSMatthew G. Knepley 
622764a2aaSMatthew G. Knepley /*@C
63dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
642764a2aaSMatthew G. Knepley 
65d083f849SBarry Smith   Collective on prob
662764a2aaSMatthew G. Knepley 
672764a2aaSMatthew G. Knepley   Input Parameters:
68dce8aebaSBarry Smith + prob - The `PetscDS` object
69dce8aebaSBarry Smith - name - The `PetscDSType`
702764a2aaSMatthew G. Knepley 
712764a2aaSMatthew G. Knepley   Options Database Key:
722764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
732764a2aaSMatthew G. Knepley 
742764a2aaSMatthew G. Knepley   Level: intermediate
752764a2aaSMatthew G. Knepley 
76dce8aebaSBarry Smith   Fortran Note:
77f5f57ec0SBarry Smith   Not available from Fortran
78f5f57ec0SBarry Smith 
79dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
802764a2aaSMatthew G. Knepley @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
82d71ae5a4SJacob Faibussowitsch {
832764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
842764a2aaSMatthew G. Knepley   PetscBool match;
852764a2aaSMatthew G. Knepley 
862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
872764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
893ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
902764a2aaSMatthew G. Knepley 
919566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
929566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
9328b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
942764a2aaSMatthew G. Knepley 
95dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
962764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
97dbbe0bcdSBarry Smith 
989566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
999566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1012764a2aaSMatthew G. Knepley }
1022764a2aaSMatthew G. Knepley 
1032764a2aaSMatthew G. Knepley /*@C
104dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
1052764a2aaSMatthew G. Knepley 
1062764a2aaSMatthew G. Knepley   Not Collective
1072764a2aaSMatthew G. Knepley 
1082764a2aaSMatthew G. Knepley   Input Parameter:
109dce8aebaSBarry Smith . prob  - The `PetscDS`
1102764a2aaSMatthew G. Knepley 
1112764a2aaSMatthew G. Knepley   Output Parameter:
112dce8aebaSBarry Smith . name - The `PetscDSType` name
1132764a2aaSMatthew G. Knepley 
1142764a2aaSMatthew G. Knepley   Level: intermediate
1152764a2aaSMatthew G. Knepley 
116dce8aebaSBarry Smith   Fortran Note:
117f5f57ec0SBarry Smith   Not available from Fortran
118f5f57ec0SBarry Smith 
119dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
1202764a2aaSMatthew G. Knepley @*/
121d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
122d71ae5a4SJacob Faibussowitsch {
1232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1242764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
125c959eef4SJed Brown   PetscValidPointer(name, 2);
1269566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1272764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1292764a2aaSMatthew G. Knepley }
1302764a2aaSMatthew G. Knepley 
131d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
132d71ae5a4SJacob Faibussowitsch {
1337d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
13497b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1355fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1367d8a60eaSMatthew G. Knepley 
1377d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
14063a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
14263a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1439566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1445fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
14540967b3bSMatthew G. Knepley     DSBoundary      b;
1467d8a60eaSMatthew G. Knepley     PetscObject     obj;
1477d8a60eaSMatthew G. Knepley     PetscClassId    id;
148f35450b9SMatthew G. Knepley     PetscQuadrature q;
1497d8a60eaSMatthew G. Knepley     const char     *name;
150f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1517d8a60eaSMatthew G. Knepley 
1529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1539566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1549566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1559566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1577d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1589566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1599566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1609566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1617d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1639566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1659371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
16663a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
16763a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1689566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1699566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1703e60c2a6SMatthew G. Knepley     if (q) {
1719566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
17263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1733e60c2a6SMatthew G. Knepley     }
17463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1759566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1769566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1779566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1789566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1799566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1809566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
18140967b3bSMatthew G. Knepley 
1825fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
18306ad1575SMatthew G. Knepley       char    *name;
18440967b3bSMatthew G. Knepley       PetscInt c, i;
18540967b3bSMatthew G. Knepley 
18640967b3bSMatthew G. Knepley       if (b->field != f) continue;
1879566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1889566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
18945480ffeSMatthew G. Knepley       if (!b->Nc) {
1909566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
19140967b3bSMatthew G. Knepley       } else {
1929566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1939566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
19445480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1959566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
19663a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
19740967b3bSMatthew G. Knepley         }
1989566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1999566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20040967b3bSMatthew G. Knepley       }
2019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
2029566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
20345480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
2049566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
20563a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
20640967b3bSMatthew G. Knepley       }
2079566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
2089566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20915943bb8SPierre Jolivet #if defined(__clang__)
21015943bb8SPierre Jolivet   #pragma clang diagnostic push
21115943bb8SPierre Jolivet   #pragma clang diagnostic ignored "-Wformat-pedantic"
21215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
21315943bb8SPierre Jolivet   #pragma GCC diagnostic push
21415943bb8SPierre Jolivet   #pragma GCC diagnostic ignored "-Wformat"
21515943bb8SPierre Jolivet #endif
2168e0d8d9cSMatthew G. Knepley       if (b->func) {
2179566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2189566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2199566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2209566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2218e0d8d9cSMatthew G. Knepley       }
2228e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2239566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2249566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2259566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2269566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2278e0d8d9cSMatthew G. Knepley       }
22815943bb8SPierre Jolivet #if defined(__clang__)
22915943bb8SPierre Jolivet   #pragma clang diagnostic pop
23015943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
23115943bb8SPierre Jolivet   #pragma GCC diagnostic pop
23215943bb8SPierre Jolivet #endif
2339566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
23540967b3bSMatthew G. Knepley     }
2367d8a60eaSMatthew G. Knepley   }
2379566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
23897b6e6e8SMatthew G. Knepley   if (numConstants) {
23963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2409566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2419566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2429566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
24397b6e6e8SMatthew G. Knepley   }
2449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2459566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2477d8a60eaSMatthew G. Knepley }
2487d8a60eaSMatthew G. Knepley 
2492764a2aaSMatthew G. Knepley /*@C
250dce8aebaSBarry Smith    PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
251fe2efc57SMark 
252fe2efc57SMark    Collective on PetscDS
253fe2efc57SMark 
254fe2efc57SMark    Input Parameters:
255dce8aebaSBarry Smith +  A - the `PetscDS` object
256736c3998SJose E. Roman .  obj - Optional object
257736c3998SJose E. Roman -  name - command line option
258fe2efc57SMark 
259fe2efc57SMark    Level: intermediate
260dce8aebaSBarry Smith 
261dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
262fe2efc57SMark @*/
263d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
264d71ae5a4SJacob Faibussowitsch {
265fe2efc57SMark   PetscFunctionBegin;
266fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2679566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
269fe2efc57SMark }
270fe2efc57SMark 
271fe2efc57SMark /*@C
272dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2732764a2aaSMatthew G. Knepley 
274d083f849SBarry Smith   Collective on prob
2752764a2aaSMatthew G. Knepley 
276d8d19677SJose E. Roman   Input Parameters:
277dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2782764a2aaSMatthew G. Knepley - v  - the viewer
2792764a2aaSMatthew G. Knepley 
2802764a2aaSMatthew G. Knepley   Level: developer
2812764a2aaSMatthew G. Knepley 
282dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`
2832764a2aaSMatthew G. Knepley @*/
284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
285d71ae5a4SJacob Faibussowitsch {
2867d8a60eaSMatthew G. Knepley   PetscBool iascii;
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2892764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2909566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
291ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2939566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
294dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2962764a2aaSMatthew G. Knepley }
2972764a2aaSMatthew G. Knepley 
2982764a2aaSMatthew G. Knepley /*@
299dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
3002764a2aaSMatthew G. Knepley 
301d083f849SBarry Smith   Collective on prob
3022764a2aaSMatthew G. Knepley 
3032764a2aaSMatthew G. Knepley   Input Parameter:
304dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
3052764a2aaSMatthew G. Knepley 
306dce8aebaSBarry Smith   Options Database Keys:
307dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
308dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
309147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
310147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
311147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
3122764a2aaSMatthew G. Knepley 
313dce8aebaSBarry Smith   Level: intermediate
3142764a2aaSMatthew G. Knepley 
315dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3162764a2aaSMatthew G. Knepley @*/
317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
318d71ae5a4SJacob Faibussowitsch {
319f1fd5e65SToby Isaac   DSBoundary  b;
3202764a2aaSMatthew G. Knepley   const char *defaultType;
3212764a2aaSMatthew G. Knepley   char        name[256];
3222764a2aaSMatthew G. Knepley   PetscBool   flg;
3232764a2aaSMatthew G. Knepley 
3242764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3252764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3262764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3272764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3282764a2aaSMatthew G. Knepley   } else {
3292764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3302764a2aaSMatthew G. Knepley   }
3319566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3322764a2aaSMatthew G. Knepley 
333d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
334f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
335f1fd5e65SToby Isaac     char      optname[1024];
336f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
337f1fd5e65SToby Isaac     PetscBool flg;
338f1fd5e65SToby Isaac 
3399566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3409566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3419566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
342f1fd5e65SToby Isaac     if (flg) {
34345480ffeSMatthew G. Knepley       b->Nv = len;
3449566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3459566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3469566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3479566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
348f1fd5e65SToby Isaac     }
349e7b0402cSSander Arens     len = 1024;
3509566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3519566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
353f1fd5e65SToby Isaac     if (flg) {
35445480ffeSMatthew G. Knepley       b->Nc = len;
3559566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3569566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3579566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
358f1fd5e65SToby Isaac     }
359f1fd5e65SToby Isaac   }
3609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3612764a2aaSMatthew G. Knepley   if (flg) {
3629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3632764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3652764a2aaSMatthew G. Knepley   }
3669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
367*12fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
368dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3692764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
370dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
371d0609cedSBarry Smith   PetscOptionsEnd();
3729566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3742764a2aaSMatthew G. Knepley }
3752764a2aaSMatthew G. Knepley 
3762764a2aaSMatthew G. Knepley /*@C
377dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3782764a2aaSMatthew G. Knepley 
379d083f849SBarry Smith   Collective on prob
3802764a2aaSMatthew G. Knepley 
3812764a2aaSMatthew G. Knepley   Input Parameter:
382dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3832764a2aaSMatthew G. Knepley 
3842764a2aaSMatthew G. Knepley   Level: developer
3852764a2aaSMatthew G. Knepley 
386dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3872764a2aaSMatthew G. Knepley @*/
388d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
389d71ae5a4SJacob Faibussowitsch {
3902764a2aaSMatthew G. Knepley   const PetscInt Nf   = prob->Nf;
391f9244615SMatthew G. Knepley   PetscBool      hasH = PETSC_FALSE;
3924bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3932764a2aaSMatthew G. Knepley 
3942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3952764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3963ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3972764a2aaSMatthew G. Knepley   /* Calculate sizes */
3989566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3999566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
400f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
4019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
4029566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
4039566063dSJacob 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]));
4049566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
405*12fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
406*12fc5b22SMatthew G. Knepley     PetscQuadrature mq = NULL, mfq = NULL;
407*12fc5b22SMatthew G. Knepley     PetscInt        maxOrder = -1, maxFOrder = -1;
408*12fc5b22SMatthew G. Knepley 
409*12fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
410*12fc5b22SMatthew G. Knepley       PetscObject     obj;
411*12fc5b22SMatthew G. Knepley       PetscClassId    id;
412*12fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
413*12fc5b22SMatthew G. Knepley       PetscInt        order = -1, forder = -1;
414*12fc5b22SMatthew G. Knepley 
415*12fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
416*12fc5b22SMatthew G. Knepley       if (!obj) continue;
417*12fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
418*12fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
419*12fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
420*12fc5b22SMatthew G. Knepley 
421*12fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
422*12fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
423*12fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
424*12fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
425*12fc5b22SMatthew G. Knepley 
426*12fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
427*12fc5b22SMatthew G. Knepley       }
428*12fc5b22SMatthew G. Knepley       if (q) PetscCall(PetscQuadratureGetOrder(q, &order));
429*12fc5b22SMatthew G. Knepley       if (fq) PetscCall(PetscQuadratureGetOrder(fq, &forder));
430*12fc5b22SMatthew G. Knepley       if (order > maxOrder) {
431*12fc5b22SMatthew G. Knepley         maxOrder = order;
432*12fc5b22SMatthew G. Knepley         mq       = q;
433*12fc5b22SMatthew G. Knepley       }
434*12fc5b22SMatthew G. Knepley       if (forder > maxFOrder) {
435*12fc5b22SMatthew G. Knepley         maxFOrder = forder;
436*12fc5b22SMatthew G. Knepley         mfq       = fq;
437*12fc5b22SMatthew G. Knepley       }
438*12fc5b22SMatthew G. Knepley     }
439*12fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
440*12fc5b22SMatthew G. Knepley       PetscObject  obj;
441*12fc5b22SMatthew G. Knepley       PetscClassId id;
442*12fc5b22SMatthew G. Knepley 
443*12fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
444*12fc5b22SMatthew G. Knepley       if (!obj) continue;
445*12fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
446*12fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
447*12fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
448*12fc5b22SMatthew G. Knepley 
449*12fc5b22SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, mq));
450*12fc5b22SMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, mfq));
451*12fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
452*12fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
453*12fc5b22SMatthew G. Knepley 
454*12fc5b22SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, mq));
455*12fc5b22SMatthew G. Knepley       }
456*12fc5b22SMatthew G. Knepley     }
457*12fc5b22SMatthew 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));
4769566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4779566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4789566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4799566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4809de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4819de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4829de99aefSMatthew G. Knepley 
4839566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4849566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
4859c3cf19fSMatthew G. Knepley         Nb = Nc;
4869566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
4874d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
48863a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
489665f567fSMatthew G. Knepley     }
49047e57110SSander Arens     prob->Nc[f]                    = Nc;
49147e57110SSander Arens     prob->Nb[f]                    = Nb;
492194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
493194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
4949ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
4959ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
4969ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
4979ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
4989ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
4999ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5009566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5012764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5024bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5032764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5049c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5052764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5065fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5075fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5082764a2aaSMatthew G. Knepley   }
5099ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5109ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5112764a2aaSMatthew G. Knepley   /* Allocate works space */
5125fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5139566063dSJacob 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));
5149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5159371c9d4SSatish 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,
5169371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
517dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5182764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5202764a2aaSMatthew G. Knepley }
5212764a2aaSMatthew G. Knepley 
522d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
523d71ae5a4SJacob Faibussowitsch {
5242764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5259566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5269566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5279566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5289566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5299566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5309566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5319566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5332764a2aaSMatthew G. Knepley }
5342764a2aaSMatthew G. Knepley 
535d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
536d71ae5a4SJacob Faibussowitsch {
537f744cafaSSander Arens   PetscObject          *tmpd;
53834aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
539f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5405fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5416528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
542f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
543f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5440c2f2876SMatthew G. Knepley   void                **tmpctx;
54534aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5462764a2aaSMatthew G. Knepley 
5472764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5483ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5492764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5509566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5519566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5529371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5539371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5549371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5559371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5569371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5579371c9d4SSatish Balay   }
5589371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5599371c9d4SSatish Balay     tmpd[f] = NULL;
5609371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5619371c9d4SSatish Balay     tmpk[f] = 1;
5629371c9d4SSatish Balay   }
5639566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5649566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5652764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5662764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
567249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5685fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
569f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5709566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
57132d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5720c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
57332d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5740c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5759566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
57632d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5770c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5789566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
579c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
58095cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
581f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
582f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
583c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
58495cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
585f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
586f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
5879566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
588c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
58995cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
590f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
591f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
5923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5932764a2aaSMatthew G. Knepley }
5942764a2aaSMatthew G. Knepley 
5952764a2aaSMatthew G. Knepley /*@
5962764a2aaSMatthew G. Knepley   PetscDSDestroy - Destroys a PetscDS object
5972764a2aaSMatthew G. Knepley 
598d083f849SBarry Smith   Collective on prob
5992764a2aaSMatthew G. Knepley 
6002764a2aaSMatthew G. Knepley   Input Parameter:
6012764a2aaSMatthew G. Knepley . prob - the PetscDS object to destroy
6022764a2aaSMatthew G. Knepley 
6032764a2aaSMatthew G. Knepley   Level: developer
6042764a2aaSMatthew G. Knepley 
605dce8aebaSBarry Smith .seealso: `PetscDSView()`
6062764a2aaSMatthew G. Knepley @*/
607d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
608d71ae5a4SJacob Faibussowitsch {
6092764a2aaSMatthew G. Knepley   PetscInt f;
6102764a2aaSMatthew G. Knepley 
6112764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6123ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6142764a2aaSMatthew G. Knepley 
6159371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6169371c9d4SSatish Balay     *ds = NULL;
6173ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6189371c9d4SSatish Balay   }
6196528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6206528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
621df3a45bdSMatthew G. Knepley     PetscInt dim, d;
622df3a45bdSMatthew G. Knepley 
6239566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6249566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
625df3a45bdSMatthew G. Knepley   }
6269566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6279566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
62848a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6299566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6309566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6319566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6329566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
633dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6349566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6359566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6369566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6382764a2aaSMatthew G. Knepley }
6392764a2aaSMatthew G. Knepley 
6402764a2aaSMatthew G. Knepley /*@
641dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6422764a2aaSMatthew G. Knepley 
643d083f849SBarry Smith   Collective
6442764a2aaSMatthew G. Knepley 
6452764a2aaSMatthew G. Knepley   Input Parameter:
646dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6472764a2aaSMatthew G. Knepley 
6482764a2aaSMatthew G. Knepley   Output Parameter:
649dce8aebaSBarry Smith . ds   - The `PetscDS` object
6502764a2aaSMatthew G. Knepley 
6512764a2aaSMatthew G. Knepley   Level: beginner
6522764a2aaSMatthew G. Knepley 
653dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6542764a2aaSMatthew G. Knepley @*/
655d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
656d71ae5a4SJacob Faibussowitsch {
6572764a2aaSMatthew G. Knepley   PetscDS p;
6582764a2aaSMatthew G. Knepley 
6592764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6606528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6616528b96dSMatthew G. Knepley   *ds = NULL;
6629566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6632764a2aaSMatthew G. Knepley 
6649566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6652764a2aaSMatthew G. Knepley 
6662764a2aaSMatthew G. Knepley   p->Nf           = 0;
6672764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
66897b6e6e8SMatthew G. Knepley   p->numConstants = 0;
66997b6e6e8SMatthew G. Knepley   p->constants    = NULL;
670a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
67155c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
672*12fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6742764a2aaSMatthew G. Knepley 
6756528b96dSMatthew G. Knepley   *ds = p;
6763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6772764a2aaSMatthew G. Knepley }
6782764a2aaSMatthew G. Knepley 
679bc4ae4beSMatthew G. Knepley /*@
680dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
681bc4ae4beSMatthew G. Knepley 
682bc4ae4beSMatthew G. Knepley   Not collective
683bc4ae4beSMatthew G. Knepley 
684bc4ae4beSMatthew G. Knepley   Input Parameter:
685bc4ae4beSMatthew G. Knepley . prob - The PetscDS object
686bc4ae4beSMatthew G. Knepley 
687bc4ae4beSMatthew G. Knepley   Output Parameter:
688bc4ae4beSMatthew G. Knepley . Nf - The number of fields
689bc4ae4beSMatthew G. Knepley 
690bc4ae4beSMatthew G. Knepley   Level: beginner
691bc4ae4beSMatthew G. Knepley 
692dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
693bc4ae4beSMatthew G. Knepley @*/
694d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
695d71ae5a4SJacob Faibussowitsch {
6962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6972764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
698dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
6992764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7012764a2aaSMatthew G. Knepley }
7022764a2aaSMatthew G. Knepley 
703bc4ae4beSMatthew G. Knepley /*@
704dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
705bc4ae4beSMatthew G. Knepley 
706bc4ae4beSMatthew G. Knepley   Not collective
707bc4ae4beSMatthew G. Knepley 
708bc4ae4beSMatthew G. Knepley   Input Parameter:
709dce8aebaSBarry Smith . prob - The `PetscDS` object
710bc4ae4beSMatthew G. Knepley 
711bc4ae4beSMatthew G. Knepley   Output Parameter:
712bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
713bc4ae4beSMatthew G. Knepley 
714bc4ae4beSMatthew G. Knepley   Level: beginner
715bc4ae4beSMatthew G. Knepley 
716dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
717bc4ae4beSMatthew G. Knepley @*/
718d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
719d71ae5a4SJacob Faibussowitsch {
7202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
722dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7232764a2aaSMatthew G. Knepley   *dim = 0;
7249de99aefSMatthew G. Knepley   if (prob->Nf) {
7259de99aefSMatthew G. Knepley     PetscObject  obj;
7269de99aefSMatthew G. Knepley     PetscClassId id;
7279de99aefSMatthew G. Knepley 
7289566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
729665f567fSMatthew G. Knepley     if (obj) {
7309566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7319566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7329566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
73398921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7349de99aefSMatthew G. Knepley     }
735665f567fSMatthew G. Knepley   }
7363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7372764a2aaSMatthew G. Knepley }
7382764a2aaSMatthew G. Knepley 
739bc4ae4beSMatthew G. Knepley /*@
740dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
741a859676bSMatthew G. Knepley 
742a859676bSMatthew G. Knepley   Not collective
743a859676bSMatthew G. Knepley 
744a859676bSMatthew G. Knepley   Input Parameter:
745dce8aebaSBarry Smith . prob - The `PetscDS` object
746a859676bSMatthew G. Knepley 
747a859676bSMatthew G. Knepley   Output Parameter:
748a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
749a859676bSMatthew G. Knepley 
750a859676bSMatthew G. Knepley   Level: beginner
751a859676bSMatthew G. Knepley 
752dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
753a859676bSMatthew G. Knepley @*/
754d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
755d71ae5a4SJacob Faibussowitsch {
756a859676bSMatthew G. Knepley   PetscFunctionBegin;
757a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
758dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
75908401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
760a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
762a859676bSMatthew G. Knepley }
763a859676bSMatthew G. Knepley 
764a859676bSMatthew G. Knepley /*@
765dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
766a859676bSMatthew G. Knepley 
767d083f849SBarry Smith   Logically collective on prob
768a859676bSMatthew G. Knepley 
769a859676bSMatthew G. Knepley   Input Parameters:
770dce8aebaSBarry Smith + prob - The `PetscDS` object
771a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
772a859676bSMatthew G. Knepley 
773a859676bSMatthew G. Knepley   Level: beginner
774a859676bSMatthew G. Knepley 
775dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
776a859676bSMatthew G. Knepley @*/
777d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
778d71ae5a4SJacob Faibussowitsch {
779a859676bSMatthew G. Knepley   PetscFunctionBegin;
780a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
78163a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
782a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
7833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
784a859676bSMatthew G. Knepley }
785a859676bSMatthew G. Knepley 
786a859676bSMatthew G. Knepley /*@
787*12fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
788*12fc5b22SMatthew G. Knepley 
789*12fc5b22SMatthew G. Knepley   Not collective
790*12fc5b22SMatthew G. Knepley 
791*12fc5b22SMatthew G. Knepley   Input Parameter:
792*12fc5b22SMatthew G. Knepley . prob - The `PetscDS` object
793*12fc5b22SMatthew G. Knepley 
794*12fc5b22SMatthew G. Knepley   Output Parameter:
795*12fc5b22SMatthew G. Knepley . forceQuad - The flag
796*12fc5b22SMatthew G. Knepley 
797*12fc5b22SMatthew G. Knepley   Level: intermediate
798*12fc5b22SMatthew G. Knepley 
799*12fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
800*12fc5b22SMatthew G. Knepley @*/
801*12fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
802*12fc5b22SMatthew G. Knepley {
803*12fc5b22SMatthew G. Knepley   PetscFunctionBegin;
804*12fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
805*12fc5b22SMatthew G. Knepley   PetscValidIntPointer(forceQuad, 2);
806*12fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
807*12fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
808*12fc5b22SMatthew G. Knepley }
809*12fc5b22SMatthew G. Knepley 
810*12fc5b22SMatthew G. Knepley /*@
811*12fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
812*12fc5b22SMatthew G. Knepley 
813*12fc5b22SMatthew G. Knepley   Logically collective on ds
814*12fc5b22SMatthew G. Knepley 
815*12fc5b22SMatthew G. Knepley   Input Parameters:
816*12fc5b22SMatthew G. Knepley + ds - The `PetscDS` object
817*12fc5b22SMatthew G. Knepley - forceQuad - The flag
818*12fc5b22SMatthew G. Knepley 
819*12fc5b22SMatthew G. Knepley   Level: intermediate
820*12fc5b22SMatthew G. Knepley 
821*12fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
822*12fc5b22SMatthew G. Knepley @*/
823*12fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
824*12fc5b22SMatthew G. Knepley {
825*12fc5b22SMatthew G. Knepley   PetscFunctionBegin;
826*12fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
827*12fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
828*12fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
829*12fc5b22SMatthew G. Knepley }
830*12fc5b22SMatthew G. Knepley 
831*12fc5b22SMatthew G. Knepley /*@
832dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8338edf6225SMatthew G. Knepley 
8348edf6225SMatthew G. Knepley   Not collective
8358edf6225SMatthew G. Knepley 
8368edf6225SMatthew G. Knepley   Input Parameter:
837dce8aebaSBarry Smith . ds - The `PetscDS` object
8388edf6225SMatthew G. Knepley 
8398edf6225SMatthew G. Knepley   Output Parameter:
8405fedec97SMatthew G. Knepley . isCohesive - The flag
8418edf6225SMatthew G. Knepley 
8428edf6225SMatthew G. Knepley   Level: developer
8438edf6225SMatthew G. Knepley 
844dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8458edf6225SMatthew G. Knepley @*/
846d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
847d71ae5a4SJacob Faibussowitsch {
8488edf6225SMatthew G. Knepley   PetscFunctionBegin;
8495fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
850dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8515fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8538edf6225SMatthew G. Knepley }
8548edf6225SMatthew G. Knepley 
8558edf6225SMatthew G. Knepley /*@
8565fedec97SMatthew G. Knepley   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
8575fedec97SMatthew G. Knepley 
8585fedec97SMatthew G. Knepley   Not collective
8595fedec97SMatthew G. Knepley 
8605fedec97SMatthew G. Knepley   Input Parameter:
861dce8aebaSBarry Smith . ds - The `PetscDS` object
8625fedec97SMatthew G. Knepley 
8635fedec97SMatthew G. Knepley   Output Parameter:
8645fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8655fedec97SMatthew G. Knepley 
8665fedec97SMatthew G. Knepley   Level: developer
8675fedec97SMatthew G. Knepley 
868dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8695fedec97SMatthew G. Knepley @*/
870d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
871d71ae5a4SJacob Faibussowitsch {
8725fedec97SMatthew G. Knepley   PetscInt f;
8735fedec97SMatthew G. Knepley 
8745fedec97SMatthew G. Knepley   PetscFunctionBegin;
8755fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
876dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
8775fedec97SMatthew G. Knepley   *numCohesive = 0;
8785fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
8793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8805fedec97SMatthew G. Knepley }
8815fedec97SMatthew G. Knepley 
8825fedec97SMatthew G. Knepley /*@
8835fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
8845fedec97SMatthew G. Knepley 
8855fedec97SMatthew G. Knepley   Not collective
8865fedec97SMatthew G. Knepley 
887f1a722f8SMatthew G. Knepley   Input Parameters:
888dce8aebaSBarry Smith + ds - The `PetscDS` object
8895fedec97SMatthew G. Knepley - f  - The field index
8905fedec97SMatthew G. Knepley 
8915fedec97SMatthew G. Knepley   Output Parameter:
8925fedec97SMatthew G. Knepley . isCohesive - The flag
8935fedec97SMatthew G. Knepley 
8945fedec97SMatthew G. Knepley   Level: developer
8955fedec97SMatthew G. Knepley 
896dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
8975fedec97SMatthew G. Knepley @*/
898d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
899d71ae5a4SJacob Faibussowitsch {
9005fedec97SMatthew G. Knepley   PetscFunctionBegin;
9015fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
902dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
90363a3b9bcSJacob 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);
9045fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9065fedec97SMatthew G. Knepley }
9075fedec97SMatthew G. Knepley 
9085fedec97SMatthew G. Knepley /*@
9095fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9108edf6225SMatthew G. Knepley 
9118edf6225SMatthew G. Knepley   Not collective
9128edf6225SMatthew G. Knepley 
9138edf6225SMatthew G. Knepley   Input Parameters:
914dce8aebaSBarry Smith + ds - The `PetscDS` object
9155fedec97SMatthew G. Knepley . f  - The field index
9165fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9178edf6225SMatthew G. Knepley 
9188edf6225SMatthew G. Knepley   Level: developer
9198edf6225SMatthew G. Knepley 
920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9218edf6225SMatthew G. Knepley @*/
922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
923d71ae5a4SJacob Faibussowitsch {
9245fedec97SMatthew G. Knepley   PetscInt i;
9255fedec97SMatthew G. Knepley 
9268edf6225SMatthew G. Knepley   PetscFunctionBegin;
9275fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
92863a3b9bcSJacob 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);
9295fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9305fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9315fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9338edf6225SMatthew G. Knepley }
9348edf6225SMatthew G. Knepley 
9358edf6225SMatthew G. Knepley /*@
936bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
937bc4ae4beSMatthew G. Knepley 
938bc4ae4beSMatthew G. Knepley   Not collective
939bc4ae4beSMatthew G. Knepley 
940bc4ae4beSMatthew G. Knepley   Input Parameter:
941dce8aebaSBarry Smith . prob - The `PetscDS` object
942bc4ae4beSMatthew G. Knepley 
943bc4ae4beSMatthew G. Knepley   Output Parameter:
944bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
945bc4ae4beSMatthew G. Knepley 
946bc4ae4beSMatthew G. Knepley   Level: beginner
947bc4ae4beSMatthew G. Knepley 
948dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
949bc4ae4beSMatthew G. Knepley @*/
950d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
951d71ae5a4SJacob Faibussowitsch {
9522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9532764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9549566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
955dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9562764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9582764a2aaSMatthew G. Knepley }
9592764a2aaSMatthew G. Knepley 
960bc4ae4beSMatthew G. Knepley /*@
961bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
962bc4ae4beSMatthew G. Knepley 
963bc4ae4beSMatthew G. Knepley   Not collective
964bc4ae4beSMatthew G. Knepley 
965bc4ae4beSMatthew G. Knepley   Input Parameter:
966dce8aebaSBarry Smith . prob - The `PetscDS` object
967bc4ae4beSMatthew G. Knepley 
968bc4ae4beSMatthew G. Knepley   Output Parameter:
969bc4ae4beSMatthew G. Knepley . dim - The total number of components
970bc4ae4beSMatthew G. Knepley 
971bc4ae4beSMatthew G. Knepley   Level: beginner
972bc4ae4beSMatthew G. Knepley 
973dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
974bc4ae4beSMatthew G. Knepley @*/
975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
976d71ae5a4SJacob Faibussowitsch {
9772764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9782764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9799566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
980dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
9812764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
9823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9832764a2aaSMatthew G. Knepley }
9842764a2aaSMatthew G. Knepley 
985bc4ae4beSMatthew G. Knepley /*@
986bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
987bc4ae4beSMatthew G. Knepley 
988bc4ae4beSMatthew G. Knepley   Not collective
989bc4ae4beSMatthew G. Knepley 
990bc4ae4beSMatthew G. Knepley   Input Parameters:
991dce8aebaSBarry Smith + prob - The `PetscDS` object
992bc4ae4beSMatthew G. Knepley - f - The field number
993bc4ae4beSMatthew G. Knepley 
994bc4ae4beSMatthew G. Knepley   Output Parameter:
995bc4ae4beSMatthew G. Knepley . disc - The discretization object
996bc4ae4beSMatthew G. Knepley 
997bc4ae4beSMatthew G. Knepley   Level: beginner
998bc4ae4beSMatthew G. Knepley 
999dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1000bc4ae4beSMatthew G. Knepley @*/
1001d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1002d71ae5a4SJacob Faibussowitsch {
10036528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10042764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10052764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
100663a3b9bcSJacob 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);
10072764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10092764a2aaSMatthew G. Knepley }
10102764a2aaSMatthew G. Knepley 
1011bc4ae4beSMatthew G. Knepley /*@
1012bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1013bc4ae4beSMatthew G. Knepley 
1014bc4ae4beSMatthew G. Knepley   Not collective
1015bc4ae4beSMatthew G. Knepley 
1016bc4ae4beSMatthew G. Knepley   Input Parameters:
1017dce8aebaSBarry Smith + prob - The `PetscDS` object
1018bc4ae4beSMatthew G. Knepley . f - The field number
1019bc4ae4beSMatthew G. Knepley - disc - The discretization object
1020bc4ae4beSMatthew G. Knepley 
1021bc4ae4beSMatthew G. Knepley   Level: beginner
1022bc4ae4beSMatthew G. Knepley 
1023dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1024bc4ae4beSMatthew G. Knepley @*/
1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1026d71ae5a4SJacob Faibussowitsch {
10272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10282764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1029665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
103063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10319566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10329566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10332764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10349566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1035665f567fSMatthew G. Knepley   if (disc) {
1036249df284SMatthew G. Knepley     PetscClassId id;
1037249df284SMatthew G. Knepley 
10389566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10391cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10409566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10411cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10429566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1043a6cbbb48SMatthew G. Knepley     }
10449566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1045249df284SMatthew G. Knepley   }
10463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10472764a2aaSMatthew G. Knepley }
10482764a2aaSMatthew G. Knepley 
1049bc4ae4beSMatthew G. Knepley /*@
10506528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10516528b96dSMatthew G. Knepley 
10526528b96dSMatthew G. Knepley   Not collective
10536528b96dSMatthew G. Knepley 
10546528b96dSMatthew G. Knepley   Input Parameter:
1055dce8aebaSBarry Smith . ds - The `PetscDS` object
10566528b96dSMatthew G. Knepley 
10576528b96dSMatthew G. Knepley   Output Parameter:
10586528b96dSMatthew G. Knepley . wf - The weak form object
10596528b96dSMatthew G. Knepley 
10606528b96dSMatthew G. Knepley   Level: beginner
10616528b96dSMatthew G. Knepley 
1062dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10636528b96dSMatthew G. Knepley @*/
1064d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1065d71ae5a4SJacob Faibussowitsch {
10666528b96dSMatthew G. Knepley   PetscFunctionBegin;
10676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10686528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10696528b96dSMatthew G. Knepley   *wf = ds->wf;
10703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10716528b96dSMatthew G. Knepley }
10726528b96dSMatthew G. Knepley 
10736528b96dSMatthew G. Knepley /*@
10746528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10756528b96dSMatthew G. Knepley 
10766528b96dSMatthew G. Knepley   Not collective
10776528b96dSMatthew G. Knepley 
10786528b96dSMatthew G. Knepley   Input Parameters:
1079dce8aebaSBarry Smith + ds - The `PetscDS` object
10806528b96dSMatthew G. Knepley - wf - The weak form object
10816528b96dSMatthew G. Knepley 
10826528b96dSMatthew G. Knepley   Level: beginner
10836528b96dSMatthew G. Knepley 
1084dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10856528b96dSMatthew G. Knepley @*/
1086d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1087d71ae5a4SJacob Faibussowitsch {
10886528b96dSMatthew G. Knepley   PetscFunctionBegin;
10896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
10919566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
10926528b96dSMatthew G. Knepley   ds->wf = wf;
10939566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
10949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
10953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10966528b96dSMatthew G. Knepley }
10976528b96dSMatthew G. Knepley 
10986528b96dSMatthew G. Knepley /*@
1099bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1100bc4ae4beSMatthew G. Knepley 
1101bc4ae4beSMatthew G. Knepley   Not collective
1102bc4ae4beSMatthew G. Knepley 
1103bc4ae4beSMatthew G. Knepley   Input Parameters:
1104dce8aebaSBarry Smith + prob - The `PetscDS` object
1105bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1106bc4ae4beSMatthew G. Knepley 
1107bc4ae4beSMatthew G. Knepley   Level: beginner
1108bc4ae4beSMatthew G. Knepley 
1109dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1110bc4ae4beSMatthew G. Knepley @*/
1111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1112d71ae5a4SJacob Faibussowitsch {
11132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11149566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11162764a2aaSMatthew G. Knepley }
11172764a2aaSMatthew G. Knepley 
1118249df284SMatthew G. Knepley /*@
1119dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1120083401c6SMatthew G. Knepley 
1121083401c6SMatthew G. Knepley   Not collective
1122083401c6SMatthew G. Knepley 
1123083401c6SMatthew G. Knepley   Input Parameter:
1124dce8aebaSBarry Smith . prob - The `PetscDS` object
1125083401c6SMatthew G. Knepley 
1126083401c6SMatthew G. Knepley   Output Parameter:
1127083401c6SMatthew G. Knepley . q - The quadrature object
1128083401c6SMatthew G. Knepley 
1129083401c6SMatthew G. Knepley   Level: intermediate
1130083401c6SMatthew G. Knepley 
1131dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1132083401c6SMatthew G. Knepley @*/
1133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1134d71ae5a4SJacob Faibussowitsch {
1135083401c6SMatthew G. Knepley   PetscObject  obj;
1136083401c6SMatthew G. Knepley   PetscClassId id;
1137083401c6SMatthew G. Knepley 
1138083401c6SMatthew G. Knepley   PetscFunctionBegin;
1139083401c6SMatthew G. Knepley   *q = NULL;
11403ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11429566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11439566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11449566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
114598921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1147083401c6SMatthew G. Knepley }
1148083401c6SMatthew G. Knepley 
1149083401c6SMatthew G. Knepley /*@
1150dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1151249df284SMatthew G. Knepley 
1152249df284SMatthew G. Knepley   Not collective
1153249df284SMatthew G. Knepley 
1154249df284SMatthew G. Knepley   Input Parameters:
1155dce8aebaSBarry Smith + prob - The `PetscDS` object
1156249df284SMatthew G. Knepley - f - The field number
1157249df284SMatthew G. Knepley 
1158249df284SMatthew G. Knepley   Output Parameter:
1159249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1160249df284SMatthew G. Knepley 
1161249df284SMatthew G. Knepley   Level: developer
1162249df284SMatthew G. Knepley 
1163dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1164249df284SMatthew G. Knepley @*/
1165d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1166d71ae5a4SJacob Faibussowitsch {
1167249df284SMatthew G. Knepley   PetscFunctionBegin;
1168249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1169dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
117063a3b9bcSJacob 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);
1171249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1173249df284SMatthew G. Knepley }
1174249df284SMatthew G. Knepley 
1175249df284SMatthew G. Knepley /*@
1176dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1177249df284SMatthew G. Knepley 
1178249df284SMatthew G. Knepley   Not collective
1179249df284SMatthew G. Knepley 
1180249df284SMatthew G. Knepley   Input Parameters:
1181dce8aebaSBarry Smith + prob - The `PetscDS` object
1182249df284SMatthew G. Knepley . f - The field number
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`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1188249df284SMatthew G. Knepley @*/
1189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1190d71ae5a4SJacob Faibussowitsch {
1191249df284SMatthew G. Knepley   PetscFunctionBegin;
1192249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
119363a3b9bcSJacob 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);
1194249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
11953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1196249df284SMatthew G. Knepley }
1197249df284SMatthew G. Knepley 
1198f9244615SMatthew G. Knepley /*@
1199f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1200f9244615SMatthew G. Knepley 
1201f9244615SMatthew G. Knepley   Not collective
1202f9244615SMatthew G. Knepley 
1203f9244615SMatthew G. Knepley   Input Parameters:
1204dce8aebaSBarry Smith + ds - The `PetscDS` object
1205f9244615SMatthew G. Knepley - f  - The field number
1206f9244615SMatthew G. Knepley 
1207f9244615SMatthew G. Knepley   Output Parameter:
1208f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1209f9244615SMatthew G. Knepley 
1210f9244615SMatthew G. Knepley   Level: developer
1211f9244615SMatthew G. Knepley 
1212dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1213f9244615SMatthew G. Knepley @*/
1214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1215d71ae5a4SJacob Faibussowitsch {
1216f9244615SMatthew G. Knepley   PetscFunctionBegin;
1217f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1218dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
121963a3b9bcSJacob 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);
1220f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1222f9244615SMatthew G. Knepley }
1223f9244615SMatthew G. Knepley 
1224f9244615SMatthew G. Knepley /*@
1225f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1226f9244615SMatthew G. Knepley 
1227f9244615SMatthew G. Knepley   Not collective
1228f9244615SMatthew G. Knepley 
1229f9244615SMatthew G. Knepley   Input Parameters:
1230dce8aebaSBarry Smith + ds - The `PetscDS` object
1231f9244615SMatthew G. Knepley . f  - The field number
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`, PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1237f9244615SMatthew G. Knepley @*/
1238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1239d71ae5a4SJacob Faibussowitsch {
1240f9244615SMatthew G. Knepley   PetscFunctionBegin;
1241f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
124263a3b9bcSJacob 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);
1243f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1245f9244615SMatthew G. Knepley }
1246f9244615SMatthew G. Knepley 
1247d71ae5a4SJacob 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[]))
1248d71ae5a4SJacob Faibussowitsch {
12496528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
12506528b96dSMatthew G. Knepley   PetscInt        n;
12516528b96dSMatthew G. Knepley 
12522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12546528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
125563a3b9bcSJacob 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);
12569566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
12576528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
12583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12592764a2aaSMatthew G. Knepley }
12602764a2aaSMatthew G. Knepley 
1261d71ae5a4SJacob 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[]))
1262d71ae5a4SJacob Faibussowitsch {
12632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12656528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
126663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
12683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12692764a2aaSMatthew G. Knepley }
12702764a2aaSMatthew G. Knepley 
1271194d53e6SMatthew G. Knepley /*@C
1272194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1273194d53e6SMatthew G. Knepley 
1274194d53e6SMatthew G. Knepley   Not collective
1275194d53e6SMatthew G. Knepley 
1276194d53e6SMatthew G. Knepley   Input Parameters:
1277dce8aebaSBarry Smith + ds - The `PetscDS`
1278194d53e6SMatthew G. Knepley - f  - The test field number
1279194d53e6SMatthew G. Knepley 
1280194d53e6SMatthew G. Knepley   Output Parameters:
1281194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1282194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1283194d53e6SMatthew G. Knepley 
1284dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1285dce8aebaSBarry Smith .vb
1286dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1287dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1288dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1289dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1290dce8aebaSBarry Smith .ve
1291194d53e6SMatthew G. Knepley + dim - the spatial dimension
1292194d53e6SMatthew G. Knepley . Nf - the number of fields
1293194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1294194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1295194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1296194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1297194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1298194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1299194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1300194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1301194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1302194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1303194d53e6SMatthew G. Knepley . t - current time
1304194d53e6SMatthew G. Knepley . x - coordinates of the current point
130597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
130697b6e6e8SMatthew G. Knepley . constants - constant parameters
1307194d53e6SMatthew G. Knepley - f0 - output values at the current point
1308194d53e6SMatthew G. Knepley 
1309194d53e6SMatthew G. Knepley   Level: intermediate
1310194d53e6SMatthew G. Knepley 
1311dce8aebaSBarry Smith   Note:
1312dce8aebaSBarry 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)
1313dce8aebaSBarry Smith 
1314dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1315194d53e6SMatthew G. Knepley @*/
1316d71ae5a4SJacob 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 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 f1[]))
1317d71ae5a4SJacob Faibussowitsch {
13186528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
13196528b96dSMatthew G. Knepley   PetscInt        n0, n1;
13206528b96dSMatthew G. Knepley 
13212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
132363a3b9bcSJacob 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);
13249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13256528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13266528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13282764a2aaSMatthew G. Knepley }
13292764a2aaSMatthew G. Knepley 
1330194d53e6SMatthew G. Knepley /*@C
1331194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1332194d53e6SMatthew G. Knepley 
1333194d53e6SMatthew G. Knepley   Not collective
1334194d53e6SMatthew G. Knepley 
1335194d53e6SMatthew G. Knepley   Input Parameters:
1336dce8aebaSBarry Smith + ds - The `PetscDS`
1337194d53e6SMatthew G. Knepley . f  - The test field number
1338194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1339194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1340194d53e6SMatthew G. Knepley 
1341dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1342dce8aebaSBarry Smith .vb
1343dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1344dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1345dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1346dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1347dce8aebaSBarry Smith .ve
1348194d53e6SMatthew G. Knepley + dim - the spatial dimension
1349194d53e6SMatthew G. Knepley . Nf - the number of fields
1350194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1351194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1352194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1353194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1354194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1355194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1356194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1357194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1358194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1359194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1360194d53e6SMatthew G. Knepley . t - current time
1361194d53e6SMatthew G. Knepley . x - coordinates of the current point
136297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
136397b6e6e8SMatthew G. Knepley . constants - constant parameters
1364194d53e6SMatthew G. Knepley - f0 - output values at the current point
1365194d53e6SMatthew G. Knepley 
1366194d53e6SMatthew G. Knepley   Level: intermediate
1367194d53e6SMatthew G. Knepley 
1368dce8aebaSBarry Smith   Note:
1369dce8aebaSBarry 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)
1370dce8aebaSBarry Smith 
1371dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1372194d53e6SMatthew G. Knepley @*/
1373d71ae5a4SJacob 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 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 f1[]))
1374d71ae5a4SJacob Faibussowitsch {
13752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1377f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1378f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
137963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
13813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13822764a2aaSMatthew G. Knepley }
13832764a2aaSMatthew G. Knepley 
13843e75805dSMatthew G. Knepley /*@C
1385cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1386cb36c0f9SMatthew G. Knepley 
1387cb36c0f9SMatthew G. Knepley   Not collective
1388cb36c0f9SMatthew G. Knepley 
1389cb36c0f9SMatthew G. Knepley   Input Parameters:
1390dce8aebaSBarry Smith + ds - The `PetscDS`
1391cb36c0f9SMatthew G. Knepley - f  - The test field number
1392cb36c0f9SMatthew G. Knepley 
1393cb36c0f9SMatthew G. Knepley   Output Parameters:
1394cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1395cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1396cb36c0f9SMatthew G. Knepley 
1397dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1398dce8aebaSBarry Smith .vb
1399dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1400dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1401dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1402dce8aebaSBarry Smith     PetscReal t, const PetscReal x[], PetscScalar f0[])
1403dce8aebaSBarry Smith .ve
1404cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1405cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1406cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1407cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1408cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1409cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1410cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1411cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1412cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1413cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1414cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1415cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1416cb36c0f9SMatthew G. Knepley . t - current time
1417cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1418cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1419cb36c0f9SMatthew G. Knepley . constants - constant parameters
1420cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1421cb36c0f9SMatthew G. Knepley 
1422cb36c0f9SMatthew G. Knepley   Level: intermediate
1423cb36c0f9SMatthew G. Knepley 
1424dce8aebaSBarry Smith   Note:
1425dce8aebaSBarry 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)
1426dce8aebaSBarry Smith 
1427dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1428cb36c0f9SMatthew G. Knepley @*/
1429d71ae5a4SJacob 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 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 f1[]))
1430d71ae5a4SJacob Faibussowitsch {
1431cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1432cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1433cb36c0f9SMatthew G. Knepley 
1434cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1435cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
143663a3b9bcSJacob 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);
14379566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1438cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1439cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1441cb36c0f9SMatthew G. Knepley }
1442cb36c0f9SMatthew G. Knepley 
1443cb36c0f9SMatthew G. Knepley /*@C
1444cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1445cb36c0f9SMatthew G. Knepley 
1446cb36c0f9SMatthew G. Knepley   Not collective
1447cb36c0f9SMatthew G. Knepley 
1448cb36c0f9SMatthew G. Knepley   Input Parameters:
1449dce8aebaSBarry Smith + ds - The `PetscDS`
1450cb36c0f9SMatthew G. Knepley . f  - The test field number
1451cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1452cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1453cb36c0f9SMatthew G. Knepley 
1454dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1455dce8aebaSBarry Smith .vb
1456dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1457dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1458dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1459dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1460dce8aebaSBarry Smith .ve
1461cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1462cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1463cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1464cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1465cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1466cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1467cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1468cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1469cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1470cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1471cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1472cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1473cb36c0f9SMatthew G. Knepley . t - current time
1474cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1475cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1476cb36c0f9SMatthew G. Knepley . constants - constant parameters
1477cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1478cb36c0f9SMatthew G. Knepley 
1479cb36c0f9SMatthew G. Knepley   Level: intermediate
1480cb36c0f9SMatthew G. Knepley 
1481dce8aebaSBarry Smith   Note:
1482dce8aebaSBarry 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)
1483dce8aebaSBarry Smith 
1484dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1485cb36c0f9SMatthew G. Knepley @*/
1486d71ae5a4SJacob 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 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 f1[]))
1487d71ae5a4SJacob Faibussowitsch {
1488cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1489cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1490cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1491cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
149263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14939566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
14943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1495cb36c0f9SMatthew G. Knepley }
1496cb36c0f9SMatthew G. Knepley 
1497cb36c0f9SMatthew G. Knepley /*@C
1498dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
14993e75805dSMatthew G. Knepley 
15003e75805dSMatthew G. Knepley   Not collective
15013e75805dSMatthew G. Knepley 
15023e75805dSMatthew G. Knepley   Input Parameter:
1503dce8aebaSBarry Smith . prob - The `PetscDS`
15043e75805dSMatthew G. Knepley 
15053e75805dSMatthew G. Knepley   Output Parameter:
15063e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15073e75805dSMatthew G. Knepley 
15083e75805dSMatthew G. Knepley   Level: intermediate
15093e75805dSMatthew G. Knepley 
1510dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15113e75805dSMatthew G. Knepley @*/
1512d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1513d71ae5a4SJacob Faibussowitsch {
15143e75805dSMatthew G. Knepley   PetscFunctionBegin;
15156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
15173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15183e75805dSMatthew G. Knepley }
15193e75805dSMatthew G. Knepley 
1520194d53e6SMatthew G. Knepley /*@C
1521194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1522194d53e6SMatthew G. Knepley 
1523194d53e6SMatthew G. Knepley   Not collective
1524194d53e6SMatthew G. Knepley 
1525194d53e6SMatthew G. Knepley   Input Parameters:
1526dce8aebaSBarry Smith + ds - The `PetscDS`
1527194d53e6SMatthew G. Knepley . f  - The test field number
1528194d53e6SMatthew G. Knepley - g  - The field number
1529194d53e6SMatthew G. Knepley 
1530194d53e6SMatthew G. Knepley   Output Parameters:
1531194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1532194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1533194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1534194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1535194d53e6SMatthew G. Knepley 
1536dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1537dce8aebaSBarry Smith .vb
1538dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1539dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1540dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1541dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1542dce8aebaSBarry Smith .ve
1543194d53e6SMatthew G. Knepley + dim - the spatial dimension
1544194d53e6SMatthew G. Knepley . Nf - the number of fields
1545194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1546194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1547194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1548194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1549194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1550194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1551194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1552194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1553194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1554194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1555194d53e6SMatthew G. Knepley . t - current time
15562aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1557194d53e6SMatthew G. Knepley . x - coordinates of the current point
155897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
155997b6e6e8SMatthew G. Knepley . constants - constant parameters
1560194d53e6SMatthew G. Knepley - g0 - output values at the current point
1561194d53e6SMatthew G. Knepley 
1562194d53e6SMatthew G. Knepley   Level: intermediate
1563194d53e6SMatthew G. Knepley 
1564dce8aebaSBarry Smith   Note:
1565dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1566dce8aebaSBarry 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
1567dce8aebaSBarry Smith 
1568dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1569194d53e6SMatthew G. Knepley @*/
1570d71ae5a4SJacob 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 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 g1[]), void (**g2)(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 g2[]), void (**g3)(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 g3[]))
1571d71ae5a4SJacob Faibussowitsch {
15726528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
15736528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
15746528b96dSMatthew G. Knepley 
15752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
157763a3b9bcSJacob 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);
157863a3b9bcSJacob 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);
15799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
15806528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
15816528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
15826528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
15836528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
15843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15852764a2aaSMatthew G. Knepley }
15862764a2aaSMatthew G. Knepley 
1587194d53e6SMatthew G. Knepley /*@C
1588194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1589194d53e6SMatthew G. Knepley 
1590194d53e6SMatthew G. Knepley   Not collective
1591194d53e6SMatthew G. Knepley 
1592194d53e6SMatthew G. Knepley   Input Parameters:
1593dce8aebaSBarry Smith + ds - The `PetscDS`
1594194d53e6SMatthew G. Knepley . f  - The test field number
1595194d53e6SMatthew G. Knepley . g  - The field number
1596194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1597194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1598194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1599194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1600194d53e6SMatthew G. Knepley 
1601dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1602dce8aebaSBarry Smith .vb
1603dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1604dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1605dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1606dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1607dce8aebaSBarry Smith .ve
1608194d53e6SMatthew G. Knepley + dim - the spatial dimension
1609194d53e6SMatthew G. Knepley . Nf - the number of fields
1610194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1611194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1612194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1613194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1614194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1615194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1616194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1617194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1618194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1619194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1620194d53e6SMatthew G. Knepley . t - current time
16212aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1622194d53e6SMatthew G. Knepley . x - coordinates of the current point
162397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
162497b6e6e8SMatthew G. Knepley . constants - constant parameters
1625194d53e6SMatthew G. Knepley - g0 - output values at the current point
1626194d53e6SMatthew G. Knepley 
1627194d53e6SMatthew G. Knepley   Level: intermediate
1628194d53e6SMatthew G. Knepley 
1629dce8aebaSBarry Smith   Note:
1630dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1631dce8aebaSBarry 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
1632dce8aebaSBarry Smith 
1633dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1634194d53e6SMatthew G. Knepley @*/
1635d71ae5a4SJacob 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 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 g1[]), void (*g2)(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 g2[]), void (*g3)(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 g3[]))
1636d71ae5a4SJacob Faibussowitsch {
16372764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16392764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
16402764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
16412764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
16422764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
164363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
164463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
16459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
16463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16472764a2aaSMatthew G. Knepley }
16482764a2aaSMatthew G. Knepley 
1649475e0ac9SMatthew G. Knepley /*@C
1650dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
165155c1f793SMatthew G. Knepley 
165255c1f793SMatthew G. Knepley   Not collective
165355c1f793SMatthew G. Knepley 
165455c1f793SMatthew G. Knepley   Input Parameters:
1655dce8aebaSBarry Smith + prob - The `PetscDS`
165655c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
165755c1f793SMatthew G. Knepley 
165855c1f793SMatthew G. Knepley   Level: intermediate
165955c1f793SMatthew G. Knepley 
1660dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
166155c1f793SMatthew G. Knepley @*/
1662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1663d71ae5a4SJacob Faibussowitsch {
166455c1f793SMatthew G. Knepley   PetscFunctionBegin;
166555c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
166655c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
16673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166855c1f793SMatthew G. Knepley }
166955c1f793SMatthew G. Knepley 
167055c1f793SMatthew G. Knepley /*@C
1671dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1672475e0ac9SMatthew G. Knepley 
1673475e0ac9SMatthew G. Knepley   Not collective
1674475e0ac9SMatthew G. Knepley 
1675475e0ac9SMatthew G. Knepley   Input Parameter:
1676dce8aebaSBarry Smith . prob - The `PetscDS`
1677475e0ac9SMatthew G. Knepley 
1678475e0ac9SMatthew G. Knepley   Output Parameter:
1679475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1680475e0ac9SMatthew G. Knepley 
1681475e0ac9SMatthew G. Knepley   Level: intermediate
1682475e0ac9SMatthew G. Knepley 
1683dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1684475e0ac9SMatthew G. Knepley @*/
1685d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1686d71ae5a4SJacob Faibussowitsch {
1687475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16886528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1689475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
16903ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
16919566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
16923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1693475e0ac9SMatthew G. Knepley }
1694475e0ac9SMatthew G. Knepley 
1695475e0ac9SMatthew G. Knepley /*@C
1696dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1697dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1698475e0ac9SMatthew G. Knepley 
1699475e0ac9SMatthew G. Knepley   Not collective
1700475e0ac9SMatthew G. Knepley 
1701475e0ac9SMatthew G. Knepley   Input Parameters:
1702dce8aebaSBarry Smith + ds - The `PetscDS`
1703475e0ac9SMatthew G. Knepley . f  - The test field number
1704475e0ac9SMatthew G. Knepley - g  - The field number
1705475e0ac9SMatthew G. Knepley 
1706475e0ac9SMatthew G. Knepley   Output Parameters:
1707475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1708475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1709475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1710475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1711475e0ac9SMatthew G. Knepley 
1712dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1713dce8aebaSBarry Smith .vb
1714dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1715dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1716dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1717dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1718dce8aebaSBarry Smith .ve
1719475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1720475e0ac9SMatthew G. Knepley . Nf - the number of fields
1721475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1722475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1723475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1724475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1725475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1726475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1727475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1728475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1729475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1730475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1731475e0ac9SMatthew G. Knepley . t - current time
1732475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1733475e0ac9SMatthew G. Knepley . x - coordinates of the current point
173497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
173597b6e6e8SMatthew G. Knepley . constants - constant parameters
1736475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1737475e0ac9SMatthew G. Knepley 
1738475e0ac9SMatthew G. Knepley   Level: intermediate
1739475e0ac9SMatthew G. Knepley 
1740dce8aebaSBarry Smith   Note:
1741dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1742dce8aebaSBarry 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
1743dce8aebaSBarry Smith 
1744dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1745475e0ac9SMatthew G. Knepley @*/
1746d71ae5a4SJacob 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 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 g1[]), void (**g2)(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 g2[]), void (**g3)(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 g3[]))
1747d71ae5a4SJacob Faibussowitsch {
17486528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17496528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17506528b96dSMatthew G. Knepley 
1751475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17526528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
175363a3b9bcSJacob 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);
175463a3b9bcSJacob 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);
17559566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17566528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17576528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17586528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17596528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1761475e0ac9SMatthew G. Knepley }
1762475e0ac9SMatthew G. Knepley 
1763475e0ac9SMatthew G. Knepley /*@C
1764dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1765dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1766475e0ac9SMatthew G. Knepley 
1767475e0ac9SMatthew G. Knepley   Not collective
1768475e0ac9SMatthew G. Knepley 
1769475e0ac9SMatthew G. Knepley   Input Parameters:
1770dce8aebaSBarry Smith + ds - The `PetscDS`
1771475e0ac9SMatthew G. Knepley . f  - The test field number
1772475e0ac9SMatthew G. Knepley . g  - The field number
1773475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1774475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1775475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1776475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1777475e0ac9SMatthew G. Knepley 
1778dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1779dce8aebaSBarry Smith .vb
1780dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1781dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1782dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1783dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1784dce8aebaSBarry Smith .ve
1785475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1786475e0ac9SMatthew G. Knepley . Nf - the number of fields
1787475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1788475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1789475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1790475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1791475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1792475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1793475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1794475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1795475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1796475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1797475e0ac9SMatthew G. Knepley . t - current time
1798475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1799475e0ac9SMatthew G. Knepley . x - coordinates of the current point
180097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
180197b6e6e8SMatthew G. Knepley . constants - constant parameters
1802475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1803475e0ac9SMatthew G. Knepley 
1804475e0ac9SMatthew G. Knepley   Level: intermediate
1805475e0ac9SMatthew G. Knepley 
1806dce8aebaSBarry Smith   Note:
1807dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1808dce8aebaSBarry 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
1809dce8aebaSBarry Smith 
1810dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1811475e0ac9SMatthew G. Knepley @*/
1812d71ae5a4SJacob 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 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 g1[]), void (*g2)(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 g2[]), void (*g3)(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 g3[]))
1813d71ae5a4SJacob Faibussowitsch {
1814475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1816475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1817475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1818475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1819475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
182063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
182163a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1824475e0ac9SMatthew G. Knepley }
1825475e0ac9SMatthew G. Knepley 
1826b7e05686SMatthew G. Knepley /*@C
1827b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1828b7e05686SMatthew G. Knepley 
1829b7e05686SMatthew G. Knepley   Not collective
1830b7e05686SMatthew G. Knepley 
1831b7e05686SMatthew G. Knepley   Input Parameter:
1832dce8aebaSBarry Smith . ds - The `PetscDS`
1833b7e05686SMatthew G. Knepley 
1834b7e05686SMatthew G. Knepley   Output Parameter:
1835b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1836b7e05686SMatthew G. Knepley 
1837b7e05686SMatthew G. Knepley   Level: intermediate
1838b7e05686SMatthew G. Knepley 
1839dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1840b7e05686SMatthew G. Knepley @*/
1841d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1842d71ae5a4SJacob Faibussowitsch {
1843b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18446528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
18463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1847b7e05686SMatthew G. Knepley }
1848b7e05686SMatthew G. Knepley 
1849b7e05686SMatthew G. Knepley /*@C
1850b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1851b7e05686SMatthew G. Knepley 
1852b7e05686SMatthew G. Knepley   Not collective
1853b7e05686SMatthew G. Knepley 
1854b7e05686SMatthew G. Knepley   Input Parameters:
1855dce8aebaSBarry Smith + ds - The `PetscDS`
1856b7e05686SMatthew G. Knepley . f  - The test field number
1857b7e05686SMatthew G. Knepley - g  - The field number
1858b7e05686SMatthew G. Knepley 
1859b7e05686SMatthew G. Knepley   Output Parameters:
1860b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1861b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1862b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1863b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1864b7e05686SMatthew G. Knepley 
1865dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
1866dce8aebaSBarry Smith .vb
1867dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1868dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1869dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1870dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1871dce8aebaSBarry Smith .ve
1872b7e05686SMatthew G. Knepley + dim - the spatial dimension
1873b7e05686SMatthew G. Knepley . Nf - the number of fields
1874b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1875b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1876b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1877b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1878b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1879b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1880b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1881b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1882b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1883b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1884b7e05686SMatthew G. Knepley . t - current time
1885b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1886b7e05686SMatthew G. Knepley . x - coordinates of the current point
188797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
188897b6e6e8SMatthew G. Knepley . constants - constant parameters
1889b7e05686SMatthew G. Knepley - g0 - output values at the current point
1890b7e05686SMatthew G. Knepley 
1891b7e05686SMatthew G. Knepley   Level: intermediate
1892b7e05686SMatthew G. Knepley 
1893dce8aebaSBarry Smith   Note:
1894dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1895dce8aebaSBarry 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
1896dce8aebaSBarry Smith 
1897dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1898b7e05686SMatthew G. Knepley @*/
1899d71ae5a4SJacob 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 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 g1[]), void (**g2)(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 g2[]), void (**g3)(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 g3[]))
1900d71ae5a4SJacob Faibussowitsch {
19016528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19026528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19036528b96dSMatthew G. Knepley 
1904b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19056528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
190663a3b9bcSJacob 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);
190763a3b9bcSJacob 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);
19089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19096528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19106528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19116528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19126528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1914b7e05686SMatthew G. Knepley }
1915b7e05686SMatthew G. Knepley 
1916b7e05686SMatthew G. Knepley /*@C
1917b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1918b7e05686SMatthew G. Knepley 
1919b7e05686SMatthew G. Knepley   Not collective
1920b7e05686SMatthew G. Knepley 
1921b7e05686SMatthew G. Knepley   Input Parameters:
1922dce8aebaSBarry Smith + ds - The `PetscDS`
1923b7e05686SMatthew G. Knepley . f  - The test field number
1924b7e05686SMatthew G. Knepley . g  - The field number
1925b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1926b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1927b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1928b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1929b7e05686SMatthew G. Knepley 
1930dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1931dce8aebaSBarry Smith .vb
1932dce8aebaSBarry Smith    g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1933dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1934dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1935dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1936dce8aebaSBarry Smith .ve
1937b7e05686SMatthew G. Knepley + dim - the spatial dimension
1938b7e05686SMatthew G. Knepley . Nf - the number of fields
1939b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1940b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1941b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1942b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1943b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1944b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1945b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1946b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1947b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1948b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1949b7e05686SMatthew G. Knepley . t - current time
1950b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1951b7e05686SMatthew G. Knepley . x - coordinates of the current point
195297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
195397b6e6e8SMatthew G. Knepley . constants - constant parameters
1954b7e05686SMatthew G. Knepley - g0 - output values at the current point
1955b7e05686SMatthew G. Knepley 
1956b7e05686SMatthew G. Knepley   Level: intermediate
1957b7e05686SMatthew G. Knepley 
1958dce8aebaSBarry Smith   Note:
1959dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1960dce8aebaSBarry 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
1961dce8aebaSBarry Smith 
1962dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1963b7e05686SMatthew G. Knepley @*/
1964d71ae5a4SJacob 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 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 g1[]), void (*g2)(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 g2[]), void (*g3)(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 g3[]))
1965d71ae5a4SJacob Faibussowitsch {
1966b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1968b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1969b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1970b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1971b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
197263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
197363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19749566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1976b7e05686SMatthew G. Knepley }
1977b7e05686SMatthew G. Knepley 
19780c2f2876SMatthew G. Knepley /*@C
19790c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
19800c2f2876SMatthew G. Knepley 
19810c2f2876SMatthew G. Knepley   Not collective
19820c2f2876SMatthew G. Knepley 
19834165533cSJose E. Roman   Input Parameters:
1984dce8aebaSBarry Smith + ds - The `PetscDS` object
19850c2f2876SMatthew G. Knepley - f  - The field number
19860c2f2876SMatthew G. Knepley 
19874165533cSJose E. Roman   Output Parameter:
19880c2f2876SMatthew G. Knepley . r    - Riemann solver
19890c2f2876SMatthew G. Knepley 
19900c2f2876SMatthew G. Knepley   Calling sequence for r:
1991dce8aebaSBarry Smith .vb
1992dce8aebaSBarry Smith   r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1993dce8aebaSBarry Smith .ve
19945db36cf9SMatthew G. Knepley + dim  - The spatial dimension
19955db36cf9SMatthew G. Knepley . Nf   - The number of fields
19965db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
19970c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
19980c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
19990c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20000c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
200197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
200297b6e6e8SMatthew G. Knepley . constants - constant parameters
20030c2f2876SMatthew G. Knepley - ctx  - optional user context
20040c2f2876SMatthew G. Knepley 
20050c2f2876SMatthew G. Knepley   Level: intermediate
20060c2f2876SMatthew G. Knepley 
2007dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20080c2f2876SMatthew G. Knepley @*/
2009d71ae5a4SJacob 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))
2010d71ae5a4SJacob Faibussowitsch {
20116528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20126528b96dSMatthew G. Knepley   PetscInt          n;
20136528b96dSMatthew G. Knepley 
20140c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20160c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
201763a3b9bcSJacob 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);
20189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20196528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20210c2f2876SMatthew G. Knepley }
20220c2f2876SMatthew G. Knepley 
20230c2f2876SMatthew G. Knepley /*@C
20240c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20250c2f2876SMatthew G. Knepley 
20260c2f2876SMatthew G. Knepley   Not collective
20270c2f2876SMatthew G. Knepley 
20284165533cSJose E. Roman   Input Parameters:
2029dce8aebaSBarry Smith + ds - The `PetscDS` object
20300c2f2876SMatthew G. Knepley . f  - The field number
20310c2f2876SMatthew G. Knepley - r  - Riemann solver
20320c2f2876SMatthew G. Knepley 
20330c2f2876SMatthew G. Knepley   Calling sequence for r:
2034dce8aebaSBarry Smith .vb
2035dce8aebaSBarry Smith    r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2036dce8aebaSBarry Smith .ve
20375db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20385db36cf9SMatthew G. Knepley . Nf   - The number of fields
20395db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20400c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20410c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20420c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20430c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
204497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
204597b6e6e8SMatthew G. Knepley . constants - constant parameters
20460c2f2876SMatthew G. Knepley - ctx  - optional user context
20470c2f2876SMatthew G. Knepley 
20480c2f2876SMatthew G. Knepley   Level: intermediate
20490c2f2876SMatthew G. Knepley 
2050dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
20510c2f2876SMatthew G. Knepley @*/
2052d71ae5a4SJacob 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))
2053d71ae5a4SJacob Faibussowitsch {
20540c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20556528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2056de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
205763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20589566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
20593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20600c2f2876SMatthew G. Knepley }
20610c2f2876SMatthew G. Knepley 
206232d2bbc9SMatthew G. Knepley /*@C
206332d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
206432d2bbc9SMatthew G. Knepley 
206532d2bbc9SMatthew G. Knepley   Not collective
206632d2bbc9SMatthew G. Knepley 
206732d2bbc9SMatthew G. Knepley   Input Parameters:
2068dce8aebaSBarry Smith + ds - The `PetscDS`
206932d2bbc9SMatthew G. Knepley - f  - The field number
207032d2bbc9SMatthew G. Knepley 
2071f899ff85SJose E. Roman   Output Parameter:
2072a2b725a8SWilliam Gropp . update - update function
207332d2bbc9SMatthew G. Knepley 
2074dce8aebaSBarry Smith   Calling sequence for the callback update:
2075dce8aebaSBarry Smith .vb
2076dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2077dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2078dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2079dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2080dce8aebaSBarry Smith .ve
208132d2bbc9SMatthew G. Knepley + dim - the spatial dimension
208232d2bbc9SMatthew G. Knepley . Nf - the number of fields
208332d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
208432d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
208532d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
208632d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
208732d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
208832d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
208932d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
209032d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
209132d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
209232d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
209332d2bbc9SMatthew G. Knepley . t - current time
209432d2bbc9SMatthew G. Knepley . x - coordinates of the current point
209532d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
209632d2bbc9SMatthew G. Knepley 
209732d2bbc9SMatthew G. Knepley   Level: intermediate
209832d2bbc9SMatthew G. Knepley 
2099dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
210032d2bbc9SMatthew G. Knepley @*/
2101d71ae5a4SJacob 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[]))
2102d71ae5a4SJacob Faibussowitsch {
210332d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
210563a3b9bcSJacob 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);
21069371c9d4SSatish Balay   if (update) {
21079371c9d4SSatish Balay     PetscValidPointer(update, 3);
21089371c9d4SSatish Balay     *update = ds->update[f];
21099371c9d4SSatish Balay   }
21103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211132d2bbc9SMatthew G. Knepley }
211232d2bbc9SMatthew G. Knepley 
211332d2bbc9SMatthew G. Knepley /*@C
21143fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
211532d2bbc9SMatthew G. Knepley 
211632d2bbc9SMatthew G. Knepley   Not collective
211732d2bbc9SMatthew G. Knepley 
211832d2bbc9SMatthew G. Knepley   Input Parameters:
2119dce8aebaSBarry Smith + ds     - The `PetscDS`
212032d2bbc9SMatthew G. Knepley . f      - The field number
212132d2bbc9SMatthew G. Knepley - update - update function
212232d2bbc9SMatthew G. Knepley 
2123dce8aebaSBarry Smith   Calling sequence for the callback update:
2124dce8aebaSBarry Smith .vb
2125dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2126dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2127dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2128dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2129dce8aebaSBarry Smith .ve
213032d2bbc9SMatthew G. Knepley + dim - the spatial dimension
213132d2bbc9SMatthew G. Knepley . Nf - the number of fields
213232d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
213332d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
213432d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
213532d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
213632d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
213732d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
213832d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
213932d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
214032d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
214132d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
214232d2bbc9SMatthew G. Knepley . t - current time
214332d2bbc9SMatthew G. Knepley . x - coordinates of the current point
214432d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
214532d2bbc9SMatthew G. Knepley 
214632d2bbc9SMatthew G. Knepley   Level: intermediate
214732d2bbc9SMatthew G. Knepley 
2148dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
214932d2bbc9SMatthew G. Knepley @*/
2150d71ae5a4SJacob 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[]))
2151d71ae5a4SJacob Faibussowitsch {
215232d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
215432d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
215563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21569566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21576528b96dSMatthew G. Knepley   ds->update[f] = update;
21583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
215932d2bbc9SMatthew G. Knepley }
216032d2bbc9SMatthew G. Knepley 
2161d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2162d71ae5a4SJacob Faibussowitsch {
21630c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216563a3b9bcSJacob 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);
21660c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
21673ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
21683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21690c2f2876SMatthew G. Knepley }
21700c2f2876SMatthew G. Knepley 
2171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2172d71ae5a4SJacob Faibussowitsch {
21730c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21746528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21769566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21776528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
21783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21790c2f2876SMatthew G. Knepley }
21800c2f2876SMatthew G. Knepley 
2181194d53e6SMatthew G. Knepley /*@C
2182194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2183194d53e6SMatthew G. Knepley 
2184194d53e6SMatthew G. Knepley   Not collective
2185194d53e6SMatthew G. Knepley 
2186194d53e6SMatthew G. Knepley   Input Parameters:
21876528b96dSMatthew G. Knepley + ds - The PetscDS
2188194d53e6SMatthew G. Knepley - f  - The test field number
2189194d53e6SMatthew G. Knepley 
2190194d53e6SMatthew G. Knepley   Output Parameters:
2191194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2192194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2193194d53e6SMatthew G. Knepley 
2194dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2195dce8aebaSBarry Smith .vb
2196dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2197dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2198dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2199dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2200dce8aebaSBarry Smith .ve
2201194d53e6SMatthew G. Knepley + dim - the spatial dimension
2202194d53e6SMatthew G. Knepley . Nf - the number of fields
2203194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2204194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2205194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2206194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2207194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2208194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2209194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2210194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2211194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2212194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2213194d53e6SMatthew G. Knepley . t - current time
2214194d53e6SMatthew G. Knepley . x - coordinates of the current point
2215194d53e6SMatthew G. Knepley . n - unit normal at the current point
221697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
221797b6e6e8SMatthew G. Knepley . constants - constant parameters
2218194d53e6SMatthew G. Knepley - f0 - output values at the current point
2219194d53e6SMatthew G. Knepley 
2220194d53e6SMatthew G. Knepley   Level: intermediate
2221194d53e6SMatthew G. Knepley 
2222dce8aebaSBarry Smith   Note:
2223dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2224dce8aebaSBarry 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
2225dce8aebaSBarry Smith 
2226dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2227194d53e6SMatthew G. Knepley @*/
2228d71ae5a4SJacob 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 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 f1[]))
2229d71ae5a4SJacob Faibussowitsch {
22306528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22316528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22326528b96dSMatthew G. Knepley 
22332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22346528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223563a3b9bcSJacob 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);
22369566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22376528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22386528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22402764a2aaSMatthew G. Knepley }
22412764a2aaSMatthew G. Knepley 
2242194d53e6SMatthew G. Knepley /*@C
2243194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2244194d53e6SMatthew G. Knepley 
2245194d53e6SMatthew G. Knepley   Not collective
2246194d53e6SMatthew G. Knepley 
2247194d53e6SMatthew G. Knepley   Input Parameters:
2248dce8aebaSBarry Smith + ds - The `PetscDS`
2249194d53e6SMatthew G. Knepley . f  - The test field number
2250194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2251194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2252194d53e6SMatthew G. Knepley 
2253dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2254dce8aebaSBarry Smith .vb
2255dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2256dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2257dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2258dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2259dce8aebaSBarry Smith .ve
2260194d53e6SMatthew G. Knepley + dim - the spatial dimension
2261194d53e6SMatthew G. Knepley . Nf - the number of fields
2262194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2263194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2264194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2265194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2266194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2267194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2268194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2269194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2270194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2271194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2272194d53e6SMatthew G. Knepley . t - current time
2273194d53e6SMatthew G. Knepley . x - coordinates of the current point
2274194d53e6SMatthew G. Knepley . n - unit normal at the current point
227597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
227697b6e6e8SMatthew G. Knepley . constants - constant parameters
2277194d53e6SMatthew G. Knepley - f0 - output values at the current point
2278194d53e6SMatthew G. Knepley 
2279194d53e6SMatthew G. Knepley   Level: intermediate
2280194d53e6SMatthew G. Knepley 
2281dce8aebaSBarry Smith   Note:
2282dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2283dce8aebaSBarry 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
2284dce8aebaSBarry Smith 
2285dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2286194d53e6SMatthew G. Knepley @*/
2287d71ae5a4SJacob 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 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 f1[]))
2288d71ae5a4SJacob Faibussowitsch {
22892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22929566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
22933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22942764a2aaSMatthew G. Knepley }
22952764a2aaSMatthew G. Knepley 
229627f02ce8SMatthew G. Knepley /*@
2297dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
229827f02ce8SMatthew G. Knepley 
229927f02ce8SMatthew G. Knepley   Not collective
230027f02ce8SMatthew G. Knepley 
230127f02ce8SMatthew G. Knepley   Input Parameter:
2302dce8aebaSBarry Smith . ds - The `PetscDS`
230327f02ce8SMatthew G. Knepley 
230427f02ce8SMatthew G. Knepley   Output Parameter:
230527f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
230627f02ce8SMatthew G. Knepley 
230727f02ce8SMatthew G. Knepley   Level: intermediate
230827f02ce8SMatthew G. Knepley 
2309dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
231027f02ce8SMatthew G. Knepley @*/
2311d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2312d71ae5a4SJacob Faibussowitsch {
231327f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23156528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
23169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
231827f02ce8SMatthew G. Knepley }
231927f02ce8SMatthew G. Knepley 
2320194d53e6SMatthew G. Knepley /*@C
2321194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2322194d53e6SMatthew G. Knepley 
2323194d53e6SMatthew G. Knepley   Not collective
2324194d53e6SMatthew G. Knepley 
2325194d53e6SMatthew G. Knepley   Input Parameters:
2326dce8aebaSBarry Smith + ds - The `PetscDS`
2327194d53e6SMatthew G. Knepley . f  - The test field number
2328194d53e6SMatthew G. Knepley - g  - The field number
2329194d53e6SMatthew G. Knepley 
2330194d53e6SMatthew G. Knepley   Output Parameters:
2331194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2332194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2333194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2334194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2335194d53e6SMatthew G. Knepley 
2336dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2337dce8aebaSBarry Smith .vb
2338dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2339dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2340dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2341dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2342dce8aebaSBarry Smith .ve
2343194d53e6SMatthew G. Knepley + dim - the spatial dimension
2344194d53e6SMatthew G. Knepley . Nf - the number of fields
2345194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2346194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2347194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2348194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2349194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2350194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2351194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2352194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2353194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2354194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2355194d53e6SMatthew G. Knepley . t - current time
23562aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2357194d53e6SMatthew G. Knepley . x - coordinates of the current point
2358194d53e6SMatthew G. Knepley . n - normal at the current point
235997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
236097b6e6e8SMatthew G. Knepley . constants - constant parameters
2361194d53e6SMatthew G. Knepley - g0 - output values at the current point
2362194d53e6SMatthew G. Knepley 
2363194d53e6SMatthew G. Knepley   Level: intermediate
2364194d53e6SMatthew G. Knepley 
2365dce8aebaSBarry Smith   Note:
2366dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2367dce8aebaSBarry 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
2368dce8aebaSBarry Smith 
2369dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2370194d53e6SMatthew G. Knepley @*/
2371d71ae5a4SJacob 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 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 g1[]), void (**g2)(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 g2[]), void (**g3)(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 g3[]))
2372d71ae5a4SJacob Faibussowitsch {
23736528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
23746528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
23756528b96dSMatthew G. Knepley 
23762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
237863a3b9bcSJacob 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);
237963a3b9bcSJacob 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);
23809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
23816528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
23826528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
23836528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
23846528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
23853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23862764a2aaSMatthew G. Knepley }
23872764a2aaSMatthew G. Knepley 
2388194d53e6SMatthew G. Knepley /*@C
2389194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2390194d53e6SMatthew G. Knepley 
2391194d53e6SMatthew G. Knepley   Not collective
2392194d53e6SMatthew G. Knepley 
2393194d53e6SMatthew G. Knepley   Input Parameters:
23946528b96dSMatthew G. Knepley + ds - The PetscDS
2395194d53e6SMatthew G. Knepley . f  - The test field number
2396194d53e6SMatthew G. Knepley . g  - The field number
2397194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2398194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2399194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2400194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2401194d53e6SMatthew G. Knepley 
2402dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2403dce8aebaSBarry Smith .vb
2404dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2405dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2406dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2407dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2408dce8aebaSBarry Smith .ve
2409194d53e6SMatthew G. Knepley + dim - the spatial dimension
2410194d53e6SMatthew G. Knepley . Nf - the number of fields
2411194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2412194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2413194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2414194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2415194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2416194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2417194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2418194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2419194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2420194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2421194d53e6SMatthew G. Knepley . t - current time
24222aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2423194d53e6SMatthew G. Knepley . x - coordinates of the current point
2424194d53e6SMatthew G. Knepley . n - normal at the current point
242597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
242697b6e6e8SMatthew G. Knepley . constants - constant parameters
2427194d53e6SMatthew G. Knepley - g0 - output values at the current point
2428194d53e6SMatthew G. Knepley 
2429194d53e6SMatthew G. Knepley   Level: intermediate
2430194d53e6SMatthew G. Knepley 
2431dce8aebaSBarry Smith   Note:
2432dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2433dce8aebaSBarry 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
2434dce8aebaSBarry Smith 
2435dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2436194d53e6SMatthew G. Knepley @*/
2437d71ae5a4SJacob 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 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 g1[]), void (*g2)(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 g2[]), void (*g3)(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 g3[]))
2438d71ae5a4SJacob Faibussowitsch {
24392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24406528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24412764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24422764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24432764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24442764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
244563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
244663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24492764a2aaSMatthew G. Knepley }
24502764a2aaSMatthew G. Knepley 
245127f02ce8SMatthew G. Knepley /*@
245227f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
245327f02ce8SMatthew G. Knepley 
245427f02ce8SMatthew G. Knepley   Not collective
245527f02ce8SMatthew G. Knepley 
245627f02ce8SMatthew G. Knepley   Input Parameter:
2457dce8aebaSBarry Smith . ds - The `PetscDS`
245827f02ce8SMatthew G. Knepley 
245927f02ce8SMatthew G. Knepley   Output Parameter:
246027f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
246127f02ce8SMatthew G. Knepley 
246227f02ce8SMatthew G. Knepley   Level: intermediate
246327f02ce8SMatthew G. Knepley 
2464dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
246527f02ce8SMatthew G. Knepley @*/
2466d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2467d71ae5a4SJacob Faibussowitsch {
246827f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24696528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24706528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
24719566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
24723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
247327f02ce8SMatthew G. Knepley }
247427f02ce8SMatthew G. Knepley 
247527f02ce8SMatthew G. Knepley /*@C
247627f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
247727f02ce8SMatthew G. Knepley 
247827f02ce8SMatthew G. Knepley   Not collective
247927f02ce8SMatthew G. Knepley 
248027f02ce8SMatthew G. Knepley   Input Parameters:
2481dce8aebaSBarry Smith + ds - The `PetscDS`
248227f02ce8SMatthew G. Knepley . f  - The test field number
248327f02ce8SMatthew G. Knepley - g  - The field number
248427f02ce8SMatthew G. Knepley 
248527f02ce8SMatthew G. Knepley   Output Parameters:
248627f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
248727f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
248827f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
248927f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
249027f02ce8SMatthew G. Knepley 
2491dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2492dce8aebaSBarry Smith .vb
2493dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2494dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2495dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2496dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2497dce8aebaSBarry Smith .ve
249827f02ce8SMatthew G. Knepley + dim - the spatial dimension
249927f02ce8SMatthew G. Knepley . Nf - the number of fields
250027f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
250127f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
250227f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
250327f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
250427f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
250527f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
250627f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
250727f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
250827f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
250927f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
251027f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
251127f02ce8SMatthew G. Knepley . t - current time
251227f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
251327f02ce8SMatthew G. Knepley . x - coordinates of the current point
251427f02ce8SMatthew G. Knepley . n - normal at the current point
251527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
251627f02ce8SMatthew G. Knepley . constants - constant parameters
251727f02ce8SMatthew G. Knepley - g0 - output values at the current point
251827f02ce8SMatthew G. Knepley 
251927f02ce8SMatthew G. Knepley   Level: intermediate
252027f02ce8SMatthew G. Knepley 
2521dce8aebaSBarry Smith   Note:
2522dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2523dce8aebaSBarry 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
2524dce8aebaSBarry Smith 
2525dce8aebaSBarry Smith   Fortran Note:
2526dce8aebaSBarry Smith   This is not yet available in Fortran.
2527dce8aebaSBarry Smith 
2528dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
252927f02ce8SMatthew G. Knepley @*/
2530d71ae5a4SJacob 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 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 g1[]), void (**g2)(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 g2[]), void (**g3)(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 g3[]))
2531d71ae5a4SJacob Faibussowitsch {
25326528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25336528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25346528b96dSMatthew G. Knepley 
253527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25366528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
253763a3b9bcSJacob 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);
253863a3b9bcSJacob 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);
25399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25406528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25416528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25426528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25436528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
254527f02ce8SMatthew G. Knepley }
254627f02ce8SMatthew G. Knepley 
254727f02ce8SMatthew G. Knepley /*@C
254827f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
254927f02ce8SMatthew G. Knepley 
255027f02ce8SMatthew G. Knepley   Not collective
255127f02ce8SMatthew G. Knepley 
255227f02ce8SMatthew G. Knepley   Input Parameters:
2553dce8aebaSBarry Smith + ds - The `PetscDS`
255427f02ce8SMatthew G. Knepley . f  - The test field number
255527f02ce8SMatthew G. Knepley . g  - The field number
255627f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
255727f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
255827f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
255927f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
256027f02ce8SMatthew G. Knepley 
2561dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2562dce8aebaSBarry Smith .vb
2563dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2564dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2565dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2566dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2567dce8aebaSBarry Smith .ve
256827f02ce8SMatthew G. Knepley + dim - the spatial dimension
256927f02ce8SMatthew G. Knepley . Nf - the number of fields
257027f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
257127f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
257227f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
257327f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
257427f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
257527f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
257627f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
257727f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
257827f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
257927f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
258027f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
258127f02ce8SMatthew G. Knepley . t - current time
258227f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
258327f02ce8SMatthew G. Knepley . x - coordinates of the current point
258427f02ce8SMatthew G. Knepley . n - normal at the current point
258527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
258627f02ce8SMatthew G. Knepley . constants - constant parameters
258727f02ce8SMatthew G. Knepley - g0 - output values at the current point
258827f02ce8SMatthew G. Knepley 
258927f02ce8SMatthew G. Knepley   Level: intermediate
259027f02ce8SMatthew G. Knepley 
2591dce8aebaSBarry Smith   Note:
2592dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2593dce8aebaSBarry 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
2594dce8aebaSBarry Smith 
2595dce8aebaSBarry Smith   Fortran Note:
2596dce8aebaSBarry Smith   This is not yet available in Fortran.
2597dce8aebaSBarry Smith 
2598dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
259927f02ce8SMatthew G. Knepley @*/
2600d71ae5a4SJacob 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 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 g1[]), void (*g2)(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 g2[]), void (*g3)(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 g3[]))
2601d71ae5a4SJacob Faibussowitsch {
260227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
260427f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
260527f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
260627f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
260727f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
260863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
260963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
261227f02ce8SMatthew G. Knepley }
261327f02ce8SMatthew G. Knepley 
26140d3e9b51SMatthew G. Knepley /*@C
2615c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2616c371a6d1SMatthew G. Knepley 
2617c371a6d1SMatthew G. Knepley   Not collective
2618c371a6d1SMatthew G. Knepley 
2619c371a6d1SMatthew G. Knepley   Input Parameters:
2620c371a6d1SMatthew G. Knepley + prob - The PetscDS
2621c371a6d1SMatthew G. Knepley - f    - The test field number
2622c371a6d1SMatthew G. Knepley 
2623d8d19677SJose E. Roman   Output Parameters:
262495cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
262595cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2626c371a6d1SMatthew G. Knepley 
2627dce8aebaSBarry Smith   Calling sequence for the solution functions:
2628dce8aebaSBarry Smith .vb
2629dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2630dce8aebaSBarry Smith .ve
2631c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2632c371a6d1SMatthew G. Knepley . t - current time
2633c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2634c371a6d1SMatthew G. Knepley . Nc - the number of field components
2635c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2636c371a6d1SMatthew G. Knepley - ctx - a user context
2637c371a6d1SMatthew G. Knepley 
2638c371a6d1SMatthew G. Knepley   Level: intermediate
2639c371a6d1SMatthew G. Knepley 
2640dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2641c371a6d1SMatthew G. Knepley @*/
2642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2643d71ae5a4SJacob Faibussowitsch {
2644c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2645c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
264663a3b9bcSJacob 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);
26479371c9d4SSatish Balay   if (sol) {
26489371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26499371c9d4SSatish Balay     *sol = prob->exactSol[f];
26509371c9d4SSatish Balay   }
26519371c9d4SSatish Balay   if (ctx) {
26529371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26539371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26549371c9d4SSatish Balay   }
26553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2656c371a6d1SMatthew G. Knepley }
2657c371a6d1SMatthew G. Knepley 
2658c371a6d1SMatthew G. Knepley /*@C
2659578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2660c371a6d1SMatthew G. Knepley 
2661c371a6d1SMatthew G. Knepley   Not collective
2662c371a6d1SMatthew G. Knepley 
2663c371a6d1SMatthew G. Knepley   Input Parameters:
2664dce8aebaSBarry Smith + prob - The `PetscDS`
2665c371a6d1SMatthew G. Knepley . f    - The test field number
266695cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
266795cbbfd3SMatthew G. Knepley - ctx  - solution context or NULL
2668c371a6d1SMatthew G. Knepley 
2669dce8aebaSBarry Smith   Calling sequence for solution functions:
2670dce8aebaSBarry Smith .vb
2671dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2672dce8aebaSBarry Smith .ve
2673c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2674c371a6d1SMatthew G. Knepley . t - current time
2675c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2676c371a6d1SMatthew G. Knepley . Nc - the number of field components
2677c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2678c371a6d1SMatthew G. Knepley - ctx - a user context
2679c371a6d1SMatthew G. Knepley 
2680c371a6d1SMatthew G. Knepley   Level: intermediate
2681c371a6d1SMatthew G. Knepley 
2682dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2683c371a6d1SMatthew G. Knepley @*/
2684d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2685d71ae5a4SJacob Faibussowitsch {
2686c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2687c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
268863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
26899566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
26909371c9d4SSatish Balay   if (sol) {
26919371c9d4SSatish Balay     PetscValidFunction(sol, 3);
26929371c9d4SSatish Balay     prob->exactSol[f] = sol;
26939371c9d4SSatish Balay   }
26949371c9d4SSatish Balay   if (ctx) {
26959371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
26969371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
26979371c9d4SSatish Balay   }
26983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2699c371a6d1SMatthew G. Knepley }
2700c371a6d1SMatthew G. Knepley 
27015638fd0eSMatthew G. Knepley /*@C
2702f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2703f2cacb80SMatthew G. Knepley 
2704f2cacb80SMatthew G. Knepley   Not collective
2705f2cacb80SMatthew G. Knepley 
2706f2cacb80SMatthew G. Knepley   Input Parameters:
2707dce8aebaSBarry Smith + prob - The `PetscDS`
2708f2cacb80SMatthew G. Knepley - f    - The test field number
2709f2cacb80SMatthew G. Knepley 
2710d8d19677SJose E. Roman   Output Parameters:
2711f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2712f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2713f2cacb80SMatthew G. Knepley 
2714dce8aebaSBarry Smith   Calling sequence for the solution functions:
2715dce8aebaSBarry Smith .vb
2716dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2717dce8aebaSBarry Smith .ve
2718f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2719f2cacb80SMatthew G. Knepley . t - current time
2720f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2721f2cacb80SMatthew G. Knepley . Nc - the number of field components
2722f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2723f2cacb80SMatthew G. Knepley - ctx - a user context
2724f2cacb80SMatthew G. Knepley 
2725f2cacb80SMatthew G. Knepley   Level: intermediate
2726f2cacb80SMatthew G. Knepley 
2727dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2728f2cacb80SMatthew G. Knepley @*/
2729d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2730d71ae5a4SJacob Faibussowitsch {
2731f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2732f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
273363a3b9bcSJacob 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);
27349371c9d4SSatish Balay   if (sol) {
27359371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27369371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27379371c9d4SSatish Balay   }
27389371c9d4SSatish Balay   if (ctx) {
27399371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27409371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27419371c9d4SSatish Balay   }
27423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2743f2cacb80SMatthew G. Knepley }
2744f2cacb80SMatthew G. Knepley 
2745f2cacb80SMatthew G. Knepley /*@C
2746f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2747f2cacb80SMatthew G. Knepley 
2748f2cacb80SMatthew G. Knepley   Not collective
2749f2cacb80SMatthew G. Knepley 
2750f2cacb80SMatthew G. Knepley   Input Parameters:
2751dce8aebaSBarry Smith + prob - The `PetscDS`
2752f2cacb80SMatthew G. Knepley . f    - The test field number
2753f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
2754f2cacb80SMatthew G. Knepley - ctx  - time derivative of the solution context or NULL
2755f2cacb80SMatthew G. Knepley 
2756dce8aebaSBarry Smith   Calling sequence for solution functions:
2757dce8aebaSBarry Smith .vb
2758dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2759dce8aebaSBarry Smith .ve
2760f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2761f2cacb80SMatthew G. Knepley . t - current time
2762f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2763f2cacb80SMatthew G. Knepley . Nc - the number of field components
2764f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2765f2cacb80SMatthew G. Knepley - ctx - a user context
2766f2cacb80SMatthew G. Knepley 
2767f2cacb80SMatthew G. Knepley   Level: intermediate
2768f2cacb80SMatthew G. Knepley 
2769dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2770f2cacb80SMatthew G. Knepley @*/
2771d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2772d71ae5a4SJacob Faibussowitsch {
2773f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2774f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
277563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27769566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27779371c9d4SSatish Balay   if (sol) {
27789371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27799371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
27809371c9d4SSatish Balay   }
27819371c9d4SSatish Balay   if (ctx) {
27829371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27839371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
27849371c9d4SSatish Balay   }
27853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2786f2cacb80SMatthew G. Knepley }
2787f2cacb80SMatthew G. Knepley 
2788f2cacb80SMatthew G. Knepley /*@C
278997b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
279097b6e6e8SMatthew G. Knepley 
279197b6e6e8SMatthew G. Knepley   Not collective
279297b6e6e8SMatthew G. Knepley 
279397b6e6e8SMatthew G. Knepley   Input Parameter:
2794dce8aebaSBarry Smith . prob - The `PetscDS` object
279597b6e6e8SMatthew G. Knepley 
279697b6e6e8SMatthew G. Knepley   Output Parameters:
279797b6e6e8SMatthew G. Knepley + numConstants - The number of constants
279897b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
279997b6e6e8SMatthew G. Knepley 
280097b6e6e8SMatthew G. Knepley   Level: intermediate
280197b6e6e8SMatthew G. Knepley 
2802dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
280397b6e6e8SMatthew G. Knepley @*/
2804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2805d71ae5a4SJacob Faibussowitsch {
280697b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
280797b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28089371c9d4SSatish Balay   if (numConstants) {
28099371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
28109371c9d4SSatish Balay     *numConstants = prob->numConstants;
28119371c9d4SSatish Balay   }
28129371c9d4SSatish Balay   if (constants) {
28139371c9d4SSatish Balay     PetscValidPointer(constants, 3);
28149371c9d4SSatish Balay     *constants = prob->constants;
28159371c9d4SSatish Balay   }
28163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
281797b6e6e8SMatthew G. Knepley }
281897b6e6e8SMatthew G. Knepley 
28190d3e9b51SMatthew G. Knepley /*@C
282097b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
282197b6e6e8SMatthew G. Knepley 
282297b6e6e8SMatthew G. Knepley   Not collective
282397b6e6e8SMatthew G. Knepley 
282497b6e6e8SMatthew G. Knepley   Input Parameters:
2825dce8aebaSBarry Smith + prob         - The `PetscDS` object
282697b6e6e8SMatthew G. Knepley . numConstants - The number of constants
282797b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
282897b6e6e8SMatthew G. Knepley 
282997b6e6e8SMatthew G. Knepley   Level: intermediate
283097b6e6e8SMatthew G. Knepley 
2831dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
283297b6e6e8SMatthew G. Knepley @*/
2833d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2834d71ae5a4SJacob Faibussowitsch {
283597b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
283697b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
283797b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28389566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
283997b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
284097b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
284220be0f5bSMatthew G. Knepley     } else {
284320be0f5bSMatthew G. Knepley       prob->constants = NULL;
284420be0f5bSMatthew G. Knepley     }
284520be0f5bSMatthew G. Knepley   }
284620be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2847dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
28489566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
284997b6e6e8SMatthew G. Knepley   }
28503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
285197b6e6e8SMatthew G. Knepley }
285297b6e6e8SMatthew G. Knepley 
28534cd1e086SMatthew G. Knepley /*@
28544cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28554cd1e086SMatthew G. Knepley 
28564cd1e086SMatthew G. Knepley   Not collective
28574cd1e086SMatthew G. Knepley 
28584cd1e086SMatthew G. Knepley   Input Parameters:
2859dce8aebaSBarry Smith + prob - The `PetscDS` object
28604cd1e086SMatthew G. Knepley - disc - The discretization object
28614cd1e086SMatthew G. Knepley 
28624cd1e086SMatthew G. Knepley   Output Parameter:
28634cd1e086SMatthew G. Knepley . f - The field number
28644cd1e086SMatthew G. Knepley 
28654cd1e086SMatthew G. Knepley   Level: beginner
28664cd1e086SMatthew G. Knepley 
2867dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28684cd1e086SMatthew G. Knepley @*/
2869d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2870d71ae5a4SJacob Faibussowitsch {
28714cd1e086SMatthew G. Knepley   PetscInt g;
28724cd1e086SMatthew G. Knepley 
28734cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28744cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2875dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
28764cd1e086SMatthew G. Knepley   *f = -1;
28779371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28789371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
28799371c9d4SSatish Balay   }
288008401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
28814cd1e086SMatthew G. Knepley   *f = g;
28823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28834cd1e086SMatthew G. Knepley }
28844cd1e086SMatthew G. Knepley 
28854cd1e086SMatthew G. Knepley /*@
28864cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
28874cd1e086SMatthew G. Knepley 
28884cd1e086SMatthew G. Knepley   Not collective
28894cd1e086SMatthew G. Knepley 
28904cd1e086SMatthew G. Knepley   Input Parameters:
2891dce8aebaSBarry Smith + prob - The `PetscDS` object
28924cd1e086SMatthew G. Knepley - f - The field number
28934cd1e086SMatthew G. Knepley 
28944cd1e086SMatthew G. Knepley   Output Parameter:
28954cd1e086SMatthew G. Knepley . size - The size
28964cd1e086SMatthew G. Knepley 
28974cd1e086SMatthew G. Knepley   Level: beginner
28984cd1e086SMatthew G. Knepley 
2899dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29004cd1e086SMatthew G. Knepley @*/
2901d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2902d71ae5a4SJacob Faibussowitsch {
29034cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29044cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2905dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
290663a3b9bcSJacob 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);
29079566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2908d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29104cd1e086SMatthew G. Knepley }
29114cd1e086SMatthew G. Knepley 
2912bc4ae4beSMatthew G. Knepley /*@
2913bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2914bc4ae4beSMatthew G. Knepley 
2915bc4ae4beSMatthew G. Knepley   Not collective
2916bc4ae4beSMatthew G. Knepley 
2917bc4ae4beSMatthew G. Knepley   Input Parameters:
2918dce8aebaSBarry Smith + prob - The `PetscDS` object
2919bc4ae4beSMatthew G. Knepley - f - The field number
2920bc4ae4beSMatthew G. Knepley 
2921bc4ae4beSMatthew G. Knepley   Output Parameter:
2922bc4ae4beSMatthew G. Knepley . off - The offset
2923bc4ae4beSMatthew G. Knepley 
2924bc4ae4beSMatthew G. Knepley   Level: beginner
2925bc4ae4beSMatthew G. Knepley 
2926dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2927bc4ae4beSMatthew G. Knepley @*/
2928d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2929d71ae5a4SJacob Faibussowitsch {
29304cd1e086SMatthew G. Knepley   PetscInt size, g;
29312764a2aaSMatthew G. Knepley 
29322764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29332764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2934dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
293563a3b9bcSJacob 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);
29362764a2aaSMatthew G. Knepley   *off = 0;
29372764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29389566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29394cd1e086SMatthew G. Knepley     *off += size;
29402764a2aaSMatthew G. Knepley   }
29413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29422764a2aaSMatthew G. Knepley }
29432764a2aaSMatthew G. Knepley 
2944bc4ae4beSMatthew G. Knepley /*@
29455fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29465fedec97SMatthew G. Knepley 
29475fedec97SMatthew G. Knepley   Not collective
29485fedec97SMatthew G. Knepley 
29495fedec97SMatthew G. Knepley   Input Parameters:
2950dce8aebaSBarry Smith + prob - The `PetscDS` object
29515fedec97SMatthew G. Knepley - f - The field number
29525fedec97SMatthew G. Knepley 
29535fedec97SMatthew G. Knepley   Output Parameter:
29545fedec97SMatthew G. Knepley . off - The offset
29555fedec97SMatthew G. Knepley 
29565fedec97SMatthew G. Knepley   Level: beginner
29575fedec97SMatthew G. Knepley 
2958dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29595fedec97SMatthew G. Knepley @*/
2960d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2961d71ae5a4SJacob Faibussowitsch {
29625fedec97SMatthew G. Knepley   PetscInt size, g;
29635fedec97SMatthew G. Knepley 
29645fedec97SMatthew G. Knepley   PetscFunctionBegin;
29655fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2966dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
296763a3b9bcSJacob 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);
29685fedec97SMatthew G. Knepley   *off = 0;
29695fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29705fedec97SMatthew G. Knepley     PetscBool cohesive;
29715fedec97SMatthew G. Knepley 
29729566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29739566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29745fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29755fedec97SMatthew G. Knepley   }
29763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29775fedec97SMatthew G. Knepley }
29785fedec97SMatthew G. Knepley 
29795fedec97SMatthew G. Knepley /*@
298047e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2981bc4ae4beSMatthew G. Knepley 
2982bc4ae4beSMatthew G. Knepley   Not collective
2983bc4ae4beSMatthew G. Knepley 
298447e57110SSander Arens   Input Parameter:
2985dce8aebaSBarry Smith . prob - The `PetscDS` object
2986bc4ae4beSMatthew G. Knepley 
2987bc4ae4beSMatthew G. Knepley   Output Parameter:
298847e57110SSander Arens . dimensions - The number of dimensions
2989bc4ae4beSMatthew G. Knepley 
2990bc4ae4beSMatthew G. Knepley   Level: beginner
2991bc4ae4beSMatthew G. Knepley 
2992dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2993bc4ae4beSMatthew G. Knepley @*/
2994d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2995d71ae5a4SJacob Faibussowitsch {
29962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29972764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29989566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
299947e57110SSander Arens   PetscValidPointer(dimensions, 2);
300047e57110SSander Arens   *dimensions = prob->Nb;
30013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30026ce16762SMatthew G. Knepley }
300347e57110SSander Arens 
300447e57110SSander Arens /*@
300547e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
300647e57110SSander Arens 
300747e57110SSander Arens   Not collective
300847e57110SSander Arens 
300947e57110SSander Arens   Input Parameter:
3010dce8aebaSBarry Smith . prob - The `PetscDS` object
301147e57110SSander Arens 
301247e57110SSander Arens   Output Parameter:
301347e57110SSander Arens . components - The number of components
301447e57110SSander Arens 
301547e57110SSander Arens   Level: beginner
301647e57110SSander Arens 
3017dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
301847e57110SSander Arens @*/
3019d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3020d71ae5a4SJacob Faibussowitsch {
302147e57110SSander Arens   PetscFunctionBegin;
302247e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30239566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
302447e57110SSander Arens   PetscValidPointer(components, 2);
302547e57110SSander Arens   *components = prob->Nc;
30263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30276ce16762SMatthew G. Knepley }
30286ce16762SMatthew G. Knepley 
30296ce16762SMatthew G. Knepley /*@
30306ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30316ce16762SMatthew G. Knepley 
30326ce16762SMatthew G. Knepley   Not collective
30336ce16762SMatthew G. Knepley 
30346ce16762SMatthew G. Knepley   Input Parameters:
3035dce8aebaSBarry Smith + prob - The `PetscDS` object
30366ce16762SMatthew G. Knepley - f - The field number
30376ce16762SMatthew G. Knepley 
30386ce16762SMatthew G. Knepley   Output Parameter:
30396ce16762SMatthew G. Knepley . off - The offset
30406ce16762SMatthew G. Knepley 
30416ce16762SMatthew G. Knepley   Level: beginner
30426ce16762SMatthew G. Knepley 
3043dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30446ce16762SMatthew G. Knepley @*/
3045d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3046d71ae5a4SJacob Faibussowitsch {
30476ce16762SMatthew G. Knepley   PetscFunctionBegin;
30486ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3049dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
305063a3b9bcSJacob 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);
30519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
305247e57110SSander Arens   *off = prob->off[f];
30533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30542764a2aaSMatthew G. Knepley }
30552764a2aaSMatthew G. Knepley 
3056194d53e6SMatthew G. Knepley /*@
3057194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3058194d53e6SMatthew G. Knepley 
3059194d53e6SMatthew G. Knepley   Not collective
3060194d53e6SMatthew G. Knepley 
3061194d53e6SMatthew G. Knepley   Input Parameter:
3062dce8aebaSBarry Smith . prob - The `PetscDS` object
3063194d53e6SMatthew G. Knepley 
3064194d53e6SMatthew G. Knepley   Output Parameter:
3065194d53e6SMatthew G. Knepley . offsets - The offsets
3066194d53e6SMatthew G. Knepley 
3067194d53e6SMatthew G. Knepley   Level: beginner
3068194d53e6SMatthew G. Knepley 
3069dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3070194d53e6SMatthew G. Knepley @*/
3071d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3072d71ae5a4SJacob Faibussowitsch {
3073194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3074194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3075194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30769566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3077194d53e6SMatthew G. Knepley   *offsets = prob->off;
30783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3079194d53e6SMatthew G. Knepley }
3080194d53e6SMatthew G. Knepley 
3081194d53e6SMatthew G. Knepley /*@
3082194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3083194d53e6SMatthew G. Knepley 
3084194d53e6SMatthew G. Knepley   Not collective
3085194d53e6SMatthew G. Knepley 
3086194d53e6SMatthew G. Knepley   Input Parameter:
3087dce8aebaSBarry Smith . prob - The `PetscDS` object
3088194d53e6SMatthew G. Knepley 
3089194d53e6SMatthew G. Knepley   Output Parameter:
3090194d53e6SMatthew G. Knepley . offsets - The offsets
3091194d53e6SMatthew G. Knepley 
3092194d53e6SMatthew G. Knepley   Level: beginner
3093194d53e6SMatthew G. Knepley 
3094dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3095194d53e6SMatthew G. Knepley @*/
3096d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3097d71ae5a4SJacob Faibussowitsch {
3098194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3099194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3100194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
31019566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3102194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3104194d53e6SMatthew G. Knepley }
3105194d53e6SMatthew G. Knepley 
31069ee2af8cSMatthew G. Knepley /*@
31079ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31089ee2af8cSMatthew G. Knepley 
31099ee2af8cSMatthew G. Knepley   Not collective
31109ee2af8cSMatthew G. Knepley 
31119ee2af8cSMatthew G. Knepley   Input Parameters:
3112dce8aebaSBarry Smith + ds - The `PetscDS` object
31139ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31149ee2af8cSMatthew G. Knepley 
31159ee2af8cSMatthew G. Knepley   Output Parameter:
31169ee2af8cSMatthew G. Knepley . offsets - The offsets
31179ee2af8cSMatthew G. Knepley 
31189ee2af8cSMatthew G. Knepley   Level: beginner
31199ee2af8cSMatthew G. Knepley 
3120dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31219ee2af8cSMatthew G. Knepley @*/
3122d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3123d71ae5a4SJacob Faibussowitsch {
31249ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31259ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31269ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
312728b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
312863a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31309ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31329ee2af8cSMatthew G. Knepley }
31339ee2af8cSMatthew G. Knepley 
31349ee2af8cSMatthew G. Knepley /*@
31359ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31369ee2af8cSMatthew G. Knepley 
31379ee2af8cSMatthew G. Knepley   Not collective
31389ee2af8cSMatthew G. Knepley 
31399ee2af8cSMatthew G. Knepley   Input Parameters:
3140dce8aebaSBarry Smith + ds - The `PetscDS` object
31419ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31429ee2af8cSMatthew G. Knepley 
31439ee2af8cSMatthew G. Knepley   Output Parameter:
31449ee2af8cSMatthew G. Knepley . offsets - The offsets
31459ee2af8cSMatthew G. Knepley 
31469ee2af8cSMatthew G. Knepley   Level: beginner
31479ee2af8cSMatthew G. Knepley 
3148dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31499ee2af8cSMatthew G. Knepley @*/
3150d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3151d71ae5a4SJacob Faibussowitsch {
31529ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31539ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31549ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
315528b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
315663a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31579566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31589ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31609ee2af8cSMatthew G. Knepley }
31619ee2af8cSMatthew G. Knepley 
316268c9edb9SMatthew G. Knepley /*@C
316368c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
316468c9edb9SMatthew G. Knepley 
316568c9edb9SMatthew G. Knepley   Not collective
316668c9edb9SMatthew G. Knepley 
316768c9edb9SMatthew G. Knepley   Input Parameter:
3168dce8aebaSBarry Smith . prob - The `PetscDS` object
316968c9edb9SMatthew G. Knepley 
3170ef0bb6c7SMatthew G. Knepley   Output Parameter:
3171ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
317268c9edb9SMatthew G. Knepley 
317368c9edb9SMatthew G. Knepley   Level: intermediate
317468c9edb9SMatthew G. Knepley 
3175dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
317668c9edb9SMatthew G. Knepley @*/
3177d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3178d71ae5a4SJacob Faibussowitsch {
31792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31802764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3181ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
31829566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3183ef0bb6c7SMatthew G. Knepley   *T = prob->T;
31843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31852764a2aaSMatthew G. Knepley }
31862764a2aaSMatthew G. Knepley 
318768c9edb9SMatthew G. Knepley /*@C
31884d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
318968c9edb9SMatthew G. Knepley 
319068c9edb9SMatthew G. Knepley   Not collective
319168c9edb9SMatthew G. Knepley 
319268c9edb9SMatthew G. Knepley   Input Parameter:
3193dce8aebaSBarry Smith . prob - The `PetscDS` object
319468c9edb9SMatthew G. Knepley 
3195ef0bb6c7SMatthew G. Knepley   Output Parameter:
3196a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
319768c9edb9SMatthew G. Knepley 
319868c9edb9SMatthew G. Knepley   Level: intermediate
319968c9edb9SMatthew G. Knepley 
3200dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
320168c9edb9SMatthew G. Knepley @*/
3202d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3203d71ae5a4SJacob Faibussowitsch {
32042764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32052764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3206ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
32079566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3208ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32102764a2aaSMatthew G. Knepley }
32112764a2aaSMatthew G. Knepley 
3212d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3213d71ae5a4SJacob Faibussowitsch {
32142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32179371c9d4SSatish Balay   if (u) {
32189371c9d4SSatish Balay     PetscValidPointer(u, 2);
32199371c9d4SSatish Balay     *u = prob->u;
32209371c9d4SSatish Balay   }
32219371c9d4SSatish Balay   if (u_t) {
32229371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
32239371c9d4SSatish Balay     *u_t = prob->u_t;
32249371c9d4SSatish Balay   }
32259371c9d4SSatish Balay   if (u_x) {
32269371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
32279371c9d4SSatish Balay     *u_x = prob->u_x;
32289371c9d4SSatish Balay   }
32293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32302764a2aaSMatthew G. Knepley }
32312764a2aaSMatthew G. Knepley 
3232d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3233d71ae5a4SJacob Faibussowitsch {
32342764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32352764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32369566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32379371c9d4SSatish Balay   if (f0) {
32389371c9d4SSatish Balay     PetscValidPointer(f0, 2);
32399371c9d4SSatish Balay     *f0 = prob->f0;
32409371c9d4SSatish Balay   }
32419371c9d4SSatish Balay   if (f1) {
32429371c9d4SSatish Balay     PetscValidPointer(f1, 3);
32439371c9d4SSatish Balay     *f1 = prob->f1;
32449371c9d4SSatish Balay   }
32459371c9d4SSatish Balay   if (g0) {
32469371c9d4SSatish Balay     PetscValidPointer(g0, 4);
32479371c9d4SSatish Balay     *g0 = prob->g0;
32489371c9d4SSatish Balay   }
32499371c9d4SSatish Balay   if (g1) {
32509371c9d4SSatish Balay     PetscValidPointer(g1, 5);
32519371c9d4SSatish Balay     *g1 = prob->g1;
32529371c9d4SSatish Balay   }
32539371c9d4SSatish Balay   if (g2) {
32549371c9d4SSatish Balay     PetscValidPointer(g2, 6);
32559371c9d4SSatish Balay     *g2 = prob->g2;
32569371c9d4SSatish Balay   }
32579371c9d4SSatish Balay   if (g3) {
32589371c9d4SSatish Balay     PetscValidPointer(g3, 7);
32599371c9d4SSatish Balay     *g3 = prob->g3;
32609371c9d4SSatish Balay   }
32613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32622764a2aaSMatthew G. Knepley }
32632764a2aaSMatthew G. Knepley 
3264d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3265d71ae5a4SJacob Faibussowitsch {
32662764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32672764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32689566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32699371c9d4SSatish Balay   if (x) {
32709371c9d4SSatish Balay     PetscValidPointer(x, 2);
32719371c9d4SSatish Balay     *x = prob->x;
32729371c9d4SSatish Balay   }
32739371c9d4SSatish Balay   if (basisReal) {
32749371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
32759371c9d4SSatish Balay     *basisReal = prob->basisReal;
32769371c9d4SSatish Balay   }
32779371c9d4SSatish Balay   if (basisDerReal) {
32789371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
32799371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
32809371c9d4SSatish Balay   }
32819371c9d4SSatish Balay   if (testReal) {
32829371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
32839371c9d4SSatish Balay     *testReal = prob->testReal;
32849371c9d4SSatish Balay   }
32859371c9d4SSatish Balay   if (testDerReal) {
32869371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
32879371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
32889371c9d4SSatish Balay   }
32893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32902764a2aaSMatthew G. Knepley }
32912764a2aaSMatthew G. Knepley 
329258ebd649SToby Isaac /*@C
3293dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3294dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3295dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
329658ebd649SToby Isaac 
3297783e2ec8SMatthew G. Knepley   Collective on ds
3298783e2ec8SMatthew G. Knepley 
329958ebd649SToby Isaac   Input Parameters:
330058ebd649SToby Isaac + ds       - The PetscDS object
3301dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
330258ebd649SToby Isaac . name     - The BC name
330345480ffeSMatthew G. Knepley . label    - The label defining constrained points
3304dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
330545480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
330658ebd649SToby Isaac . field    - The field to constrain
330745480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
330858ebd649SToby Isaac . comps    - An array of constrained component numbers
330958ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3310a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
331158ebd649SToby Isaac - ctx      - An optional user context for bcFunc
331258ebd649SToby Isaac 
331345480ffeSMatthew G. Knepley   Output Parameters:
331445480ffeSMatthew G. Knepley - bd       - The boundary number
331545480ffeSMatthew G. Knepley 
331658ebd649SToby Isaac   Options Database Keys:
331758ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
331858ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
331958ebd649SToby Isaac 
3320dce8aebaSBarry Smith   Level: developer
3321dce8aebaSBarry Smith 
332256cf3b9cSMatthew G. Knepley   Note:
3323dce8aebaSBarry Smith   Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, Then the calling sequence is:
332456cf3b9cSMatthew G. Knepley 
332556cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
332656cf3b9cSMatthew G. Knepley 
3327dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3328dce8aebaSBarry Smith .vb
3329dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3330dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3331dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3332dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3333dce8aebaSBarry Smith .ve
333456cf3b9cSMatthew G. Knepley + dim - the spatial dimension
333556cf3b9cSMatthew G. Knepley . Nf - the number of fields
333656cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
333756cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
333856cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
333956cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
334056cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
334156cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
334256cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
334356cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
334456cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
334556cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
334656cf3b9cSMatthew G. Knepley . t - current time
334756cf3b9cSMatthew G. Knepley . x - coordinates of the current point
334856cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
334956cf3b9cSMatthew G. Knepley . constants - constant parameters
335056cf3b9cSMatthew G. Knepley - bcval - output values at the current point
335156cf3b9cSMatthew G. Knepley 
3352dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
335358ebd649SToby Isaac @*/
3354d71ae5a4SJacob 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)
3355d71ae5a4SJacob Faibussowitsch {
335645480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
335745480ffeSMatthew G. Knepley   PetscInt    n    = 0;
335845480ffeSMatthew G. Knepley   const char *lname;
335958ebd649SToby Isaac 
336058ebd649SToby Isaac   PetscFunctionBegin;
336158ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3362783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
336345480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
336445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
336545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
336645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
336745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3368dce9da9cSMatthew 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);
3369d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3370d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3371d57bb9dbSMatthew G. Knepley     PetscInt  c;
3372d57bb9dbSMatthew G. Knepley 
33739566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
337463a3b9bcSJacob 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);
3375d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
33761dca8a05SBarry 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);
3377d57bb9dbSMatthew G. Knepley     }
3378d57bb9dbSMatthew G. Knepley   }
33799566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33809566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33839566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33849566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
33859566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
33869566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
33879566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
33889566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3389f971fd6bSMatthew G. Knepley   b->type   = type;
339045480ffeSMatthew G. Knepley   b->label  = label;
339145480ffeSMatthew G. Knepley   b->Nv     = Nv;
339258ebd649SToby Isaac   b->field  = field;
339345480ffeSMatthew G. Knepley   b->Nc     = Nc;
339458ebd649SToby Isaac   b->func   = bcFunc;
339556cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
339658ebd649SToby Isaac   b->ctx    = ctx;
339745480ffeSMatthew G. Knepley   b->next   = NULL;
339845480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
339945480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
340045480ffeSMatthew G. Knepley   while (head) {
340145480ffeSMatthew G. Knepley     if (!head->next) {
340245480ffeSMatthew G. Knepley       head->next = b;
340345480ffeSMatthew G. Knepley       head       = b;
340445480ffeSMatthew G. Knepley     }
340545480ffeSMatthew G. Knepley     head = head->next;
340645480ffeSMatthew G. Knepley     ++n;
340745480ffeSMatthew G. Knepley   }
34089371c9d4SSatish Balay   if (bd) {
34099371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34109371c9d4SSatish Balay     *bd = n;
34119371c9d4SSatish Balay   }
34123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
341345480ffeSMatthew G. Knepley }
341445480ffeSMatthew G. Knepley 
341545480ffeSMatthew G. Knepley /*@C
3416dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3417dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that
3418dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
341945480ffeSMatthew G. Knepley 
342045480ffeSMatthew G. Knepley   Collective on ds
342145480ffeSMatthew G. Knepley 
342245480ffeSMatthew G. Knepley   Input Parameters:
3423dce8aebaSBarry Smith + ds       - The `PetscDS` object
3424dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
342545480ffeSMatthew G. Knepley . name     - The BC name
342645480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3427dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
342845480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
342945480ffeSMatthew G. Knepley . field    - The field to constrain
343045480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
343145480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
343245480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3433a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
343445480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
343545480ffeSMatthew G. Knepley 
343645480ffeSMatthew G. Knepley   Output Parameters:
343745480ffeSMatthew G. Knepley - bd       - The boundary number
343845480ffeSMatthew G. Knepley 
343945480ffeSMatthew G. Knepley   Options Database Keys:
344045480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
344145480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
344245480ffeSMatthew G. Knepley 
3443dce8aebaSBarry Smith   Calling Sequence of bcFunc() and bcFunc_t():
3444dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3445dce8aebaSBarry Smith .vb
3446dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3447dce8aebaSBarry Smith .ve
3448dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3449dce8aebaSBarry Smith .vb
3450dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3451dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3452dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3453dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3454dce8aebaSBarry Smith .ve
345545480ffeSMatthew G. Knepley + dim - the spatial dimension
345645480ffeSMatthew G. Knepley . Nf - the number of fields
345745480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
345845480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
345945480ffeSMatthew G. Knepley . u - each field evaluated at the current point
346045480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
346145480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
346245480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
346345480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
346445480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
346545480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
346645480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
346745480ffeSMatthew G. Knepley . t - current time
346845480ffeSMatthew G. Knepley . x - coordinates of the current point
346945480ffeSMatthew G. Knepley . numConstants - number of constant parameters
347045480ffeSMatthew G. Knepley . constants - constant parameters
347145480ffeSMatthew G. Knepley - bcval - output values at the current point
347245480ffeSMatthew G. Knepley 
347345480ffeSMatthew G. Knepley   Level: developer
347445480ffeSMatthew G. Knepley 
3475dce8aebaSBarry Smith   Note:
3476dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3477dce8aebaSBarry Smith 
3478dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
347945480ffeSMatthew G. Knepley @*/
3480d71ae5a4SJacob 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)
3481d71ae5a4SJacob Faibussowitsch {
348245480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
348345480ffeSMatthew G. Knepley   PetscInt   n    = 0;
348445480ffeSMatthew G. Knepley 
348545480ffeSMatthew G. Knepley   PetscFunctionBegin;
348645480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
348745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
348845480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
348945480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
349045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
349145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
349245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
34939566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34949566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34969566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34979566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34989566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35009566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35019566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
350245480ffeSMatthew G. Knepley   b->type   = type;
350345480ffeSMatthew G. Knepley   b->label  = NULL;
350445480ffeSMatthew G. Knepley   b->Nv     = Nv;
350545480ffeSMatthew G. Knepley   b->field  = field;
350645480ffeSMatthew G. Knepley   b->Nc     = Nc;
350745480ffeSMatthew G. Knepley   b->func   = bcFunc;
350845480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
350945480ffeSMatthew G. Knepley   b->ctx    = ctx;
351045480ffeSMatthew G. Knepley   b->next   = NULL;
351145480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
351245480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
351345480ffeSMatthew G. Knepley   while (head) {
351445480ffeSMatthew G. Knepley     if (!head->next) {
351545480ffeSMatthew G. Knepley       head->next = b;
351645480ffeSMatthew G. Knepley       head       = b;
351745480ffeSMatthew G. Knepley     }
351845480ffeSMatthew G. Knepley     head = head->next;
351945480ffeSMatthew G. Knepley     ++n;
352045480ffeSMatthew G. Knepley   }
35219371c9d4SSatish Balay   if (bd) {
35229371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35239371c9d4SSatish Balay     *bd = n;
35249371c9d4SSatish Balay   }
35253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352658ebd649SToby Isaac }
352758ebd649SToby Isaac 
3528b67eacb3SMatthew G. Knepley /*@C
3529dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3530dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals
3531dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3532b67eacb3SMatthew G. Knepley 
3533b67eacb3SMatthew G. Knepley   Input Parameters:
3534dce8aebaSBarry Smith + ds       - The `PetscDS` object
3535b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3536dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3537b67eacb3SMatthew G. Knepley . name     - The BC name
353845480ffeSMatthew G. Knepley . label    - The label defining constrained points
3539dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
354045480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3541b67eacb3SMatthew G. Knepley . field    - The field to constrain
354245480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3543b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3544b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3545a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3546b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3547b67eacb3SMatthew G. Knepley 
3548b67eacb3SMatthew G. Knepley   Level: developer
3549b67eacb3SMatthew G. Knepley 
3550dce8aebaSBarry Smith   Note:
3551dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3552dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3553dce8aebaSBarry Smith 
3554dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3555b67eacb3SMatthew G. Knepley @*/
3556d71ae5a4SJacob 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)
3557d71ae5a4SJacob Faibussowitsch {
3558b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3559b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3560b67eacb3SMatthew G. Knepley 
3561b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3562b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3563b67eacb3SMatthew G. Knepley   while (b) {
3564b67eacb3SMatthew G. Knepley     if (n == bd) break;
3565b67eacb3SMatthew G. Knepley     b = b->next;
3566b67eacb3SMatthew G. Knepley     ++n;
3567b67eacb3SMatthew G. Knepley   }
356863a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3569b67eacb3SMatthew G. Knepley   if (name) {
35709566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
35719566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3572b67eacb3SMatthew G. Knepley   }
3573b67eacb3SMatthew G. Knepley   b->type = type;
357445480ffeSMatthew G. Knepley   if (label) {
357545480ffeSMatthew G. Knepley     const char *name;
357645480ffeSMatthew G. Knepley 
357745480ffeSMatthew G. Knepley     b->label = label;
35789566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
35799566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
35809566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
358145480ffeSMatthew G. Knepley   }
358245480ffeSMatthew G. Knepley   if (Nv >= 0) {
358345480ffeSMatthew G. Knepley     b->Nv = Nv;
35849566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
35859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
35869566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
358745480ffeSMatthew G. Knepley   }
358845480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
358945480ffeSMatthew G. Knepley   if (Nc >= 0) {
359045480ffeSMatthew G. Knepley     b->Nc = Nc;
35919566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
35929566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
35939566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
359445480ffeSMatthew G. Knepley   }
359545480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
359645480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
359745480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
35983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3599b67eacb3SMatthew G. Knepley }
3600b67eacb3SMatthew G. Knepley 
360158ebd649SToby Isaac /*@
360258ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
360358ebd649SToby Isaac 
360458ebd649SToby Isaac   Input Parameters:
3605dce8aebaSBarry Smith . ds - The `PetscDS` object
360658ebd649SToby Isaac 
360758ebd649SToby Isaac   Output Parameters:
360858ebd649SToby Isaac . numBd - The number of BC
360958ebd649SToby Isaac 
361058ebd649SToby Isaac   Level: intermediate
361158ebd649SToby Isaac 
3612dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
361358ebd649SToby Isaac @*/
3614d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3615d71ae5a4SJacob Faibussowitsch {
361658ebd649SToby Isaac   DSBoundary b = ds->boundary;
361758ebd649SToby Isaac 
361858ebd649SToby Isaac   PetscFunctionBegin;
361958ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3620dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
362158ebd649SToby Isaac   *numBd = 0;
36229371c9d4SSatish Balay   while (b) {
36239371c9d4SSatish Balay     ++(*numBd);
36249371c9d4SSatish Balay     b = b->next;
36259371c9d4SSatish Balay   }
36263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
362758ebd649SToby Isaac }
362858ebd649SToby Isaac 
362958ebd649SToby Isaac /*@C
36309a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
363158ebd649SToby Isaac 
363258ebd649SToby Isaac   Input Parameters:
3633dce8aebaSBarry Smith + ds          - The `PetscDS` object
363458ebd649SToby Isaac - bd          - The BC number
363558ebd649SToby Isaac 
363658ebd649SToby Isaac   Output Parameters:
3637dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3638dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
363958ebd649SToby Isaac . name     - The BC name
364045480ffeSMatthew G. Knepley . label    - The label defining constrained points
3641dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
364245480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
364358ebd649SToby Isaac . field    - The field to constrain
364445480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
364558ebd649SToby Isaac . comps    - An array of constrained component numbers
364658ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3647a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
364858ebd649SToby Isaac - ctx      - An optional user context for bcFunc
364958ebd649SToby Isaac 
365058ebd649SToby Isaac   Options Database Keys:
365158ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
365258ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
365358ebd649SToby Isaac 
365458ebd649SToby Isaac   Level: developer
365558ebd649SToby Isaac 
3656dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
365758ebd649SToby Isaac @*/
3658d71ae5a4SJacob 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)
3659d71ae5a4SJacob Faibussowitsch {
366058ebd649SToby Isaac   DSBoundary b = ds->boundary;
366158ebd649SToby Isaac   PetscInt   n = 0;
366258ebd649SToby Isaac 
366358ebd649SToby Isaac   PetscFunctionBegin;
366458ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
366558ebd649SToby Isaac   while (b) {
366658ebd649SToby Isaac     if (n == bd) break;
366758ebd649SToby Isaac     b = b->next;
366858ebd649SToby Isaac     ++n;
366958ebd649SToby Isaac   }
367063a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
367145480ffeSMatthew G. Knepley   if (wf) {
367245480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
367345480ffeSMatthew G. Knepley     *wf = b->wf;
367445480ffeSMatthew G. Knepley   }
3675f971fd6bSMatthew G. Knepley   if (type) {
367645480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3677f971fd6bSMatthew G. Knepley     *type = b->type;
367858ebd649SToby Isaac   }
367958ebd649SToby Isaac   if (name) {
368045480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
368158ebd649SToby Isaac     *name = b->name;
368258ebd649SToby Isaac   }
368345480ffeSMatthew G. Knepley   if (label) {
368445480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
368545480ffeSMatthew G. Knepley     *label = b->label;
368645480ffeSMatthew G. Knepley   }
368745480ffeSMatthew G. Knepley   if (Nv) {
368845480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
368945480ffeSMatthew G. Knepley     *Nv = b->Nv;
369045480ffeSMatthew G. Knepley   }
369145480ffeSMatthew G. Knepley   if (values) {
369245480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
369345480ffeSMatthew G. Knepley     *values = b->values;
369458ebd649SToby Isaac   }
369558ebd649SToby Isaac   if (field) {
369645480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
369758ebd649SToby Isaac     *field = b->field;
369858ebd649SToby Isaac   }
369945480ffeSMatthew G. Knepley   if (Nc) {
370045480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
370145480ffeSMatthew G. Knepley     *Nc = b->Nc;
370258ebd649SToby Isaac   }
370358ebd649SToby Isaac   if (comps) {
370445480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
370558ebd649SToby Isaac     *comps = b->comps;
370658ebd649SToby Isaac   }
370758ebd649SToby Isaac   if (func) {
370845480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
370958ebd649SToby Isaac     *func = b->func;
371058ebd649SToby Isaac   }
371156cf3b9cSMatthew G. Knepley   if (func_t) {
371245480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
371356cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
371456cf3b9cSMatthew G. Knepley   }
371558ebd649SToby Isaac   if (ctx) {
371645480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
371758ebd649SToby Isaac     *ctx = b->ctx;
371858ebd649SToby Isaac   }
37193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
372058ebd649SToby Isaac }
372158ebd649SToby Isaac 
3722d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3723d71ae5a4SJacob Faibussowitsch {
372445480ffeSMatthew G. Knepley   PetscFunctionBegin;
37259566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37289566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37299566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
373045480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
373145480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
373245480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37339566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37349566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
373545480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
373645480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37379566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37389566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
373945480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
374045480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
374145480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
37423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
374345480ffeSMatthew G. Knepley }
374445480ffeSMatthew G. Knepley 
37459252d075SMatthew G. Knepley /*@
37469252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
37479252d075SMatthew G. Knepley 
37489252d075SMatthew G. Knepley   Not collective
37499252d075SMatthew G. Knepley 
375036951cb5SMatthew G. Knepley   Input Parameters:
3751dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3752dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
375336951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
37549252d075SMatthew G. Knepley 
37559252d075SMatthew G. Knepley   Output Parameter:
3756dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
37579252d075SMatthew G. Knepley 
37589252d075SMatthew G. Knepley   Level: intermediate
37599252d075SMatthew G. Knepley 
3760dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37619252d075SMatthew G. Knepley @*/
3762d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3763d71ae5a4SJacob Faibussowitsch {
376445480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3765dff059c6SToby Isaac 
3766dff059c6SToby Isaac   PetscFunctionBegin;
376736951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
376836951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
37693ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
37709566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
377136951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
377236951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3773dff059c6SToby Isaac     DSBoundary bNew;
377436951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3775dff059c6SToby Isaac 
377636951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
377736951cb5SMatthew G. Knepley       PetscInt f;
377836951cb5SMatthew G. Knepley 
37799371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
37809371c9d4SSatish Balay         if (b->field == fields[f]) break;
378136951cb5SMatthew G. Knepley       if (f == numFields) continue;
378236951cb5SMatthew G. Knepley       fieldNew = f;
378336951cb5SMatthew G. Knepley     }
37849566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
378536951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3786dff059c6SToby Isaac     *lastnext   = bNew;
3787dff059c6SToby Isaac     lastnext    = &(bNew->next);
3788dff059c6SToby Isaac   }
37893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3790dff059c6SToby Isaac }
3791dff059c6SToby Isaac 
37926c1eb96dSMatthew G. Knepley /*@
3793dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
379445480ffeSMatthew G. Knepley 
379545480ffeSMatthew G. Knepley   Not collective
379645480ffeSMatthew G. Knepley 
379745480ffeSMatthew G. Knepley   Input Parameter:
3798dce8aebaSBarry Smith . ds - The `PetscDS` object
379945480ffeSMatthew G. Knepley 
380045480ffeSMatthew G. Knepley   Level: intermediate
380145480ffeSMatthew G. Knepley 
3802dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
380345480ffeSMatthew G. Knepley @*/
3804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3805d71ae5a4SJacob Faibussowitsch {
380645480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
380745480ffeSMatthew G. Knepley 
380845480ffeSMatthew G. Knepley   PetscFunctionBegin;
380945480ffeSMatthew G. Knepley   while (next) {
381045480ffeSMatthew G. Knepley     DSBoundary b = next;
381145480ffeSMatthew G. Knepley 
381245480ffeSMatthew G. Knepley     next = b->next;
38139566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38149566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38159566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38169566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38179566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38189566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
381945480ffeSMatthew G. Knepley   }
38203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
382145480ffeSMatthew G. Knepley }
382245480ffeSMatthew G. Knepley 
382345480ffeSMatthew G. Knepley /*@
38246c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38256c1eb96dSMatthew G. Knepley 
38266c1eb96dSMatthew G. Knepley   Not collective
38276c1eb96dSMatthew G. Knepley 
3828d8d19677SJose E. Roman   Input Parameters:
3829dce8aebaSBarry Smith + prob - The `PetscDS` object
38306c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38316c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
38326c1eb96dSMatthew G. Knepley 
38336c1eb96dSMatthew G. Knepley   Output Parameter:
3834dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38356c1eb96dSMatthew G. Knepley 
38366c1eb96dSMatthew G. Knepley   Level: intermediate
38376c1eb96dSMatthew G. Knepley 
3838dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38396c1eb96dSMatthew G. Knepley @*/
3840d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3841d71ae5a4SJacob Faibussowitsch {
38426c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
38436c1eb96dSMatthew G. Knepley 
38446c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
38456c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3846dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38476c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38489566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38499566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
385045480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
38516c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38526c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
38536c1eb96dSMatthew G. Knepley     PetscObject    disc;
38546c1eb96dSMatthew G. Knepley 
38556c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
38569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
38579566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
38586c1eb96dSMatthew G. Knepley   }
38593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38606c1eb96dSMatthew G. Knepley }
38616c1eb96dSMatthew G. Knepley 
38626c1eb96dSMatthew G. Knepley /*@
38639252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
38649252d075SMatthew G. Knepley 
38659252d075SMatthew G. Knepley   Not collective
38669252d075SMatthew G. Knepley 
3867d8d19677SJose E. Roman   Input Parameters:
3868dce8aebaSBarry Smith + prob - The `PetscDS` object
38699252d075SMatthew G. Knepley . numFields - Number of new fields
38709252d075SMatthew G. Knepley - fields - Old field number for each new field
38719252d075SMatthew G. Knepley 
38729252d075SMatthew G. Knepley   Output Parameter:
3873dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38749252d075SMatthew G. Knepley 
38759252d075SMatthew G. Knepley   Level: intermediate
38769252d075SMatthew G. Knepley 
3877dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38789252d075SMatthew G. Knepley @*/
3879d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3880d71ae5a4SJacob Faibussowitsch {
38819252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
38829252d075SMatthew G. Knepley 
38839252d075SMatthew G. Knepley   PetscFunctionBegin;
38849252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3885dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38869252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38879566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38889566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
388963a3b9bcSJacob 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);
38909252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38919252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
38929252d075SMatthew G. Knepley     PetscPointFunc   obj;
38939252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
38949252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
38959252d075SMatthew G. Knepley     PetscRiemannFunc r;
38969252d075SMatthew G. Knepley 
3897c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
38989566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
38999566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39009566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39019566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39029566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39039566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39049566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39059566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39069252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39079252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39089252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39099252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39109252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39119252d075SMatthew G. Knepley 
3912c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39139566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39149566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39159566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39169566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39179566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39189566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39199252d075SMatthew G. Knepley     }
39209252d075SMatthew G. Knepley   }
39213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39229252d075SMatthew G. Knepley }
39239252d075SMatthew G. Knepley 
3924da51fcedSMatthew G. Knepley /*@
3925dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3926da51fcedSMatthew G. Knepley 
3927da51fcedSMatthew G. Knepley   Not collective
3928da51fcedSMatthew G. Knepley 
3929da51fcedSMatthew G. Knepley   Input Parameter:
3930dce8aebaSBarry Smith . prob - The `PetscDS` object
3931da51fcedSMatthew G. Knepley 
3932da51fcedSMatthew G. Knepley   Output Parameter:
3933dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3934da51fcedSMatthew G. Knepley 
3935da51fcedSMatthew G. Knepley   Level: intermediate
3936da51fcedSMatthew G. Knepley 
3937dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3938da51fcedSMatthew G. Knepley @*/
3939d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3940d71ae5a4SJacob Faibussowitsch {
3941b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
39429252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3943da51fcedSMatthew G. Knepley 
3944da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3945da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3946da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39479566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39489566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
394963a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
39509566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
39519566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
39529566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
39533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39549252d075SMatthew G. Knepley }
395545480ffeSMatthew G. Knepley 
39569252d075SMatthew G. Knepley /*@
3957dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3958da51fcedSMatthew G. Knepley 
39599252d075SMatthew G. Knepley   Not collective
39609252d075SMatthew G. Knepley 
39619252d075SMatthew G. Knepley   Input Parameter:
3962dce8aebaSBarry Smith . prob - The `PetscDS` object
39639252d075SMatthew G. Knepley 
39649252d075SMatthew G. Knepley   Output Parameter:
3965dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39669252d075SMatthew G. Knepley 
39679252d075SMatthew G. Knepley   Level: intermediate
39689252d075SMatthew G. Knepley 
3969dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39709252d075SMatthew G. Knepley @*/
3971d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3972d71ae5a4SJacob Faibussowitsch {
39739252d075SMatthew G. Knepley   PetscInt           Nc;
39749252d075SMatthew G. Knepley   const PetscScalar *constants;
39759252d075SMatthew G. Knepley 
39769252d075SMatthew G. Knepley   PetscFunctionBegin;
39779252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39789252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39799566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
39809566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
39813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3982da51fcedSMatthew G. Knepley }
3983da51fcedSMatthew G. Knepley 
398445480ffeSMatthew G. Knepley /*@
3985dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
398645480ffeSMatthew G. Knepley 
398745480ffeSMatthew G. Knepley   Not collective
398845480ffeSMatthew G. Knepley 
398945480ffeSMatthew G. Knepley   Input Parameter:
3990dce8aebaSBarry Smith . ds - The `PetscDS` object
399145480ffeSMatthew G. Knepley 
399245480ffeSMatthew G. Knepley   Output Parameter:
3993dce8aebaSBarry Smith . newds - The `PetscDS` copy
399445480ffeSMatthew G. Knepley 
399545480ffeSMatthew G. Knepley   Level: intermediate
399645480ffeSMatthew G. Knepley 
3997dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
399845480ffeSMatthew G. Knepley @*/
3999d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4000d71ae5a4SJacob Faibussowitsch {
400145480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
400245480ffeSMatthew G. Knepley   void                *ctx;
400345480ffeSMatthew G. Knepley   PetscInt             Nf, f;
400445480ffeSMatthew G. Knepley 
400545480ffeSMatthew G. Knepley   PetscFunctionBegin;
400645480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
400745480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40089566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
400945480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40109566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40119566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40129566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40139566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
401445480ffeSMatthew G. Knepley   }
40153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
401645480ffeSMatthew G. Knepley }
401745480ffeSMatthew G. Knepley 
4018d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4019d71ae5a4SJacob Faibussowitsch {
4020df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4021b1353e8eSMatthew G. Knepley 
4022b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4023b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4024b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
40259371c9d4SSatish Balay   if (height == 0) {
40269371c9d4SSatish Balay     *subprob = prob;
40273ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
40289371c9d4SSatish Balay   }
40299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40309566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
403163a3b9bcSJacob 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);
40329566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4033df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4034b1353e8eSMatthew G. Knepley     PetscInt cdim;
4035b1353e8eSMatthew G. Knepley 
40369566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
40379566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
40389566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4039b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4040b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4041b1353e8eSMatthew G. Knepley       PetscObject  obj;
4042b1353e8eSMatthew G. Knepley       PetscClassId id;
4043b1353e8eSMatthew G. Knepley 
40449566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40459566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
40469566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
404763a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
40489566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4049b1353e8eSMatthew G. Knepley     }
4050b1353e8eSMatthew G. Knepley   }
4051df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
40523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4053b1353e8eSMatthew G. Knepley }
4054b1353e8eSMatthew G. Knepley 
4055d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4056d71ae5a4SJacob Faibussowitsch {
4057c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4058c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4059c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4060c7bd5f0bSMatthew G. Knepley 
4061c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4062c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4063665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4064665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
40659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
406663a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
40679566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4068665f567fSMatthew G. Knepley   if (obj) {
40699566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4070665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4071665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4072665f567fSMatthew G. Knepley   }
40733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4074c7bd5f0bSMatthew G. Knepley }
4075c7bd5f0bSMatthew G. Knepley 
4076d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4077d71ae5a4SJacob Faibussowitsch {
40782764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40799566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
40803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40812764a2aaSMatthew G. Knepley }
40822764a2aaSMatthew G. Knepley 
4083d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4084d71ae5a4SJacob Faibussowitsch {
40852764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40866528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
40876528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
40886528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
40896528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
40903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40912764a2aaSMatthew G. Knepley }
40922764a2aaSMatthew G. Knepley 
40932764a2aaSMatthew G. Knepley /*MC
40942764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
40952764a2aaSMatthew G. Knepley 
40962764a2aaSMatthew G. Knepley   Level: intermediate
40972764a2aaSMatthew G. Knepley 
4098db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
40992764a2aaSMatthew G. Knepley M*/
41002764a2aaSMatthew G. Knepley 
4101d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4102d71ae5a4SJacob Faibussowitsch {
41032764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
41042764a2aaSMatthew G. Knepley 
41052764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41066528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41074dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
41086528b96dSMatthew G. Knepley   ds->data = b;
41092764a2aaSMatthew G. Knepley 
41109566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
41113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41122764a2aaSMatthew G. Knepley }
4113