xref: /petsc/src/dm/dt/interface/dtds.c (revision 1c7e414e2723e48d2171f9bad7df83055ad45d0b)
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__)
210*1c7e414eSJacob Faibussowitsch       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic");
21115943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
212*1c7e414eSJacob Faibussowitsch       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat");
21315943bb8SPierre Jolivet #endif
2148e0d8d9cSMatthew G. Knepley       if (b->func) {
2159566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2169566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2179566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2189566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2198e0d8d9cSMatthew G. Knepley       }
2208e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2219566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2229566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2239566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2249566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2258e0d8d9cSMatthew G. Knepley       }
226*1c7e414eSJacob Faibussowitsch       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END();
2279566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2289566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
22940967b3bSMatthew G. Knepley     }
2307d8a60eaSMatthew G. Knepley   }
2319566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
23297b6e6e8SMatthew G. Knepley   if (numConstants) {
23363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2359566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2369566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
23797b6e6e8SMatthew G. Knepley   }
2389566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2399566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2417d8a60eaSMatthew G. Knepley }
2427d8a60eaSMatthew G. Knepley 
2432764a2aaSMatthew G. Knepley /*@C
244dce8aebaSBarry Smith    PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
245fe2efc57SMark 
246fe2efc57SMark    Collective on PetscDS
247fe2efc57SMark 
248fe2efc57SMark    Input Parameters:
249dce8aebaSBarry Smith +  A - the `PetscDS` object
250736c3998SJose E. Roman .  obj - Optional object
251736c3998SJose E. Roman -  name - command line option
252fe2efc57SMark 
253fe2efc57SMark    Level: intermediate
254dce8aebaSBarry Smith 
255dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
256fe2efc57SMark @*/
257d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
258d71ae5a4SJacob Faibussowitsch {
259fe2efc57SMark   PetscFunctionBegin;
260fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2619566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
263fe2efc57SMark }
264fe2efc57SMark 
265fe2efc57SMark /*@C
266dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2672764a2aaSMatthew G. Knepley 
268d083f849SBarry Smith   Collective on prob
2692764a2aaSMatthew G. Knepley 
270d8d19677SJose E. Roman   Input Parameters:
271dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2722764a2aaSMatthew G. Knepley - v  - the viewer
2732764a2aaSMatthew G. Knepley 
2742764a2aaSMatthew G. Knepley   Level: developer
2752764a2aaSMatthew G. Knepley 
276dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`
2772764a2aaSMatthew G. Knepley @*/
278d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
279d71ae5a4SJacob Faibussowitsch {
2807d8a60eaSMatthew G. Knepley   PetscBool iascii;
2812764a2aaSMatthew G. Knepley 
2822764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2832764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2849566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
285ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2879566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
288dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2902764a2aaSMatthew G. Knepley }
2912764a2aaSMatthew G. Knepley 
2922764a2aaSMatthew G. Knepley /*@
293dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2942764a2aaSMatthew G. Knepley 
295d083f849SBarry Smith   Collective on prob
2962764a2aaSMatthew G. Knepley 
2972764a2aaSMatthew G. Knepley   Input Parameter:
298dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2992764a2aaSMatthew G. Knepley 
300dce8aebaSBarry Smith   Options Database Keys:
301dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
302dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
303147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
304147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
305147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
3062764a2aaSMatthew G. Knepley 
307dce8aebaSBarry Smith   Level: intermediate
3082764a2aaSMatthew G. Knepley 
309dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3102764a2aaSMatthew G. Knepley @*/
311d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
312d71ae5a4SJacob Faibussowitsch {
313f1fd5e65SToby Isaac   DSBoundary  b;
3142764a2aaSMatthew G. Knepley   const char *defaultType;
3152764a2aaSMatthew G. Knepley   char        name[256];
3162764a2aaSMatthew G. Knepley   PetscBool   flg;
3172764a2aaSMatthew G. Knepley 
3182764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3192764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3202764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3212764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3222764a2aaSMatthew G. Knepley   } else {
3232764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3242764a2aaSMatthew G. Knepley   }
3259566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3262764a2aaSMatthew G. Knepley 
327d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
328f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
329f1fd5e65SToby Isaac     char      optname[1024];
330f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
331f1fd5e65SToby Isaac     PetscBool flg;
332f1fd5e65SToby Isaac 
3339566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3349566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
336f1fd5e65SToby Isaac     if (flg) {
33745480ffeSMatthew G. Knepley       b->Nv = len;
3389566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3399566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3409566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3419566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
342f1fd5e65SToby Isaac     }
343e7b0402cSSander Arens     len = 1024;
3449566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3459566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3469566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
347f1fd5e65SToby Isaac     if (flg) {
34845480ffeSMatthew G. Knepley       b->Nc = len;
3499566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3509566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3519566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
352f1fd5e65SToby Isaac     }
353f1fd5e65SToby Isaac   }
3549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3552764a2aaSMatthew G. Knepley   if (flg) {
3569566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3572764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3592764a2aaSMatthew G. Knepley   }
3609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
36112fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
362dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3632764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
364dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
365d0609cedSBarry Smith   PetscOptionsEnd();
3669566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3682764a2aaSMatthew G. Knepley }
3692764a2aaSMatthew G. Knepley 
3702764a2aaSMatthew G. Knepley /*@C
371dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3722764a2aaSMatthew G. Knepley 
373d083f849SBarry Smith   Collective on prob
3742764a2aaSMatthew G. Knepley 
3752764a2aaSMatthew G. Knepley   Input Parameter:
376dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3772764a2aaSMatthew G. Knepley 
3782764a2aaSMatthew G. Knepley   Level: developer
3792764a2aaSMatthew G. Knepley 
380dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3812764a2aaSMatthew G. Knepley @*/
382d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
383d71ae5a4SJacob Faibussowitsch {
3842764a2aaSMatthew G. Knepley   const PetscInt Nf   = prob->Nf;
385f9244615SMatthew G. Knepley   PetscBool      hasH = PETSC_FALSE;
3864bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
38749ae0b56SMatthew G. Knepley   PetscInt       gorder = -1, fgorder = -1;
3882764a2aaSMatthew G. Knepley 
3892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3902764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3913ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3922764a2aaSMatthew G. Knepley   /* Calculate sizes */
3939566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3949566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
395f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3979566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3989566063dSJacob 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]));
3999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
40012fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
40112fc5b22SMatthew G. Knepley     PetscQuadrature mq = NULL, mfq = NULL;
40212fc5b22SMatthew G. Knepley     PetscInt        maxOrder = -1, maxFOrder = -1;
40312fc5b22SMatthew G. Knepley 
40412fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
40512fc5b22SMatthew G. Knepley       PetscObject     obj;
40612fc5b22SMatthew G. Knepley       PetscClassId    id;
40712fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
40812fc5b22SMatthew G. Knepley       PetscInt        order = -1, forder = -1;
40912fc5b22SMatthew G. Knepley 
41012fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41112fc5b22SMatthew G. Knepley       if (!obj) continue;
41212fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
41312fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
41412fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
41512fc5b22SMatthew G. Knepley 
41612fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
41712fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
41812fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41912fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
42012fc5b22SMatthew G. Knepley 
42112fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
42212fc5b22SMatthew G. Knepley       }
42312fc5b22SMatthew G. Knepley       if (q) PetscCall(PetscQuadratureGetOrder(q, &order));
42412fc5b22SMatthew G. Knepley       if (fq) PetscCall(PetscQuadratureGetOrder(fq, &forder));
42512fc5b22SMatthew G. Knepley       if (order > maxOrder) {
42612fc5b22SMatthew G. Knepley         maxOrder = order;
42712fc5b22SMatthew G. Knepley         mq       = q;
42812fc5b22SMatthew G. Knepley       }
42912fc5b22SMatthew G. Knepley       if (forder > maxFOrder) {
43012fc5b22SMatthew G. Knepley         maxFOrder = forder;
43112fc5b22SMatthew G. Knepley         mfq       = fq;
43212fc5b22SMatthew G. Knepley       }
43312fc5b22SMatthew G. Knepley     }
43412fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
43512fc5b22SMatthew G. Knepley       PetscObject  obj;
43612fc5b22SMatthew G. Knepley       PetscClassId id;
43712fc5b22SMatthew G. Knepley 
43812fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
43912fc5b22SMatthew G. Knepley       if (!obj) continue;
44012fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44112fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44212fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44312fc5b22SMatthew G. Knepley 
44412fc5b22SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, mq));
44512fc5b22SMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, mfq));
44612fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
44712fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
44812fc5b22SMatthew G. Knepley 
44912fc5b22SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, mq));
45012fc5b22SMatthew G. Knepley       }
45112fc5b22SMatthew G. Knepley     }
45212fc5b22SMatthew G. Knepley   }
4532764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4549de99aefSMatthew G. Knepley     PetscObject     obj;
4559de99aefSMatthew G. Knepley     PetscClassId    id;
456665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4579de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4582764a2aaSMatthew G. Knepley 
4599566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
460f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
461665f567fSMatthew G. Knepley     if (!obj) {
462665f567fSMatthew G. Knepley       /* Empty mesh */
463665f567fSMatthew G. Knepley       Nb = Nc    = 0;
464665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
465665f567fSMatthew G. Knepley     } else {
4669566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4679de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4689de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4699de99aefSMatthew G. Knepley 
4709566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
47149ae0b56SMatthew G. Knepley         {
47249ae0b56SMatthew G. Knepley           PetscQuadrature fq;
47349ae0b56SMatthew G. Knepley           PetscInt        order, forder;
47449ae0b56SMatthew G. Knepley 
47549ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
47649ae0b56SMatthew G. Knepley           if (gorder < 0) gorder = order;
47749ae0b56SMatthew G. Knepley           PetscCheck(order == gorder, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, gorder);
47849ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
47949ae0b56SMatthew G. Knepley           if (fq) {
48049ae0b56SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &forder));
48149ae0b56SMatthew G. Knepley             if (fgorder < 0) fgorder = forder;
48249ae0b56SMatthew G. Knepley             PetscCheck(forder == fgorder, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, forder, fgorder);
48349ae0b56SMatthew G. Knepley           }
48449ae0b56SMatthew G. Knepley         }
4859566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4869566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4879566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4889566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4899de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4909de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4919de99aefSMatthew G. Knepley 
4929566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
4949c3cf19fSMatthew G. Knepley         Nb = Nc;
4959566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
4964d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
49763a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
498665f567fSMatthew G. Knepley     }
49947e57110SSander Arens     prob->Nc[f]                    = Nc;
50047e57110SSander Arens     prob->Nb[f]                    = Nb;
501194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
502194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5039ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5049ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5059ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5069ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5079ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5089ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5099566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5102764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5114bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5122764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5139c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5142764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5155fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5165fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5172764a2aaSMatthew G. Knepley   }
5189ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5199ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5202764a2aaSMatthew G. Knepley   /* Allocate works space */
5215fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5229566063dSJacob 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));
5239566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5249371c9d4SSatish 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,
5259371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
526dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5272764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5292764a2aaSMatthew G. Knepley }
5302764a2aaSMatthew G. Knepley 
531d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
532d71ae5a4SJacob Faibussowitsch {
5332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5349566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5359566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5369566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5379566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5389566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5399566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5409566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5422764a2aaSMatthew G. Knepley }
5432764a2aaSMatthew G. Knepley 
544d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
545d71ae5a4SJacob Faibussowitsch {
546f744cafaSSander Arens   PetscObject          *tmpd;
54734aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
548f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5495fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5506528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
551f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
552f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5530c2f2876SMatthew G. Knepley   void                **tmpctx;
55434aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5552764a2aaSMatthew G. Knepley 
5562764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5573ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5582764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5599566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5609566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5619371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5629371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5639371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5649371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5659371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5669371c9d4SSatish Balay   }
5679371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5689371c9d4SSatish Balay     tmpd[f] = NULL;
5699371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5709371c9d4SSatish Balay     tmpk[f] = 1;
5719371c9d4SSatish Balay   }
5729566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5742764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5752764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
576249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5775fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
578f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5799566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58032d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5810c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58232d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5830c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5849566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
58532d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5860c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5879566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
588c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
58995cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
590f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
591f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
592c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
59395cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
594f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
595f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
5969566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
597c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
59895cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
599f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
600f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6022764a2aaSMatthew G. Knepley }
6032764a2aaSMatthew G. Knepley 
6042764a2aaSMatthew G. Knepley /*@
6052764a2aaSMatthew G. Knepley   PetscDSDestroy - Destroys a PetscDS object
6062764a2aaSMatthew G. Knepley 
607d083f849SBarry Smith   Collective on prob
6082764a2aaSMatthew G. Knepley 
6092764a2aaSMatthew G. Knepley   Input Parameter:
6102764a2aaSMatthew G. Knepley . prob - the PetscDS object to destroy
6112764a2aaSMatthew G. Knepley 
6122764a2aaSMatthew G. Knepley   Level: developer
6132764a2aaSMatthew G. Knepley 
614dce8aebaSBarry Smith .seealso: `PetscDSView()`
6152764a2aaSMatthew G. Knepley @*/
616d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
617d71ae5a4SJacob Faibussowitsch {
6182764a2aaSMatthew G. Knepley   PetscInt f;
6192764a2aaSMatthew G. Knepley 
6202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6213ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6232764a2aaSMatthew G. Knepley 
6249371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6259371c9d4SSatish Balay     *ds = NULL;
6263ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6279371c9d4SSatish Balay   }
6286528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6296528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
630df3a45bdSMatthew G. Knepley     PetscInt dim, d;
631df3a45bdSMatthew G. Knepley 
6329566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6339566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
634df3a45bdSMatthew G. Knepley   }
6359566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6369566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
63748a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6389566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6409566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6419566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
642dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6439566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6449566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6459566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6472764a2aaSMatthew G. Knepley }
6482764a2aaSMatthew G. Knepley 
6492764a2aaSMatthew G. Knepley /*@
650dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6512764a2aaSMatthew G. Knepley 
652d083f849SBarry Smith   Collective
6532764a2aaSMatthew G. Knepley 
6542764a2aaSMatthew G. Knepley   Input Parameter:
655dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6562764a2aaSMatthew G. Knepley 
6572764a2aaSMatthew G. Knepley   Output Parameter:
658dce8aebaSBarry Smith . ds   - The `PetscDS` object
6592764a2aaSMatthew G. Knepley 
6602764a2aaSMatthew G. Knepley   Level: beginner
6612764a2aaSMatthew G. Knepley 
662dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6632764a2aaSMatthew G. Knepley @*/
664d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
665d71ae5a4SJacob Faibussowitsch {
6662764a2aaSMatthew G. Knepley   PetscDS p;
6672764a2aaSMatthew G. Knepley 
6682764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6696528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6706528b96dSMatthew G. Knepley   *ds = NULL;
6719566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6722764a2aaSMatthew G. Knepley 
6739566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6742764a2aaSMatthew G. Knepley 
6752764a2aaSMatthew G. Knepley   p->Nf           = 0;
6762764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
67797b6e6e8SMatthew G. Knepley   p->numConstants = 0;
67897b6e6e8SMatthew G. Knepley   p->constants    = NULL;
679a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
68055c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
68112fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6832764a2aaSMatthew G. Knepley 
6846528b96dSMatthew G. Knepley   *ds = p;
6853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6862764a2aaSMatthew G. Knepley }
6872764a2aaSMatthew G. Knepley 
688bc4ae4beSMatthew G. Knepley /*@
689dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
690bc4ae4beSMatthew G. Knepley 
691bc4ae4beSMatthew G. Knepley   Not collective
692bc4ae4beSMatthew G. Knepley 
693bc4ae4beSMatthew G. Knepley   Input Parameter:
694bc4ae4beSMatthew G. Knepley . prob - The PetscDS object
695bc4ae4beSMatthew G. Knepley 
696bc4ae4beSMatthew G. Knepley   Output Parameter:
697bc4ae4beSMatthew G. Knepley . Nf - The number of fields
698bc4ae4beSMatthew G. Knepley 
699bc4ae4beSMatthew G. Knepley   Level: beginner
700bc4ae4beSMatthew G. Knepley 
701dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
702bc4ae4beSMatthew G. Knepley @*/
703d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
704d71ae5a4SJacob Faibussowitsch {
7052764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7062764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
707dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
7082764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7102764a2aaSMatthew G. Knepley }
7112764a2aaSMatthew G. Knepley 
712bc4ae4beSMatthew G. Knepley /*@
713dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
714bc4ae4beSMatthew G. Knepley 
715bc4ae4beSMatthew G. Knepley   Not collective
716bc4ae4beSMatthew G. Knepley 
717bc4ae4beSMatthew G. Knepley   Input Parameter:
718dce8aebaSBarry Smith . prob - The `PetscDS` object
719bc4ae4beSMatthew G. Knepley 
720bc4ae4beSMatthew G. Knepley   Output Parameter:
721bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
722bc4ae4beSMatthew G. Knepley 
723bc4ae4beSMatthew G. Knepley   Level: beginner
724bc4ae4beSMatthew G. Knepley 
725dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
726bc4ae4beSMatthew G. Knepley @*/
727d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
728d71ae5a4SJacob Faibussowitsch {
7292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7302764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
731dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7322764a2aaSMatthew G. Knepley   *dim = 0;
7339de99aefSMatthew G. Knepley   if (prob->Nf) {
7349de99aefSMatthew G. Knepley     PetscObject  obj;
7359de99aefSMatthew G. Knepley     PetscClassId id;
7369de99aefSMatthew G. Knepley 
7379566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
738665f567fSMatthew G. Knepley     if (obj) {
7399566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7409566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7419566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
74298921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7439de99aefSMatthew G. Knepley     }
744665f567fSMatthew G. Knepley   }
7453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7462764a2aaSMatthew G. Knepley }
7472764a2aaSMatthew G. Knepley 
748bc4ae4beSMatthew G. Knepley /*@
749dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
750a859676bSMatthew G. Knepley 
751a859676bSMatthew G. Knepley   Not collective
752a859676bSMatthew G. Knepley 
753a859676bSMatthew G. Knepley   Input Parameter:
754dce8aebaSBarry Smith . prob - The `PetscDS` object
755a859676bSMatthew G. Knepley 
756a859676bSMatthew G. Knepley   Output Parameter:
757a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
758a859676bSMatthew G. Knepley 
759a859676bSMatthew G. Knepley   Level: beginner
760a859676bSMatthew G. Knepley 
761dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
762a859676bSMatthew G. Knepley @*/
763d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
764d71ae5a4SJacob Faibussowitsch {
765a859676bSMatthew G. Knepley   PetscFunctionBegin;
766a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
767dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
76808401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
769a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
771a859676bSMatthew G. Knepley }
772a859676bSMatthew G. Knepley 
773a859676bSMatthew G. Knepley /*@
774dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
775a859676bSMatthew G. Knepley 
776d083f849SBarry Smith   Logically collective on prob
777a859676bSMatthew G. Knepley 
778a859676bSMatthew G. Knepley   Input Parameters:
779dce8aebaSBarry Smith + prob - The `PetscDS` object
780a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
781a859676bSMatthew G. Knepley 
782a859676bSMatthew G. Knepley   Level: beginner
783a859676bSMatthew G. Knepley 
784dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
785a859676bSMatthew G. Knepley @*/
786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
787d71ae5a4SJacob Faibussowitsch {
788a859676bSMatthew G. Knepley   PetscFunctionBegin;
789a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
79063a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
791a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
7923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
793a859676bSMatthew G. Knepley }
794a859676bSMatthew G. Knepley 
795a859676bSMatthew G. Knepley /*@
79612fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
79712fc5b22SMatthew G. Knepley 
79812fc5b22SMatthew G. Knepley   Not collective
79912fc5b22SMatthew G. Knepley 
80012fc5b22SMatthew G. Knepley   Input Parameter:
80112fc5b22SMatthew G. Knepley . prob - The `PetscDS` object
80212fc5b22SMatthew G. Knepley 
80312fc5b22SMatthew G. Knepley   Output Parameter:
80412fc5b22SMatthew G. Knepley . forceQuad - The flag
80512fc5b22SMatthew G. Knepley 
80612fc5b22SMatthew G. Knepley   Level: intermediate
80712fc5b22SMatthew G. Knepley 
80812fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
80912fc5b22SMatthew G. Knepley @*/
81012fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
81112fc5b22SMatthew G. Knepley {
81212fc5b22SMatthew G. Knepley   PetscFunctionBegin;
81312fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
81412fc5b22SMatthew G. Knepley   PetscValidIntPointer(forceQuad, 2);
81512fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
81612fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
81712fc5b22SMatthew G. Knepley }
81812fc5b22SMatthew G. Knepley 
81912fc5b22SMatthew G. Knepley /*@
82012fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
82112fc5b22SMatthew G. Knepley 
82212fc5b22SMatthew G. Knepley   Logically collective on ds
82312fc5b22SMatthew G. Knepley 
82412fc5b22SMatthew G. Knepley   Input Parameters:
82512fc5b22SMatthew G. Knepley + ds - The `PetscDS` object
82612fc5b22SMatthew G. Knepley - forceQuad - The flag
82712fc5b22SMatthew G. Knepley 
82812fc5b22SMatthew G. Knepley   Level: intermediate
82912fc5b22SMatthew G. Knepley 
83012fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
83112fc5b22SMatthew G. Knepley @*/
83212fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
83312fc5b22SMatthew G. Knepley {
83412fc5b22SMatthew G. Knepley   PetscFunctionBegin;
83512fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
83612fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
83712fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83812fc5b22SMatthew G. Knepley }
83912fc5b22SMatthew G. Knepley 
84012fc5b22SMatthew G. Knepley /*@
841dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8428edf6225SMatthew G. Knepley 
8438edf6225SMatthew G. Knepley   Not collective
8448edf6225SMatthew G. Knepley 
8458edf6225SMatthew G. Knepley   Input Parameter:
846dce8aebaSBarry Smith . ds - The `PetscDS` object
8478edf6225SMatthew G. Knepley 
8488edf6225SMatthew G. Knepley   Output Parameter:
8495fedec97SMatthew G. Knepley . isCohesive - The flag
8508edf6225SMatthew G. Knepley 
8518edf6225SMatthew G. Knepley   Level: developer
8528edf6225SMatthew G. Knepley 
853dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8548edf6225SMatthew G. Knepley @*/
855d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
856d71ae5a4SJacob Faibussowitsch {
8578edf6225SMatthew G. Knepley   PetscFunctionBegin;
8585fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
859dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8605fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8628edf6225SMatthew G. Knepley }
8638edf6225SMatthew G. Knepley 
8648edf6225SMatthew G. Knepley /*@
8655fedec97SMatthew G. Knepley   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
8665fedec97SMatthew G. Knepley 
8675fedec97SMatthew G. Knepley   Not collective
8685fedec97SMatthew G. Knepley 
8695fedec97SMatthew G. Knepley   Input Parameter:
870dce8aebaSBarry Smith . ds - The `PetscDS` object
8715fedec97SMatthew G. Knepley 
8725fedec97SMatthew G. Knepley   Output Parameter:
8735fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8745fedec97SMatthew G. Knepley 
8755fedec97SMatthew G. Knepley   Level: developer
8765fedec97SMatthew G. Knepley 
877dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8785fedec97SMatthew G. Knepley @*/
879d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
880d71ae5a4SJacob Faibussowitsch {
8815fedec97SMatthew G. Knepley   PetscInt f;
8825fedec97SMatthew G. Knepley 
8835fedec97SMatthew G. Knepley   PetscFunctionBegin;
8845fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
885dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
8865fedec97SMatthew G. Knepley   *numCohesive = 0;
8875fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
8883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8895fedec97SMatthew G. Knepley }
8905fedec97SMatthew G. Knepley 
8915fedec97SMatthew G. Knepley /*@
8925fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
8935fedec97SMatthew G. Knepley 
8945fedec97SMatthew G. Knepley   Not collective
8955fedec97SMatthew G. Knepley 
896f1a722f8SMatthew G. Knepley   Input Parameters:
897dce8aebaSBarry Smith + ds - The `PetscDS` object
8985fedec97SMatthew G. Knepley - f  - The field index
8995fedec97SMatthew G. Knepley 
9005fedec97SMatthew G. Knepley   Output Parameter:
9015fedec97SMatthew G. Knepley . isCohesive - The flag
9025fedec97SMatthew G. Knepley 
9035fedec97SMatthew G. Knepley   Level: developer
9045fedec97SMatthew G. Knepley 
905dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9065fedec97SMatthew G. Knepley @*/
907d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
908d71ae5a4SJacob Faibussowitsch {
9095fedec97SMatthew G. Knepley   PetscFunctionBegin;
9105fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
911dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
91263a3b9bcSJacob 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);
9135fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9155fedec97SMatthew G. Knepley }
9165fedec97SMatthew G. Knepley 
9175fedec97SMatthew G. Knepley /*@
9185fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9198edf6225SMatthew G. Knepley 
9208edf6225SMatthew G. Knepley   Not collective
9218edf6225SMatthew G. Knepley 
9228edf6225SMatthew G. Knepley   Input Parameters:
923dce8aebaSBarry Smith + ds - The `PetscDS` object
9245fedec97SMatthew G. Knepley . f  - The field index
9255fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9268edf6225SMatthew G. Knepley 
9278edf6225SMatthew G. Knepley   Level: developer
9288edf6225SMatthew G. Knepley 
929dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9308edf6225SMatthew G. Knepley @*/
931d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
932d71ae5a4SJacob Faibussowitsch {
9335fedec97SMatthew G. Knepley   PetscInt i;
9345fedec97SMatthew G. Knepley 
9358edf6225SMatthew G. Knepley   PetscFunctionBegin;
9365fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
93763a3b9bcSJacob 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);
9385fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9395fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9405fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9428edf6225SMatthew G. Knepley }
9438edf6225SMatthew G. Knepley 
9448edf6225SMatthew G. Knepley /*@
945bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
946bc4ae4beSMatthew G. Knepley 
947bc4ae4beSMatthew G. Knepley   Not collective
948bc4ae4beSMatthew G. Knepley 
949bc4ae4beSMatthew G. Knepley   Input Parameter:
950dce8aebaSBarry Smith . prob - The `PetscDS` object
951bc4ae4beSMatthew G. Knepley 
952bc4ae4beSMatthew G. Knepley   Output Parameter:
953bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
954bc4ae4beSMatthew G. Knepley 
955bc4ae4beSMatthew G. Knepley   Level: beginner
956bc4ae4beSMatthew G. Knepley 
957dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
958bc4ae4beSMatthew G. Knepley @*/
959d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
960d71ae5a4SJacob Faibussowitsch {
9612764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9622764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9639566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
964dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9652764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9672764a2aaSMatthew G. Knepley }
9682764a2aaSMatthew G. Knepley 
969bc4ae4beSMatthew G. Knepley /*@
970bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
971bc4ae4beSMatthew G. Knepley 
972bc4ae4beSMatthew G. Knepley   Not collective
973bc4ae4beSMatthew G. Knepley 
974bc4ae4beSMatthew G. Knepley   Input Parameter:
975dce8aebaSBarry Smith . prob - The `PetscDS` object
976bc4ae4beSMatthew G. Knepley 
977bc4ae4beSMatthew G. Knepley   Output Parameter:
978bc4ae4beSMatthew G. Knepley . dim - The total number of components
979bc4ae4beSMatthew G. Knepley 
980bc4ae4beSMatthew G. Knepley   Level: beginner
981bc4ae4beSMatthew G. Knepley 
982dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
983bc4ae4beSMatthew G. Knepley @*/
984d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
985d71ae5a4SJacob Faibussowitsch {
9862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9872764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9889566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
989dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
9902764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
9913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9922764a2aaSMatthew G. Knepley }
9932764a2aaSMatthew G. Knepley 
994bc4ae4beSMatthew G. Knepley /*@
995bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
996bc4ae4beSMatthew G. Knepley 
997bc4ae4beSMatthew G. Knepley   Not collective
998bc4ae4beSMatthew G. Knepley 
999bc4ae4beSMatthew G. Knepley   Input Parameters:
1000dce8aebaSBarry Smith + prob - The `PetscDS` object
1001bc4ae4beSMatthew G. Knepley - f - The field number
1002bc4ae4beSMatthew G. Knepley 
1003bc4ae4beSMatthew G. Knepley   Output Parameter:
1004bc4ae4beSMatthew G. Knepley . disc - The discretization object
1005bc4ae4beSMatthew G. Knepley 
1006bc4ae4beSMatthew G. Knepley   Level: beginner
1007bc4ae4beSMatthew G. Knepley 
1008dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1009bc4ae4beSMatthew G. Knepley @*/
1010d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1011d71ae5a4SJacob Faibussowitsch {
10126528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10132764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10142764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
101563a3b9bcSJacob 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);
10162764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10182764a2aaSMatthew G. Knepley }
10192764a2aaSMatthew G. Knepley 
1020bc4ae4beSMatthew G. Knepley /*@
1021bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1022bc4ae4beSMatthew G. Knepley 
1023bc4ae4beSMatthew G. Knepley   Not collective
1024bc4ae4beSMatthew G. Knepley 
1025bc4ae4beSMatthew G. Knepley   Input Parameters:
1026dce8aebaSBarry Smith + prob - The `PetscDS` object
1027bc4ae4beSMatthew G. Knepley . f - The field number
1028bc4ae4beSMatthew G. Knepley - disc - The discretization object
1029bc4ae4beSMatthew G. Knepley 
1030bc4ae4beSMatthew G. Knepley   Level: beginner
1031bc4ae4beSMatthew G. Knepley 
1032dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1033bc4ae4beSMatthew G. Knepley @*/
1034d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1035d71ae5a4SJacob Faibussowitsch {
10362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10372764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1038665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
103963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10409566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10419566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10422764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10439566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1044665f567fSMatthew G. Knepley   if (disc) {
1045249df284SMatthew G. Knepley     PetscClassId id;
1046249df284SMatthew G. Knepley 
10479566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10481cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10499566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10501cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10519566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1052a6cbbb48SMatthew G. Knepley     }
10539566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1054249df284SMatthew G. Knepley   }
10553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10562764a2aaSMatthew G. Knepley }
10572764a2aaSMatthew G. Knepley 
1058bc4ae4beSMatthew G. Knepley /*@
10596528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10606528b96dSMatthew G. Knepley 
10616528b96dSMatthew G. Knepley   Not collective
10626528b96dSMatthew G. Knepley 
10636528b96dSMatthew G. Knepley   Input Parameter:
1064dce8aebaSBarry Smith . ds - The `PetscDS` object
10656528b96dSMatthew G. Knepley 
10666528b96dSMatthew G. Knepley   Output Parameter:
10676528b96dSMatthew G. Knepley . wf - The weak form object
10686528b96dSMatthew G. Knepley 
10696528b96dSMatthew G. Knepley   Level: beginner
10706528b96dSMatthew G. Knepley 
1071dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10726528b96dSMatthew G. Knepley @*/
1073d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1074d71ae5a4SJacob Faibussowitsch {
10756528b96dSMatthew G. Knepley   PetscFunctionBegin;
10766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10776528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10786528b96dSMatthew G. Knepley   *wf = ds->wf;
10793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10806528b96dSMatthew G. Knepley }
10816528b96dSMatthew G. Knepley 
10826528b96dSMatthew G. Knepley /*@
10836528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10846528b96dSMatthew G. Knepley 
10856528b96dSMatthew G. Knepley   Not collective
10866528b96dSMatthew G. Knepley 
10876528b96dSMatthew G. Knepley   Input Parameters:
1088dce8aebaSBarry Smith + ds - The `PetscDS` object
10896528b96dSMatthew G. Knepley - wf - The weak form object
10906528b96dSMatthew G. Knepley 
10916528b96dSMatthew G. Knepley   Level: beginner
10926528b96dSMatthew G. Knepley 
1093dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10946528b96dSMatthew G. Knepley @*/
1095d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1096d71ae5a4SJacob Faibussowitsch {
10976528b96dSMatthew G. Knepley   PetscFunctionBegin;
10986528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10996528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11009566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11016528b96dSMatthew G. Knepley   ds->wf = wf;
11029566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11056528b96dSMatthew G. Knepley }
11066528b96dSMatthew G. Knepley 
11076528b96dSMatthew G. Knepley /*@
1108bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1109bc4ae4beSMatthew G. Knepley 
1110bc4ae4beSMatthew G. Knepley   Not collective
1111bc4ae4beSMatthew G. Knepley 
1112bc4ae4beSMatthew G. Knepley   Input Parameters:
1113dce8aebaSBarry Smith + prob - The `PetscDS` object
1114bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1115bc4ae4beSMatthew G. Knepley 
1116bc4ae4beSMatthew G. Knepley   Level: beginner
1117bc4ae4beSMatthew G. Knepley 
1118dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1119bc4ae4beSMatthew G. Knepley @*/
1120d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1121d71ae5a4SJacob Faibussowitsch {
11222764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11239566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11252764a2aaSMatthew G. Knepley }
11262764a2aaSMatthew G. Knepley 
1127249df284SMatthew G. Knepley /*@
1128dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1129083401c6SMatthew G. Knepley 
1130083401c6SMatthew G. Knepley   Not collective
1131083401c6SMatthew G. Knepley 
1132083401c6SMatthew G. Knepley   Input Parameter:
1133dce8aebaSBarry Smith . prob - The `PetscDS` object
1134083401c6SMatthew G. Knepley 
1135083401c6SMatthew G. Knepley   Output Parameter:
1136083401c6SMatthew G. Knepley . q - The quadrature object
1137083401c6SMatthew G. Knepley 
1138083401c6SMatthew G. Knepley   Level: intermediate
1139083401c6SMatthew G. Knepley 
1140dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1141083401c6SMatthew G. Knepley @*/
1142d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1143d71ae5a4SJacob Faibussowitsch {
1144083401c6SMatthew G. Knepley   PetscObject  obj;
1145083401c6SMatthew G. Knepley   PetscClassId id;
1146083401c6SMatthew G. Knepley 
1147083401c6SMatthew G. Knepley   PetscFunctionBegin;
1148083401c6SMatthew G. Knepley   *q = NULL;
11493ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11509566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11519566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11529566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11539566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
115498921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1156083401c6SMatthew G. Knepley }
1157083401c6SMatthew G. Knepley 
1158083401c6SMatthew G. Knepley /*@
1159dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1160249df284SMatthew G. Knepley 
1161249df284SMatthew G. Knepley   Not collective
1162249df284SMatthew G. Knepley 
1163249df284SMatthew G. Knepley   Input Parameters:
1164dce8aebaSBarry Smith + prob - The `PetscDS` object
1165249df284SMatthew G. Knepley - f - The field number
1166249df284SMatthew G. Knepley 
1167249df284SMatthew G. Knepley   Output Parameter:
1168249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1169249df284SMatthew G. Knepley 
1170249df284SMatthew G. Knepley   Level: developer
1171249df284SMatthew G. Knepley 
1172dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1173249df284SMatthew G. Knepley @*/
1174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1175d71ae5a4SJacob Faibussowitsch {
1176249df284SMatthew G. Knepley   PetscFunctionBegin;
1177249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1178dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
117963a3b9bcSJacob 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);
1180249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1182249df284SMatthew G. Knepley }
1183249df284SMatthew G. Knepley 
1184249df284SMatthew G. Knepley /*@
1185dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1186249df284SMatthew G. Knepley 
1187249df284SMatthew G. Knepley   Not collective
1188249df284SMatthew G. Knepley 
1189249df284SMatthew G. Knepley   Input Parameters:
1190dce8aebaSBarry Smith + prob - The `PetscDS` object
1191249df284SMatthew G. Knepley . f - The field number
1192249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1193249df284SMatthew G. Knepley 
1194249df284SMatthew G. Knepley   Level: developer
1195249df284SMatthew G. Knepley 
1196dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1197249df284SMatthew G. Knepley @*/
1198d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1199d71ae5a4SJacob Faibussowitsch {
1200249df284SMatthew G. Knepley   PetscFunctionBegin;
1201249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
120263a3b9bcSJacob 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);
1203249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1205249df284SMatthew G. Knepley }
1206249df284SMatthew G. Knepley 
1207f9244615SMatthew G. Knepley /*@
1208f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1209f9244615SMatthew G. Knepley 
1210f9244615SMatthew G. Knepley   Not collective
1211f9244615SMatthew G. Knepley 
1212f9244615SMatthew G. Knepley   Input Parameters:
1213dce8aebaSBarry Smith + ds - The `PetscDS` object
1214f9244615SMatthew G. Knepley - f  - The field number
1215f9244615SMatthew G. Knepley 
1216f9244615SMatthew G. Knepley   Output Parameter:
1217f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1218f9244615SMatthew G. Knepley 
1219f9244615SMatthew G. Knepley   Level: developer
1220f9244615SMatthew G. Knepley 
1221dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1222f9244615SMatthew G. Knepley @*/
1223d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1224d71ae5a4SJacob Faibussowitsch {
1225f9244615SMatthew G. Knepley   PetscFunctionBegin;
1226f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1227dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
122863a3b9bcSJacob 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);
1229f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1231f9244615SMatthew G. Knepley }
1232f9244615SMatthew G. Knepley 
1233f9244615SMatthew G. Knepley /*@
1234f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1235f9244615SMatthew G. Knepley 
1236f9244615SMatthew G. Knepley   Not collective
1237f9244615SMatthew G. Knepley 
1238f9244615SMatthew G. Knepley   Input Parameters:
1239dce8aebaSBarry Smith + ds - The `PetscDS` object
1240f9244615SMatthew G. Knepley . f  - The field number
1241f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1242f9244615SMatthew G. Knepley 
1243f9244615SMatthew G. Knepley   Level: developer
1244f9244615SMatthew G. Knepley 
1245dce8aebaSBarry Smith .seealso: ``PetscDS`, PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1246f9244615SMatthew G. Knepley @*/
1247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1248d71ae5a4SJacob Faibussowitsch {
1249f9244615SMatthew G. Knepley   PetscFunctionBegin;
1250f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
125163a3b9bcSJacob 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);
1252f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1254f9244615SMatthew G. Knepley }
1255f9244615SMatthew G. Knepley 
1256d71ae5a4SJacob 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[]))
1257d71ae5a4SJacob Faibussowitsch {
12586528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
12596528b96dSMatthew G. Knepley   PetscInt        n;
12606528b96dSMatthew G. Knepley 
12612764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12626528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12636528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
126463a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
12659566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
12666528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
12673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12682764a2aaSMatthew G. Knepley }
12692764a2aaSMatthew G. Knepley 
1270d71ae5a4SJacob 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[]))
1271d71ae5a4SJacob Faibussowitsch {
12722764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12736528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12746528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
127563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12769566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
12773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12782764a2aaSMatthew G. Knepley }
12792764a2aaSMatthew G. Knepley 
1280194d53e6SMatthew G. Knepley /*@C
1281194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1282194d53e6SMatthew G. Knepley 
1283194d53e6SMatthew G. Knepley   Not collective
1284194d53e6SMatthew G. Knepley 
1285194d53e6SMatthew G. Knepley   Input Parameters:
1286dce8aebaSBarry Smith + ds - The `PetscDS`
1287194d53e6SMatthew G. Knepley - f  - The test field number
1288194d53e6SMatthew G. Knepley 
1289194d53e6SMatthew G. Knepley   Output Parameters:
1290194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1291194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1292194d53e6SMatthew G. Knepley 
1293dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1294dce8aebaSBarry Smith .vb
1295dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1296dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1297dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1298dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1299dce8aebaSBarry Smith .ve
1300194d53e6SMatthew G. Knepley + dim - the spatial dimension
1301194d53e6SMatthew G. Knepley . Nf - the number of fields
1302194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1303194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1304194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1305194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1306194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1307194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1308194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1309194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1310194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1311194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1312194d53e6SMatthew G. Knepley . t - current time
1313194d53e6SMatthew G. Knepley . x - coordinates of the current point
131497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
131597b6e6e8SMatthew G. Knepley . constants - constant parameters
1316194d53e6SMatthew G. Knepley - f0 - output values at the current point
1317194d53e6SMatthew G. Knepley 
1318194d53e6SMatthew G. Knepley   Level: intermediate
1319194d53e6SMatthew G. Knepley 
1320dce8aebaSBarry Smith   Note:
1321dce8aebaSBarry 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)
1322dce8aebaSBarry Smith 
1323dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1324194d53e6SMatthew G. Knepley @*/
1325d71ae5a4SJacob 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[]))
1326d71ae5a4SJacob Faibussowitsch {
13276528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
13286528b96dSMatthew G. Knepley   PetscInt        n0, n1;
13296528b96dSMatthew G. Knepley 
13302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
133263a3b9bcSJacob 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);
13339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13346528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13356528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13372764a2aaSMatthew G. Knepley }
13382764a2aaSMatthew G. Knepley 
1339194d53e6SMatthew G. Knepley /*@C
1340194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1341194d53e6SMatthew G. Knepley 
1342194d53e6SMatthew G. Knepley   Not collective
1343194d53e6SMatthew G. Knepley 
1344194d53e6SMatthew G. Knepley   Input Parameters:
1345dce8aebaSBarry Smith + ds - The `PetscDS`
1346194d53e6SMatthew G. Knepley . f  - The test field number
1347194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1348194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1349194d53e6SMatthew G. Knepley 
1350dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1351dce8aebaSBarry Smith .vb
1352dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1353dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1354dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1355dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1356dce8aebaSBarry Smith .ve
1357194d53e6SMatthew G. Knepley + dim - the spatial dimension
1358194d53e6SMatthew G. Knepley . Nf - the number of fields
1359194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1360194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1361194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1362194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1363194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1364194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1365194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1366194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1367194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1368194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1369194d53e6SMatthew G. Knepley . t - current time
1370194d53e6SMatthew G. Knepley . x - coordinates of the current point
137197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
137297b6e6e8SMatthew G. Knepley . constants - constant parameters
1373194d53e6SMatthew G. Knepley - f0 - output values at the current point
1374194d53e6SMatthew G. Knepley 
1375194d53e6SMatthew G. Knepley   Level: intermediate
1376194d53e6SMatthew G. Knepley 
1377dce8aebaSBarry Smith   Note:
1378dce8aebaSBarry 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)
1379dce8aebaSBarry Smith 
1380dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1381194d53e6SMatthew G. Knepley @*/
1382d71ae5a4SJacob 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[]))
1383d71ae5a4SJacob Faibussowitsch {
13842764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13856528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1386f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1387f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
138863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
13903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13912764a2aaSMatthew G. Knepley }
13922764a2aaSMatthew G. Knepley 
13933e75805dSMatthew G. Knepley /*@C
1394cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1395cb36c0f9SMatthew G. Knepley 
1396cb36c0f9SMatthew G. Knepley   Not collective
1397cb36c0f9SMatthew G. Knepley 
1398cb36c0f9SMatthew G. Knepley   Input Parameters:
1399dce8aebaSBarry Smith + ds - The `PetscDS`
1400cb36c0f9SMatthew G. Knepley - f  - The test field number
1401cb36c0f9SMatthew G. Knepley 
1402cb36c0f9SMatthew G. Knepley   Output Parameters:
1403cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1404cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1405cb36c0f9SMatthew G. Knepley 
1406dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1407dce8aebaSBarry Smith .vb
1408dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1409dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1410dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1411dce8aebaSBarry Smith     PetscReal t, const PetscReal x[], PetscScalar f0[])
1412dce8aebaSBarry Smith .ve
1413cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1414cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1415cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1416cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1417cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1418cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1419cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1420cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1421cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1422cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1423cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1424cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1425cb36c0f9SMatthew G. Knepley . t - current time
1426cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1427cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1428cb36c0f9SMatthew G. Knepley . constants - constant parameters
1429cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1430cb36c0f9SMatthew G. Knepley 
1431cb36c0f9SMatthew G. Knepley   Level: intermediate
1432cb36c0f9SMatthew G. Knepley 
1433dce8aebaSBarry Smith   Note:
1434dce8aebaSBarry 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)
1435dce8aebaSBarry Smith 
1436dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1437cb36c0f9SMatthew G. Knepley @*/
1438d71ae5a4SJacob 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[]))
1439d71ae5a4SJacob Faibussowitsch {
1440cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1441cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1442cb36c0f9SMatthew G. Knepley 
1443cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1444cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
144563a3b9bcSJacob 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);
14469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1447cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1448cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1450cb36c0f9SMatthew G. Knepley }
1451cb36c0f9SMatthew G. Knepley 
1452cb36c0f9SMatthew G. Knepley /*@C
1453cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1454cb36c0f9SMatthew G. Knepley 
1455cb36c0f9SMatthew G. Knepley   Not collective
1456cb36c0f9SMatthew G. Knepley 
1457cb36c0f9SMatthew G. Knepley   Input Parameters:
1458dce8aebaSBarry Smith + ds - The `PetscDS`
1459cb36c0f9SMatthew G. Knepley . f  - The test field number
1460cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1461cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1462cb36c0f9SMatthew G. Knepley 
1463dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1464dce8aebaSBarry Smith .vb
1465dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1466dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1467dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1468dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1469dce8aebaSBarry Smith .ve
1470cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1471cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1472cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1473cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1474cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1475cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1476cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1477cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1478cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1479cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1480cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1481cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1482cb36c0f9SMatthew G. Knepley . t - current time
1483cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1484cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1485cb36c0f9SMatthew G. Knepley . constants - constant parameters
1486cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1487cb36c0f9SMatthew G. Knepley 
1488cb36c0f9SMatthew G. Knepley   Level: intermediate
1489cb36c0f9SMatthew G. Knepley 
1490dce8aebaSBarry Smith   Note:
1491dce8aebaSBarry 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)
1492dce8aebaSBarry Smith 
1493dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1494cb36c0f9SMatthew G. Knepley @*/
1495d71ae5a4SJacob 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[]))
1496d71ae5a4SJacob Faibussowitsch {
1497cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1498cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1499cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1500cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
150163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1504cb36c0f9SMatthew G. Knepley }
1505cb36c0f9SMatthew G. Knepley 
1506cb36c0f9SMatthew G. Knepley /*@C
1507dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15083e75805dSMatthew G. Knepley 
15093e75805dSMatthew G. Knepley   Not collective
15103e75805dSMatthew G. Knepley 
15113e75805dSMatthew G. Knepley   Input Parameter:
1512dce8aebaSBarry Smith . prob - The `PetscDS`
15133e75805dSMatthew G. Knepley 
15143e75805dSMatthew G. Knepley   Output Parameter:
15153e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15163e75805dSMatthew G. Knepley 
15173e75805dSMatthew G. Knepley   Level: intermediate
15183e75805dSMatthew G. Knepley 
1519dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15203e75805dSMatthew G. Knepley @*/
1521d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1522d71ae5a4SJacob Faibussowitsch {
15233e75805dSMatthew G. Knepley   PetscFunctionBegin;
15246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
15263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15273e75805dSMatthew G. Knepley }
15283e75805dSMatthew G. Knepley 
1529194d53e6SMatthew G. Knepley /*@C
1530194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1531194d53e6SMatthew G. Knepley 
1532194d53e6SMatthew G. Knepley   Not collective
1533194d53e6SMatthew G. Knepley 
1534194d53e6SMatthew G. Knepley   Input Parameters:
1535dce8aebaSBarry Smith + ds - The `PetscDS`
1536194d53e6SMatthew G. Knepley . f  - The test field number
1537194d53e6SMatthew G. Knepley - g  - The field number
1538194d53e6SMatthew G. Knepley 
1539194d53e6SMatthew G. Knepley   Output Parameters:
1540194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1541194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1542194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1543194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1544194d53e6SMatthew G. Knepley 
1545dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1546dce8aebaSBarry Smith .vb
1547dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1548dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1549dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1550dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1551dce8aebaSBarry Smith .ve
1552194d53e6SMatthew G. Knepley + dim - the spatial dimension
1553194d53e6SMatthew G. Knepley . Nf - the number of fields
1554194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1555194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1556194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1557194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1558194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1559194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1560194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1561194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1562194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1563194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1564194d53e6SMatthew G. Knepley . t - current time
15652aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1566194d53e6SMatthew G. Knepley . x - coordinates of the current point
156797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
156897b6e6e8SMatthew G. Knepley . constants - constant parameters
1569194d53e6SMatthew G. Knepley - g0 - output values at the current point
1570194d53e6SMatthew G. Knepley 
1571194d53e6SMatthew G. Knepley   Level: intermediate
1572194d53e6SMatthew G. Knepley 
1573dce8aebaSBarry Smith   Note:
1574dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1575dce8aebaSBarry 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
1576dce8aebaSBarry Smith 
1577dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1578194d53e6SMatthew G. Knepley @*/
1579d71ae5a4SJacob 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[]))
1580d71ae5a4SJacob Faibussowitsch {
15816528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
15826528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
15836528b96dSMatthew G. Knepley 
15842764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15856528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
158663a3b9bcSJacob 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);
158763a3b9bcSJacob 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);
15889566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
15896528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
15906528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
15916528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
15926528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
15933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15942764a2aaSMatthew G. Knepley }
15952764a2aaSMatthew G. Knepley 
1596194d53e6SMatthew G. Knepley /*@C
1597194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1598194d53e6SMatthew G. Knepley 
1599194d53e6SMatthew G. Knepley   Not collective
1600194d53e6SMatthew G. Knepley 
1601194d53e6SMatthew G. Knepley   Input Parameters:
1602dce8aebaSBarry Smith + ds - The `PetscDS`
1603194d53e6SMatthew G. Knepley . f  - The test field number
1604194d53e6SMatthew G. Knepley . g  - The field number
1605194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1606194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1607194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1608194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1609194d53e6SMatthew G. Knepley 
1610dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1611dce8aebaSBarry Smith .vb
1612dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1613dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1614dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1615dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1616dce8aebaSBarry Smith .ve
1617194d53e6SMatthew G. Knepley + dim - the spatial dimension
1618194d53e6SMatthew G. Knepley . Nf - the number of fields
1619194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1620194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1621194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1622194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1623194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1624194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1625194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1626194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1627194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1628194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1629194d53e6SMatthew G. Knepley . t - current time
16302aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1631194d53e6SMatthew G. Knepley . x - coordinates of the current point
163297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
163397b6e6e8SMatthew G. Knepley . constants - constant parameters
1634194d53e6SMatthew G. Knepley - g0 - output values at the current point
1635194d53e6SMatthew G. Knepley 
1636194d53e6SMatthew G. Knepley   Level: intermediate
1637194d53e6SMatthew G. Knepley 
1638dce8aebaSBarry Smith   Note:
1639dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1640dce8aebaSBarry 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
1641dce8aebaSBarry Smith 
1642dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1643194d53e6SMatthew G. Knepley @*/
1644d71ae5a4SJacob 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[]))
1645d71ae5a4SJacob Faibussowitsch {
16462764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16476528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16482764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
16492764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
16502764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
16512764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
165263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
165363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
16549566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
16553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16562764a2aaSMatthew G. Knepley }
16572764a2aaSMatthew G. Knepley 
1658475e0ac9SMatthew G. Knepley /*@C
1659dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
166055c1f793SMatthew G. Knepley 
166155c1f793SMatthew G. Knepley   Not collective
166255c1f793SMatthew G. Knepley 
166355c1f793SMatthew G. Knepley   Input Parameters:
1664dce8aebaSBarry Smith + prob - The `PetscDS`
166555c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
166655c1f793SMatthew G. Knepley 
166755c1f793SMatthew G. Knepley   Level: intermediate
166855c1f793SMatthew G. Knepley 
1669dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
167055c1f793SMatthew G. Knepley @*/
1671d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1672d71ae5a4SJacob Faibussowitsch {
167355c1f793SMatthew G. Knepley   PetscFunctionBegin;
167455c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
167555c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
16763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
167755c1f793SMatthew G. Knepley }
167855c1f793SMatthew G. Knepley 
167955c1f793SMatthew G. Knepley /*@C
1680dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1681475e0ac9SMatthew G. Knepley 
1682475e0ac9SMatthew G. Knepley   Not collective
1683475e0ac9SMatthew G. Knepley 
1684475e0ac9SMatthew G. Knepley   Input Parameter:
1685dce8aebaSBarry Smith . prob - The `PetscDS`
1686475e0ac9SMatthew G. Knepley 
1687475e0ac9SMatthew G. Knepley   Output Parameter:
1688475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1689475e0ac9SMatthew G. Knepley 
1690475e0ac9SMatthew G. Knepley   Level: intermediate
1691475e0ac9SMatthew G. Knepley 
1692dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1693475e0ac9SMatthew G. Knepley @*/
1694d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1695d71ae5a4SJacob Faibussowitsch {
1696475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16976528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1698475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
16993ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17009566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1702475e0ac9SMatthew G. Knepley }
1703475e0ac9SMatthew G. Knepley 
1704475e0ac9SMatthew G. Knepley /*@C
1705dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1706dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1707475e0ac9SMatthew G. Knepley 
1708475e0ac9SMatthew G. Knepley   Not collective
1709475e0ac9SMatthew G. Knepley 
1710475e0ac9SMatthew G. Knepley   Input Parameters:
1711dce8aebaSBarry Smith + ds - The `PetscDS`
1712475e0ac9SMatthew G. Knepley . f  - The test field number
1713475e0ac9SMatthew G. Knepley - g  - The field number
1714475e0ac9SMatthew G. Knepley 
1715475e0ac9SMatthew G. Knepley   Output Parameters:
1716475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1717475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1718475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1719475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1720475e0ac9SMatthew G. Knepley 
1721dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1722dce8aebaSBarry Smith .vb
1723dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1724dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1725dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1726dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1727dce8aebaSBarry Smith .ve
1728475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1729475e0ac9SMatthew G. Knepley . Nf - the number of fields
1730475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1731475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1732475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1733475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1734475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1735475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1736475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1737475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1738475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1739475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1740475e0ac9SMatthew G. Knepley . t - current time
1741475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1742475e0ac9SMatthew G. Knepley . x - coordinates of the current point
174397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
174497b6e6e8SMatthew G. Knepley . constants - constant parameters
1745475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1746475e0ac9SMatthew G. Knepley 
1747475e0ac9SMatthew G. Knepley   Level: intermediate
1748475e0ac9SMatthew G. Knepley 
1749dce8aebaSBarry Smith   Note:
1750dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1751dce8aebaSBarry 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
1752dce8aebaSBarry Smith 
1753dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1754475e0ac9SMatthew G. Knepley @*/
1755d71ae5a4SJacob 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[]))
1756d71ae5a4SJacob Faibussowitsch {
17576528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17586528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17596528b96dSMatthew G. Knepley 
1760475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17616528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
176263a3b9bcSJacob 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);
176363a3b9bcSJacob 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);
17649566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17656528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17666528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17676528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17686528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1770475e0ac9SMatthew G. Knepley }
1771475e0ac9SMatthew G. Knepley 
1772475e0ac9SMatthew G. Knepley /*@C
1773dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1774dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1775475e0ac9SMatthew G. Knepley 
1776475e0ac9SMatthew G. Knepley   Not collective
1777475e0ac9SMatthew G. Knepley 
1778475e0ac9SMatthew G. Knepley   Input Parameters:
1779dce8aebaSBarry Smith + ds - The `PetscDS`
1780475e0ac9SMatthew G. Knepley . f  - The test field number
1781475e0ac9SMatthew G. Knepley . g  - The field number
1782475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1783475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1784475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1785475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1786475e0ac9SMatthew G. Knepley 
1787dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1788dce8aebaSBarry Smith .vb
1789dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1790dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1791dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1792dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1793dce8aebaSBarry Smith .ve
1794475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1795475e0ac9SMatthew G. Knepley . Nf - the number of fields
1796475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1797475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1798475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1799475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1800475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1801475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1802475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1803475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1804475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1805475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1806475e0ac9SMatthew G. Knepley . t - current time
1807475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1808475e0ac9SMatthew G. Knepley . x - coordinates of the current point
180997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
181097b6e6e8SMatthew G. Knepley . constants - constant parameters
1811475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1812475e0ac9SMatthew G. Knepley 
1813475e0ac9SMatthew G. Knepley   Level: intermediate
1814475e0ac9SMatthew G. Knepley 
1815dce8aebaSBarry Smith   Note:
1816dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1817dce8aebaSBarry 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
1818dce8aebaSBarry Smith 
1819dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1820475e0ac9SMatthew G. Knepley @*/
1821d71ae5a4SJacob 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[]))
1822d71ae5a4SJacob Faibussowitsch {
1823475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1825475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1826475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1827475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1828475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
182963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
183063a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1833475e0ac9SMatthew G. Knepley }
1834475e0ac9SMatthew G. Knepley 
1835b7e05686SMatthew G. Knepley /*@C
1836b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1837b7e05686SMatthew G. Knepley 
1838b7e05686SMatthew G. Knepley   Not collective
1839b7e05686SMatthew G. Knepley 
1840b7e05686SMatthew G. Knepley   Input Parameter:
1841dce8aebaSBarry Smith . ds - The `PetscDS`
1842b7e05686SMatthew G. Knepley 
1843b7e05686SMatthew G. Knepley   Output Parameter:
1844b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1845b7e05686SMatthew G. Knepley 
1846b7e05686SMatthew G. Knepley   Level: intermediate
1847b7e05686SMatthew G. Knepley 
1848dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1849b7e05686SMatthew G. Knepley @*/
1850d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1851d71ae5a4SJacob Faibussowitsch {
1852b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18549566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
18553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1856b7e05686SMatthew G. Knepley }
1857b7e05686SMatthew G. Knepley 
1858b7e05686SMatthew G. Knepley /*@C
1859b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1860b7e05686SMatthew G. Knepley 
1861b7e05686SMatthew G. Knepley   Not collective
1862b7e05686SMatthew G. Knepley 
1863b7e05686SMatthew G. Knepley   Input Parameters:
1864dce8aebaSBarry Smith + ds - The `PetscDS`
1865b7e05686SMatthew G. Knepley . f  - The test field number
1866b7e05686SMatthew G. Knepley - g  - The field number
1867b7e05686SMatthew G. Knepley 
1868b7e05686SMatthew G. Knepley   Output Parameters:
1869b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1870b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1871b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1872b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1873b7e05686SMatthew G. Knepley 
1874dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
1875dce8aebaSBarry Smith .vb
1876dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1877dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1878dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1879dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1880dce8aebaSBarry Smith .ve
1881b7e05686SMatthew G. Knepley + dim - the spatial dimension
1882b7e05686SMatthew G. Knepley . Nf - the number of fields
1883b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1884b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1885b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1886b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1887b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1888b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1889b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1890b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1891b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1892b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1893b7e05686SMatthew G. Knepley . t - current time
1894b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1895b7e05686SMatthew G. Knepley . x - coordinates of the current point
189697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
189797b6e6e8SMatthew G. Knepley . constants - constant parameters
1898b7e05686SMatthew G. Knepley - g0 - output values at the current point
1899b7e05686SMatthew G. Knepley 
1900b7e05686SMatthew G. Knepley   Level: intermediate
1901b7e05686SMatthew G. Knepley 
1902dce8aebaSBarry Smith   Note:
1903dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1904dce8aebaSBarry 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
1905dce8aebaSBarry Smith 
1906dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1907b7e05686SMatthew G. Knepley @*/
1908d71ae5a4SJacob 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[]))
1909d71ae5a4SJacob Faibussowitsch {
19106528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19116528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19126528b96dSMatthew G. Knepley 
1913b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
191563a3b9bcSJacob 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);
191663a3b9bcSJacob 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);
19179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19186528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19196528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19206528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19216528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1923b7e05686SMatthew G. Knepley }
1924b7e05686SMatthew G. Knepley 
1925b7e05686SMatthew G. Knepley /*@C
1926b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1927b7e05686SMatthew G. Knepley 
1928b7e05686SMatthew G. Knepley   Not collective
1929b7e05686SMatthew G. Knepley 
1930b7e05686SMatthew G. Knepley   Input Parameters:
1931dce8aebaSBarry Smith + ds - The `PetscDS`
1932b7e05686SMatthew G. Knepley . f  - The test field number
1933b7e05686SMatthew G. Knepley . g  - The field number
1934b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1935b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1936b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1937b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1938b7e05686SMatthew G. Knepley 
1939dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1940dce8aebaSBarry Smith .vb
1941dce8aebaSBarry Smith    g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1942dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1943dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1944dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1945dce8aebaSBarry Smith .ve
1946b7e05686SMatthew G. Knepley + dim - the spatial dimension
1947b7e05686SMatthew G. Knepley . Nf - the number of fields
1948b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1949b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1950b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1951b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1952b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1953b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1954b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1955b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1956b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1957b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1958b7e05686SMatthew G. Knepley . t - current time
1959b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1960b7e05686SMatthew G. Knepley . x - coordinates of the current point
196197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
196297b6e6e8SMatthew G. Knepley . constants - constant parameters
1963b7e05686SMatthew G. Knepley - g0 - output values at the current point
1964b7e05686SMatthew G. Knepley 
1965b7e05686SMatthew G. Knepley   Level: intermediate
1966b7e05686SMatthew G. Knepley 
1967dce8aebaSBarry Smith   Note:
1968dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1969dce8aebaSBarry 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
1970dce8aebaSBarry Smith 
1971dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1972b7e05686SMatthew G. Knepley @*/
1973d71ae5a4SJacob 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[]))
1974d71ae5a4SJacob Faibussowitsch {
1975b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1977b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1978b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1979b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1980b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
198163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
198263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1985b7e05686SMatthew G. Knepley }
1986b7e05686SMatthew G. Knepley 
19870c2f2876SMatthew G. Knepley /*@C
19880c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
19890c2f2876SMatthew G. Knepley 
19900c2f2876SMatthew G. Knepley   Not collective
19910c2f2876SMatthew G. Knepley 
19924165533cSJose E. Roman   Input Parameters:
1993dce8aebaSBarry Smith + ds - The `PetscDS` object
19940c2f2876SMatthew G. Knepley - f  - The field number
19950c2f2876SMatthew G. Knepley 
19964165533cSJose E. Roman   Output Parameter:
19970c2f2876SMatthew G. Knepley . r    - Riemann solver
19980c2f2876SMatthew G. Knepley 
19990c2f2876SMatthew G. Knepley   Calling sequence for r:
2000dce8aebaSBarry Smith .vb
2001dce8aebaSBarry Smith   r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2002dce8aebaSBarry Smith .ve
20035db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20045db36cf9SMatthew G. Knepley . Nf   - The number of fields
20055db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20060c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20070c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20080c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20090c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
201097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
201197b6e6e8SMatthew G. Knepley . constants - constant parameters
20120c2f2876SMatthew G. Knepley - ctx  - optional user context
20130c2f2876SMatthew G. Knepley 
20140c2f2876SMatthew G. Knepley   Level: intermediate
20150c2f2876SMatthew G. Knepley 
2016dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20170c2f2876SMatthew G. Knepley @*/
2018d71ae5a4SJacob 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))
2019d71ae5a4SJacob Faibussowitsch {
20206528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20216528b96dSMatthew G. Knepley   PetscInt          n;
20226528b96dSMatthew G. Knepley 
20230c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20250c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
202663a3b9bcSJacob 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);
20279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20286528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20300c2f2876SMatthew G. Knepley }
20310c2f2876SMatthew G. Knepley 
20320c2f2876SMatthew G. Knepley /*@C
20330c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20340c2f2876SMatthew G. Knepley 
20350c2f2876SMatthew G. Knepley   Not collective
20360c2f2876SMatthew G. Knepley 
20374165533cSJose E. Roman   Input Parameters:
2038dce8aebaSBarry Smith + ds - The `PetscDS` object
20390c2f2876SMatthew G. Knepley . f  - The field number
20400c2f2876SMatthew G. Knepley - r  - Riemann solver
20410c2f2876SMatthew G. Knepley 
20420c2f2876SMatthew G. Knepley   Calling sequence for r:
2043dce8aebaSBarry Smith .vb
2044dce8aebaSBarry Smith    r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2045dce8aebaSBarry Smith .ve
20465db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20475db36cf9SMatthew G. Knepley . Nf   - The number of fields
20485db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20490c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20500c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20510c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20520c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
205397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
205497b6e6e8SMatthew G. Knepley . constants - constant parameters
20550c2f2876SMatthew G. Knepley - ctx  - optional user context
20560c2f2876SMatthew G. Knepley 
20570c2f2876SMatthew G. Knepley   Level: intermediate
20580c2f2876SMatthew G. Knepley 
2059dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
20600c2f2876SMatthew G. Knepley @*/
2061d71ae5a4SJacob 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))
2062d71ae5a4SJacob Faibussowitsch {
20630c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2065de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
206663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
20683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20690c2f2876SMatthew G. Knepley }
20700c2f2876SMatthew G. Knepley 
207132d2bbc9SMatthew G. Knepley /*@C
207232d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
207332d2bbc9SMatthew G. Knepley 
207432d2bbc9SMatthew G. Knepley   Not collective
207532d2bbc9SMatthew G. Knepley 
207632d2bbc9SMatthew G. Knepley   Input Parameters:
2077dce8aebaSBarry Smith + ds - The `PetscDS`
207832d2bbc9SMatthew G. Knepley - f  - The field number
207932d2bbc9SMatthew G. Knepley 
2080f899ff85SJose E. Roman   Output Parameter:
2081a2b725a8SWilliam Gropp . update - update function
208232d2bbc9SMatthew G. Knepley 
2083dce8aebaSBarry Smith   Calling sequence for the callback update:
2084dce8aebaSBarry Smith .vb
2085dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2086dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2087dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2088dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2089dce8aebaSBarry Smith .ve
209032d2bbc9SMatthew G. Knepley + dim - the spatial dimension
209132d2bbc9SMatthew G. Knepley . Nf - the number of fields
209232d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
209332d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
209432d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
209532d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
209632d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
209732d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
209832d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
209932d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
210032d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
210132d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
210232d2bbc9SMatthew G. Knepley . t - current time
210332d2bbc9SMatthew G. Knepley . x - coordinates of the current point
210432d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
210532d2bbc9SMatthew G. Knepley 
210632d2bbc9SMatthew G. Knepley   Level: intermediate
210732d2bbc9SMatthew G. Knepley 
2108dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
210932d2bbc9SMatthew G. Knepley @*/
2110d71ae5a4SJacob 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[]))
2111d71ae5a4SJacob Faibussowitsch {
211232d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
211463a3b9bcSJacob 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);
21159371c9d4SSatish Balay   if (update) {
21169371c9d4SSatish Balay     PetscValidPointer(update, 3);
21179371c9d4SSatish Balay     *update = ds->update[f];
21189371c9d4SSatish Balay   }
21193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
212032d2bbc9SMatthew G. Knepley }
212132d2bbc9SMatthew G. Knepley 
212232d2bbc9SMatthew G. Knepley /*@C
21233fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
212432d2bbc9SMatthew G. Knepley 
212532d2bbc9SMatthew G. Knepley   Not collective
212632d2bbc9SMatthew G. Knepley 
212732d2bbc9SMatthew G. Knepley   Input Parameters:
2128dce8aebaSBarry Smith + ds     - The `PetscDS`
212932d2bbc9SMatthew G. Knepley . f      - The field number
213032d2bbc9SMatthew G. Knepley - update - update function
213132d2bbc9SMatthew G. Knepley 
2132dce8aebaSBarry Smith   Calling sequence for the callback update:
2133dce8aebaSBarry Smith .vb
2134dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2135dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2136dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2137dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2138dce8aebaSBarry Smith .ve
213932d2bbc9SMatthew G. Knepley + dim - the spatial dimension
214032d2bbc9SMatthew G. Knepley . Nf - the number of fields
214132d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
214232d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
214332d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
214432d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
214532d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
214632d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
214732d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
214832d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
214932d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
215032d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
215132d2bbc9SMatthew G. Knepley . t - current time
215232d2bbc9SMatthew G. Knepley . x - coordinates of the current point
215332d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
215432d2bbc9SMatthew G. Knepley 
215532d2bbc9SMatthew G. Knepley   Level: intermediate
215632d2bbc9SMatthew G. Knepley 
2157dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
215832d2bbc9SMatthew G. Knepley @*/
2159d71ae5a4SJacob 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[]))
2160d71ae5a4SJacob Faibussowitsch {
216132d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21626528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216332d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
216463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21659566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21666528b96dSMatthew G. Knepley   ds->update[f] = update;
21673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
216832d2bbc9SMatthew G. Knepley }
216932d2bbc9SMatthew G. Knepley 
2170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2171d71ae5a4SJacob Faibussowitsch {
21720c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21736528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217463a3b9bcSJacob 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);
21750c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
21763ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
21773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21780c2f2876SMatthew G. Knepley }
21790c2f2876SMatthew G. Knepley 
2180d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2181d71ae5a4SJacob Faibussowitsch {
21820c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21836528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
218463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21859566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21866528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
21873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21880c2f2876SMatthew G. Knepley }
21890c2f2876SMatthew G. Knepley 
2190194d53e6SMatthew G. Knepley /*@C
2191194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2192194d53e6SMatthew G. Knepley 
2193194d53e6SMatthew G. Knepley   Not collective
2194194d53e6SMatthew G. Knepley 
2195194d53e6SMatthew G. Knepley   Input Parameters:
21966528b96dSMatthew G. Knepley + ds - The PetscDS
2197194d53e6SMatthew G. Knepley - f  - The test field number
2198194d53e6SMatthew G. Knepley 
2199194d53e6SMatthew G. Knepley   Output Parameters:
2200194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2201194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2202194d53e6SMatthew G. Knepley 
2203dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2204dce8aebaSBarry Smith .vb
2205dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2206dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2207dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2208dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2209dce8aebaSBarry Smith .ve
2210194d53e6SMatthew G. Knepley + dim - the spatial dimension
2211194d53e6SMatthew G. Knepley . Nf - the number of fields
2212194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2213194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2214194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2215194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2216194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2217194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2218194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2219194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2220194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2221194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2222194d53e6SMatthew G. Knepley . t - current time
2223194d53e6SMatthew G. Knepley . x - coordinates of the current point
2224194d53e6SMatthew G. Knepley . n - unit normal at the current point
222597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
222697b6e6e8SMatthew G. Knepley . constants - constant parameters
2227194d53e6SMatthew G. Knepley - f0 - output values at the current point
2228194d53e6SMatthew G. Knepley 
2229194d53e6SMatthew G. Knepley   Level: intermediate
2230194d53e6SMatthew G. Knepley 
2231dce8aebaSBarry Smith   Note:
2232dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2233dce8aebaSBarry 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
2234dce8aebaSBarry Smith 
2235dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2236194d53e6SMatthew G. Knepley @*/
2237d71ae5a4SJacob 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[]))
2238d71ae5a4SJacob Faibussowitsch {
22396528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22406528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22416528b96dSMatthew G. Knepley 
22422764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22436528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
224463a3b9bcSJacob 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);
22459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22466528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22476528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22492764a2aaSMatthew G. Knepley }
22502764a2aaSMatthew G. Knepley 
2251194d53e6SMatthew G. Knepley /*@C
2252194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2253194d53e6SMatthew G. Knepley 
2254194d53e6SMatthew G. Knepley   Not collective
2255194d53e6SMatthew G. Knepley 
2256194d53e6SMatthew G. Knepley   Input Parameters:
2257dce8aebaSBarry Smith + ds - The `PetscDS`
2258194d53e6SMatthew G. Knepley . f  - The test field number
2259194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2260194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2261194d53e6SMatthew G. Knepley 
2262dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2263dce8aebaSBarry Smith .vb
2264dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2265dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2266dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2267dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2268dce8aebaSBarry Smith .ve
2269194d53e6SMatthew G. Knepley + dim - the spatial dimension
2270194d53e6SMatthew G. Knepley . Nf - the number of fields
2271194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2272194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2273194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2274194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2275194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2276194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2277194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2278194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2279194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2280194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2281194d53e6SMatthew G. Knepley . t - current time
2282194d53e6SMatthew G. Knepley . x - coordinates of the current point
2283194d53e6SMatthew G. Knepley . n - unit normal at the current point
228497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
228597b6e6e8SMatthew G. Knepley . constants - constant parameters
2286194d53e6SMatthew G. Knepley - f0 - output values at the current point
2287194d53e6SMatthew G. Knepley 
2288194d53e6SMatthew G. Knepley   Level: intermediate
2289194d53e6SMatthew G. Knepley 
2290dce8aebaSBarry Smith   Note:
2291dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2292dce8aebaSBarry 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
2293dce8aebaSBarry Smith 
2294dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2295194d53e6SMatthew G. Knepley @*/
2296d71ae5a4SJacob 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[]))
2297d71ae5a4SJacob Faibussowitsch {
22982764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22996528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
230063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23019566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23032764a2aaSMatthew G. Knepley }
23042764a2aaSMatthew G. Knepley 
230527f02ce8SMatthew G. Knepley /*@
2306dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
230727f02ce8SMatthew G. Knepley 
230827f02ce8SMatthew G. Knepley   Not collective
230927f02ce8SMatthew G. Knepley 
231027f02ce8SMatthew G. Knepley   Input Parameter:
2311dce8aebaSBarry Smith . ds - The `PetscDS`
231227f02ce8SMatthew G. Knepley 
231327f02ce8SMatthew G. Knepley   Output Parameter:
231427f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
231527f02ce8SMatthew G. Knepley 
231627f02ce8SMatthew G. Knepley   Level: intermediate
231727f02ce8SMatthew G. Knepley 
2318dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
231927f02ce8SMatthew G. Knepley @*/
2320d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2321d71ae5a4SJacob Faibussowitsch {
232227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23236528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23246528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
23259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
232727f02ce8SMatthew G. Knepley }
232827f02ce8SMatthew G. Knepley 
2329194d53e6SMatthew G. Knepley /*@C
2330194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2331194d53e6SMatthew G. Knepley 
2332194d53e6SMatthew G. Knepley   Not collective
2333194d53e6SMatthew G. Knepley 
2334194d53e6SMatthew G. Knepley   Input Parameters:
2335dce8aebaSBarry Smith + ds - The `PetscDS`
2336194d53e6SMatthew G. Knepley . f  - The test field number
2337194d53e6SMatthew G. Knepley - g  - The field number
2338194d53e6SMatthew G. Knepley 
2339194d53e6SMatthew G. Knepley   Output Parameters:
2340194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2341194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2342194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2343194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2344194d53e6SMatthew G. Knepley 
2345dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2346dce8aebaSBarry Smith .vb
2347dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2348dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2349dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2350dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2351dce8aebaSBarry Smith .ve
2352194d53e6SMatthew G. Knepley + dim - the spatial dimension
2353194d53e6SMatthew G. Knepley . Nf - the number of fields
2354194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2355194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2356194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2357194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2358194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2359194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2360194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2361194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2362194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2363194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2364194d53e6SMatthew G. Knepley . t - current time
23652aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2366194d53e6SMatthew G. Knepley . x - coordinates of the current point
2367194d53e6SMatthew G. Knepley . n - normal at the current point
236897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
236997b6e6e8SMatthew G. Knepley . constants - constant parameters
2370194d53e6SMatthew G. Knepley - g0 - output values at the current point
2371194d53e6SMatthew G. Knepley 
2372194d53e6SMatthew G. Knepley   Level: intermediate
2373194d53e6SMatthew G. Knepley 
2374dce8aebaSBarry Smith   Note:
2375dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2376dce8aebaSBarry 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
2377dce8aebaSBarry Smith 
2378dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2379194d53e6SMatthew G. Knepley @*/
2380d71ae5a4SJacob 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[]))
2381d71ae5a4SJacob Faibussowitsch {
23826528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
23836528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
23846528b96dSMatthew G. Knepley 
23852764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23866528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
238763a3b9bcSJacob 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);
238863a3b9bcSJacob 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);
23899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
23906528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
23916528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
23926528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
23936528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
23943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23952764a2aaSMatthew G. Knepley }
23962764a2aaSMatthew G. Knepley 
2397194d53e6SMatthew G. Knepley /*@C
2398194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2399194d53e6SMatthew G. Knepley 
2400194d53e6SMatthew G. Knepley   Not collective
2401194d53e6SMatthew G. Knepley 
2402194d53e6SMatthew G. Knepley   Input Parameters:
24036528b96dSMatthew G. Knepley + ds - The PetscDS
2404194d53e6SMatthew G. Knepley . f  - The test field number
2405194d53e6SMatthew G. Knepley . g  - The field number
2406194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2407194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2408194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2409194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2410194d53e6SMatthew G. Knepley 
2411dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2412dce8aebaSBarry Smith .vb
2413dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2414dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2415dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2416dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2417dce8aebaSBarry Smith .ve
2418194d53e6SMatthew G. Knepley + dim - the spatial dimension
2419194d53e6SMatthew G. Knepley . Nf - the number of fields
2420194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2421194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2422194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2423194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2424194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2425194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2426194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2427194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2428194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2429194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2430194d53e6SMatthew G. Knepley . t - current time
24312aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2432194d53e6SMatthew G. Knepley . x - coordinates of the current point
2433194d53e6SMatthew G. Knepley . n - normal at the current point
243497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
243597b6e6e8SMatthew G. Knepley . constants - constant parameters
2436194d53e6SMatthew G. Knepley - g0 - output values at the current point
2437194d53e6SMatthew G. Knepley 
2438194d53e6SMatthew G. Knepley   Level: intermediate
2439194d53e6SMatthew G. Knepley 
2440dce8aebaSBarry Smith   Note:
2441dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2442dce8aebaSBarry 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
2443dce8aebaSBarry Smith 
2444dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2445194d53e6SMatthew G. Knepley @*/
2446d71ae5a4SJacob 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[]))
2447d71ae5a4SJacob Faibussowitsch {
24482764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24496528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24502764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24512764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24522764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24532764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
245463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
245563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24569566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24582764a2aaSMatthew G. Knepley }
24592764a2aaSMatthew G. Knepley 
246027f02ce8SMatthew G. Knepley /*@
246127f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
246227f02ce8SMatthew G. Knepley 
246327f02ce8SMatthew G. Knepley   Not collective
246427f02ce8SMatthew G. Knepley 
246527f02ce8SMatthew G. Knepley   Input Parameter:
2466dce8aebaSBarry Smith . ds - The `PetscDS`
246727f02ce8SMatthew G. Knepley 
246827f02ce8SMatthew G. Knepley   Output Parameter:
246927f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
247027f02ce8SMatthew G. Knepley 
247127f02ce8SMatthew G. Knepley   Level: intermediate
247227f02ce8SMatthew G. Knepley 
2473dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
247427f02ce8SMatthew G. Knepley @*/
2475d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2476d71ae5a4SJacob Faibussowitsch {
247727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24796528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
24809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
24813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248227f02ce8SMatthew G. Knepley }
248327f02ce8SMatthew G. Knepley 
248427f02ce8SMatthew G. Knepley /*@C
248527f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
248627f02ce8SMatthew G. Knepley 
248727f02ce8SMatthew G. Knepley   Not collective
248827f02ce8SMatthew G. Knepley 
248927f02ce8SMatthew G. Knepley   Input Parameters:
2490dce8aebaSBarry Smith + ds - The `PetscDS`
249127f02ce8SMatthew G. Knepley . f  - The test field number
249227f02ce8SMatthew G. Knepley - g  - The field number
249327f02ce8SMatthew G. Knepley 
249427f02ce8SMatthew G. Knepley   Output Parameters:
249527f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
249627f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
249727f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
249827f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
249927f02ce8SMatthew G. Knepley 
2500dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2501dce8aebaSBarry Smith .vb
2502dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2503dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2504dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2505dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2506dce8aebaSBarry Smith .ve
250727f02ce8SMatthew G. Knepley + dim - the spatial dimension
250827f02ce8SMatthew G. Knepley . Nf - the number of fields
250927f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
251027f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
251127f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
251227f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
251327f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
251427f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
251527f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
251627f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
251727f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
251827f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
251927f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
252027f02ce8SMatthew G. Knepley . t - current time
252127f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
252227f02ce8SMatthew G. Knepley . x - coordinates of the current point
252327f02ce8SMatthew G. Knepley . n - normal at the current point
252427f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
252527f02ce8SMatthew G. Knepley . constants - constant parameters
252627f02ce8SMatthew G. Knepley - g0 - output values at the current point
252727f02ce8SMatthew G. Knepley 
252827f02ce8SMatthew G. Knepley   Level: intermediate
252927f02ce8SMatthew G. Knepley 
2530dce8aebaSBarry Smith   Note:
2531dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2532dce8aebaSBarry 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
2533dce8aebaSBarry Smith 
2534dce8aebaSBarry Smith   Fortran Note:
2535dce8aebaSBarry Smith   This is not yet available in Fortran.
2536dce8aebaSBarry Smith 
2537dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
253827f02ce8SMatthew G. Knepley @*/
2539d71ae5a4SJacob 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[]))
2540d71ae5a4SJacob Faibussowitsch {
25416528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25426528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25436528b96dSMatthew G. Knepley 
254427f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25456528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
254663a3b9bcSJacob 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);
254763a3b9bcSJacob 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);
25489566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25496528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25506528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25516528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25526528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
255427f02ce8SMatthew G. Knepley }
255527f02ce8SMatthew G. Knepley 
255627f02ce8SMatthew G. Knepley /*@C
255727f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
255827f02ce8SMatthew G. Knepley 
255927f02ce8SMatthew G. Knepley   Not collective
256027f02ce8SMatthew G. Knepley 
256127f02ce8SMatthew G. Knepley   Input Parameters:
2562dce8aebaSBarry Smith + ds - The `PetscDS`
256327f02ce8SMatthew G. Knepley . f  - The test field number
256427f02ce8SMatthew G. Knepley . g  - The field number
256527f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
256627f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
256727f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
256827f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
256927f02ce8SMatthew G. Knepley 
2570dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2571dce8aebaSBarry Smith .vb
2572dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2573dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2574dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2575dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2576dce8aebaSBarry Smith .ve
257727f02ce8SMatthew G. Knepley + dim - the spatial dimension
257827f02ce8SMatthew G. Knepley . Nf - the number of fields
257927f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
258027f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
258127f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
258227f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
258327f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
258427f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
258527f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
258627f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
258727f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
258827f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
258927f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
259027f02ce8SMatthew G. Knepley . t - current time
259127f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
259227f02ce8SMatthew G. Knepley . x - coordinates of the current point
259327f02ce8SMatthew G. Knepley . n - normal at the current point
259427f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
259527f02ce8SMatthew G. Knepley . constants - constant parameters
259627f02ce8SMatthew G. Knepley - g0 - output values at the current point
259727f02ce8SMatthew G. Knepley 
259827f02ce8SMatthew G. Knepley   Level: intermediate
259927f02ce8SMatthew G. Knepley 
2600dce8aebaSBarry Smith   Note:
2601dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2602dce8aebaSBarry 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
2603dce8aebaSBarry Smith 
2604dce8aebaSBarry Smith   Fortran Note:
2605dce8aebaSBarry Smith   This is not yet available in Fortran.
2606dce8aebaSBarry Smith 
2607dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
260827f02ce8SMatthew G. Knepley @*/
2609d71ae5a4SJacob 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[]))
2610d71ae5a4SJacob Faibussowitsch {
261127f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26126528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
261327f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
261427f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
261527f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
261627f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
261763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
261863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26199566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262127f02ce8SMatthew G. Knepley }
262227f02ce8SMatthew G. Knepley 
26230d3e9b51SMatthew G. Knepley /*@C
2624c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2625c371a6d1SMatthew G. Knepley 
2626c371a6d1SMatthew G. Knepley   Not collective
2627c371a6d1SMatthew G. Knepley 
2628c371a6d1SMatthew G. Knepley   Input Parameters:
2629c371a6d1SMatthew G. Knepley + prob - The PetscDS
2630c371a6d1SMatthew G. Knepley - f    - The test field number
2631c371a6d1SMatthew G. Knepley 
2632d8d19677SJose E. Roman   Output Parameters:
263395cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
263495cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2635c371a6d1SMatthew G. Knepley 
2636dce8aebaSBarry Smith   Calling sequence for the solution functions:
2637dce8aebaSBarry Smith .vb
2638dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2639dce8aebaSBarry Smith .ve
2640c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2641c371a6d1SMatthew G. Knepley . t - current time
2642c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2643c371a6d1SMatthew G. Knepley . Nc - the number of field components
2644c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2645c371a6d1SMatthew G. Knepley - ctx - a user context
2646c371a6d1SMatthew G. Knepley 
2647c371a6d1SMatthew G. Knepley   Level: intermediate
2648c371a6d1SMatthew G. Knepley 
2649dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2650c371a6d1SMatthew G. Knepley @*/
2651d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2652d71ae5a4SJacob Faibussowitsch {
2653c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2654c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
265563a3b9bcSJacob 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);
26569371c9d4SSatish Balay   if (sol) {
26579371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26589371c9d4SSatish Balay     *sol = prob->exactSol[f];
26599371c9d4SSatish Balay   }
26609371c9d4SSatish Balay   if (ctx) {
26619371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26629371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26639371c9d4SSatish Balay   }
26643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2665c371a6d1SMatthew G. Knepley }
2666c371a6d1SMatthew G. Knepley 
2667c371a6d1SMatthew G. Knepley /*@C
2668578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2669c371a6d1SMatthew G. Knepley 
2670c371a6d1SMatthew G. Knepley   Not collective
2671c371a6d1SMatthew G. Knepley 
2672c371a6d1SMatthew G. Knepley   Input Parameters:
2673dce8aebaSBarry Smith + prob - The `PetscDS`
2674c371a6d1SMatthew G. Knepley . f    - The test field number
267595cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
267695cbbfd3SMatthew G. Knepley - ctx  - solution context or NULL
2677c371a6d1SMatthew G. Knepley 
2678dce8aebaSBarry Smith   Calling sequence for solution functions:
2679dce8aebaSBarry Smith .vb
2680dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2681dce8aebaSBarry Smith .ve
2682c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2683c371a6d1SMatthew G. Knepley . t - current time
2684c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2685c371a6d1SMatthew G. Knepley . Nc - the number of field components
2686c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2687c371a6d1SMatthew G. Knepley - ctx - a user context
2688c371a6d1SMatthew G. Knepley 
2689c371a6d1SMatthew G. Knepley   Level: intermediate
2690c371a6d1SMatthew G. Knepley 
2691dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2692c371a6d1SMatthew G. Knepley @*/
2693d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2694d71ae5a4SJacob Faibussowitsch {
2695c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2696c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
269763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
26989566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
26999371c9d4SSatish Balay   if (sol) {
27009371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27019371c9d4SSatish Balay     prob->exactSol[f] = sol;
27029371c9d4SSatish Balay   }
27039371c9d4SSatish Balay   if (ctx) {
27049371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27059371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27069371c9d4SSatish Balay   }
27073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2708c371a6d1SMatthew G. Knepley }
2709c371a6d1SMatthew G. Knepley 
27105638fd0eSMatthew G. Knepley /*@C
2711f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2712f2cacb80SMatthew G. Knepley 
2713f2cacb80SMatthew G. Knepley   Not collective
2714f2cacb80SMatthew G. Knepley 
2715f2cacb80SMatthew G. Knepley   Input Parameters:
2716dce8aebaSBarry Smith + prob - The `PetscDS`
2717f2cacb80SMatthew G. Knepley - f    - The test field number
2718f2cacb80SMatthew G. Knepley 
2719d8d19677SJose E. Roman   Output Parameters:
2720f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2721f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2722f2cacb80SMatthew G. Knepley 
2723dce8aebaSBarry Smith   Calling sequence for the solution functions:
2724dce8aebaSBarry Smith .vb
2725dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2726dce8aebaSBarry Smith .ve
2727f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2728f2cacb80SMatthew G. Knepley . t - current time
2729f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2730f2cacb80SMatthew G. Knepley . Nc - the number of field components
2731f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2732f2cacb80SMatthew G. Knepley - ctx - a user context
2733f2cacb80SMatthew G. Knepley 
2734f2cacb80SMatthew G. Knepley   Level: intermediate
2735f2cacb80SMatthew G. Knepley 
2736dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2737f2cacb80SMatthew G. Knepley @*/
2738d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2739d71ae5a4SJacob Faibussowitsch {
2740f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2741f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
274263a3b9bcSJacob 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);
27439371c9d4SSatish Balay   if (sol) {
27449371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27459371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27469371c9d4SSatish Balay   }
27479371c9d4SSatish Balay   if (ctx) {
27489371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27499371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27509371c9d4SSatish Balay   }
27513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2752f2cacb80SMatthew G. Knepley }
2753f2cacb80SMatthew G. Knepley 
2754f2cacb80SMatthew G. Knepley /*@C
2755f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2756f2cacb80SMatthew G. Knepley 
2757f2cacb80SMatthew G. Knepley   Not collective
2758f2cacb80SMatthew G. Knepley 
2759f2cacb80SMatthew G. Knepley   Input Parameters:
2760dce8aebaSBarry Smith + prob - The `PetscDS`
2761f2cacb80SMatthew G. Knepley . f    - The test field number
2762f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
2763f2cacb80SMatthew G. Knepley - ctx  - time derivative of the solution context or NULL
2764f2cacb80SMatthew G. Knepley 
2765dce8aebaSBarry Smith   Calling sequence for solution functions:
2766dce8aebaSBarry Smith .vb
2767dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2768dce8aebaSBarry Smith .ve
2769f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2770f2cacb80SMatthew G. Knepley . t - current time
2771f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2772f2cacb80SMatthew G. Knepley . Nc - the number of field components
2773f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2774f2cacb80SMatthew G. Knepley - ctx - a user context
2775f2cacb80SMatthew G. Knepley 
2776f2cacb80SMatthew G. Knepley   Level: intermediate
2777f2cacb80SMatthew G. Knepley 
2778dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2779f2cacb80SMatthew G. Knepley @*/
2780d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2781d71ae5a4SJacob Faibussowitsch {
2782f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2783f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
278463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27859566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27869371c9d4SSatish Balay   if (sol) {
27879371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27889371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
27899371c9d4SSatish Balay   }
27909371c9d4SSatish Balay   if (ctx) {
27919371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27929371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
27939371c9d4SSatish Balay   }
27943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2795f2cacb80SMatthew G. Knepley }
2796f2cacb80SMatthew G. Knepley 
2797f2cacb80SMatthew G. Knepley /*@C
279897b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
279997b6e6e8SMatthew G. Knepley 
280097b6e6e8SMatthew G. Knepley   Not collective
280197b6e6e8SMatthew G. Knepley 
280297b6e6e8SMatthew G. Knepley   Input Parameter:
2803dce8aebaSBarry Smith . prob - The `PetscDS` object
280497b6e6e8SMatthew G. Knepley 
280597b6e6e8SMatthew G. Knepley   Output Parameters:
280697b6e6e8SMatthew G. Knepley + numConstants - The number of constants
280797b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
280897b6e6e8SMatthew G. Knepley 
280997b6e6e8SMatthew G. Knepley   Level: intermediate
281097b6e6e8SMatthew G. Knepley 
2811dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
281297b6e6e8SMatthew G. Knepley @*/
2813d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2814d71ae5a4SJacob Faibussowitsch {
281597b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
281697b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28179371c9d4SSatish Balay   if (numConstants) {
28189371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
28199371c9d4SSatish Balay     *numConstants = prob->numConstants;
28209371c9d4SSatish Balay   }
28219371c9d4SSatish Balay   if (constants) {
28229371c9d4SSatish Balay     PetscValidPointer(constants, 3);
28239371c9d4SSatish Balay     *constants = prob->constants;
28249371c9d4SSatish Balay   }
28253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
282697b6e6e8SMatthew G. Knepley }
282797b6e6e8SMatthew G. Knepley 
28280d3e9b51SMatthew G. Knepley /*@C
282997b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
283097b6e6e8SMatthew G. Knepley 
283197b6e6e8SMatthew G. Knepley   Not collective
283297b6e6e8SMatthew G. Knepley 
283397b6e6e8SMatthew G. Knepley   Input Parameters:
2834dce8aebaSBarry Smith + prob         - The `PetscDS` object
283597b6e6e8SMatthew G. Knepley . numConstants - The number of constants
283697b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
283797b6e6e8SMatthew G. Knepley 
283897b6e6e8SMatthew G. Knepley   Level: intermediate
283997b6e6e8SMatthew G. Knepley 
2840dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
284197b6e6e8SMatthew G. Knepley @*/
2842d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2843d71ae5a4SJacob Faibussowitsch {
284497b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
284597b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
284697b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28479566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
284897b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
284997b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28509566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
285120be0f5bSMatthew G. Knepley     } else {
285220be0f5bSMatthew G. Knepley       prob->constants = NULL;
285320be0f5bSMatthew G. Knepley     }
285420be0f5bSMatthew G. Knepley   }
285520be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2856dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
28579566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
285897b6e6e8SMatthew G. Knepley   }
28593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286097b6e6e8SMatthew G. Knepley }
286197b6e6e8SMatthew G. Knepley 
28624cd1e086SMatthew G. Knepley /*@
28634cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28644cd1e086SMatthew G. Knepley 
28654cd1e086SMatthew G. Knepley   Not collective
28664cd1e086SMatthew G. Knepley 
28674cd1e086SMatthew G. Knepley   Input Parameters:
2868dce8aebaSBarry Smith + prob - The `PetscDS` object
28694cd1e086SMatthew G. Knepley - disc - The discretization object
28704cd1e086SMatthew G. Knepley 
28714cd1e086SMatthew G. Knepley   Output Parameter:
28724cd1e086SMatthew G. Knepley . f - The field number
28734cd1e086SMatthew G. Knepley 
28744cd1e086SMatthew G. Knepley   Level: beginner
28754cd1e086SMatthew G. Knepley 
2876dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28774cd1e086SMatthew G. Knepley @*/
2878d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2879d71ae5a4SJacob Faibussowitsch {
28804cd1e086SMatthew G. Knepley   PetscInt g;
28814cd1e086SMatthew G. Knepley 
28824cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28834cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2884dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
28854cd1e086SMatthew G. Knepley   *f = -1;
28869371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28879371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
28889371c9d4SSatish Balay   }
288908401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
28904cd1e086SMatthew G. Knepley   *f = g;
28913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28924cd1e086SMatthew G. Knepley }
28934cd1e086SMatthew G. Knepley 
28944cd1e086SMatthew G. Knepley /*@
28954cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
28964cd1e086SMatthew G. Knepley 
28974cd1e086SMatthew G. Knepley   Not collective
28984cd1e086SMatthew G. Knepley 
28994cd1e086SMatthew G. Knepley   Input Parameters:
2900dce8aebaSBarry Smith + prob - The `PetscDS` object
29014cd1e086SMatthew G. Knepley - f - The field number
29024cd1e086SMatthew G. Knepley 
29034cd1e086SMatthew G. Knepley   Output Parameter:
29044cd1e086SMatthew G. Knepley . size - The size
29054cd1e086SMatthew G. Knepley 
29064cd1e086SMatthew G. Knepley   Level: beginner
29074cd1e086SMatthew G. Knepley 
2908dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29094cd1e086SMatthew G. Knepley @*/
2910d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2911d71ae5a4SJacob Faibussowitsch {
29124cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29134cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2914dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
291563a3b9bcSJacob 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);
29169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2917d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29194cd1e086SMatthew G. Knepley }
29204cd1e086SMatthew G. Knepley 
2921bc4ae4beSMatthew G. Knepley /*@
2922bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2923bc4ae4beSMatthew G. Knepley 
2924bc4ae4beSMatthew G. Knepley   Not collective
2925bc4ae4beSMatthew G. Knepley 
2926bc4ae4beSMatthew G. Knepley   Input Parameters:
2927dce8aebaSBarry Smith + prob - The `PetscDS` object
2928bc4ae4beSMatthew G. Knepley - f - The field number
2929bc4ae4beSMatthew G. Knepley 
2930bc4ae4beSMatthew G. Knepley   Output Parameter:
2931bc4ae4beSMatthew G. Knepley . off - The offset
2932bc4ae4beSMatthew G. Knepley 
2933bc4ae4beSMatthew G. Knepley   Level: beginner
2934bc4ae4beSMatthew G. Knepley 
2935dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2936bc4ae4beSMatthew G. Knepley @*/
2937d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2938d71ae5a4SJacob Faibussowitsch {
29394cd1e086SMatthew G. Knepley   PetscInt size, g;
29402764a2aaSMatthew G. Knepley 
29412764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29422764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2943dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
294463a3b9bcSJacob 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);
29452764a2aaSMatthew G. Knepley   *off = 0;
29462764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29479566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29484cd1e086SMatthew G. Knepley     *off += size;
29492764a2aaSMatthew G. Knepley   }
29503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29512764a2aaSMatthew G. Knepley }
29522764a2aaSMatthew G. Knepley 
2953bc4ae4beSMatthew G. Knepley /*@
29545fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29555fedec97SMatthew G. Knepley 
29565fedec97SMatthew G. Knepley   Not collective
29575fedec97SMatthew G. Knepley 
29585fedec97SMatthew G. Knepley   Input Parameters:
2959dce8aebaSBarry Smith + prob - The `PetscDS` object
29605fedec97SMatthew G. Knepley - f - The field number
29615fedec97SMatthew G. Knepley 
29625fedec97SMatthew G. Knepley   Output Parameter:
29635fedec97SMatthew G. Knepley . off - The offset
29645fedec97SMatthew G. Knepley 
29655fedec97SMatthew G. Knepley   Level: beginner
29665fedec97SMatthew G. Knepley 
2967dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29685fedec97SMatthew G. Knepley @*/
2969d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2970d71ae5a4SJacob Faibussowitsch {
29715fedec97SMatthew G. Knepley   PetscInt size, g;
29725fedec97SMatthew G. Knepley 
29735fedec97SMatthew G. Knepley   PetscFunctionBegin;
29745fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2975dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
297663a3b9bcSJacob 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);
29775fedec97SMatthew G. Knepley   *off = 0;
29785fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29795fedec97SMatthew G. Knepley     PetscBool cohesive;
29805fedec97SMatthew G. Knepley 
29819566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29829566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29835fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29845fedec97SMatthew G. Knepley   }
29853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29865fedec97SMatthew G. Knepley }
29875fedec97SMatthew G. Knepley 
29885fedec97SMatthew G. Knepley /*@
298947e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2990bc4ae4beSMatthew G. Knepley 
2991bc4ae4beSMatthew G. Knepley   Not collective
2992bc4ae4beSMatthew G. Knepley 
299347e57110SSander Arens   Input Parameter:
2994dce8aebaSBarry Smith . prob - The `PetscDS` object
2995bc4ae4beSMatthew G. Knepley 
2996bc4ae4beSMatthew G. Knepley   Output Parameter:
299747e57110SSander Arens . dimensions - The number of dimensions
2998bc4ae4beSMatthew G. Knepley 
2999bc4ae4beSMatthew G. Knepley   Level: beginner
3000bc4ae4beSMatthew G. Knepley 
3001dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3002bc4ae4beSMatthew G. Knepley @*/
3003d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3004d71ae5a4SJacob Faibussowitsch {
30052764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30062764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30079566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
300847e57110SSander Arens   PetscValidPointer(dimensions, 2);
300947e57110SSander Arens   *dimensions = prob->Nb;
30103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30116ce16762SMatthew G. Knepley }
301247e57110SSander Arens 
301347e57110SSander Arens /*@
301447e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
301547e57110SSander Arens 
301647e57110SSander Arens   Not collective
301747e57110SSander Arens 
301847e57110SSander Arens   Input Parameter:
3019dce8aebaSBarry Smith . prob - The `PetscDS` object
302047e57110SSander Arens 
302147e57110SSander Arens   Output Parameter:
302247e57110SSander Arens . components - The number of components
302347e57110SSander Arens 
302447e57110SSander Arens   Level: beginner
302547e57110SSander Arens 
3026dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
302747e57110SSander Arens @*/
3028d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3029d71ae5a4SJacob Faibussowitsch {
303047e57110SSander Arens   PetscFunctionBegin;
303147e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30329566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
303347e57110SSander Arens   PetscValidPointer(components, 2);
303447e57110SSander Arens   *components = prob->Nc;
30353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30366ce16762SMatthew G. Knepley }
30376ce16762SMatthew G. Knepley 
30386ce16762SMatthew G. Knepley /*@
30396ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30406ce16762SMatthew G. Knepley 
30416ce16762SMatthew G. Knepley   Not collective
30426ce16762SMatthew G. Knepley 
30436ce16762SMatthew G. Knepley   Input Parameters:
3044dce8aebaSBarry Smith + prob - The `PetscDS` object
30456ce16762SMatthew G. Knepley - f - The field number
30466ce16762SMatthew G. Knepley 
30476ce16762SMatthew G. Knepley   Output Parameter:
30486ce16762SMatthew G. Knepley . off - The offset
30496ce16762SMatthew G. Knepley 
30506ce16762SMatthew G. Knepley   Level: beginner
30516ce16762SMatthew G. Knepley 
3052dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30536ce16762SMatthew G. Knepley @*/
3054d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3055d71ae5a4SJacob Faibussowitsch {
30566ce16762SMatthew G. Knepley   PetscFunctionBegin;
30576ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3058dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
305963a3b9bcSJacob 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);
30609566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
306147e57110SSander Arens   *off = prob->off[f];
30623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30632764a2aaSMatthew G. Knepley }
30642764a2aaSMatthew G. Knepley 
3065194d53e6SMatthew G. Knepley /*@
3066194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3067194d53e6SMatthew G. Knepley 
3068194d53e6SMatthew G. Knepley   Not collective
3069194d53e6SMatthew G. Knepley 
3070194d53e6SMatthew G. Knepley   Input Parameter:
3071dce8aebaSBarry Smith . prob - The `PetscDS` object
3072194d53e6SMatthew G. Knepley 
3073194d53e6SMatthew G. Knepley   Output Parameter:
3074194d53e6SMatthew G. Knepley . offsets - The offsets
3075194d53e6SMatthew G. Knepley 
3076194d53e6SMatthew G. Knepley   Level: beginner
3077194d53e6SMatthew G. Knepley 
3078dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3079194d53e6SMatthew G. Knepley @*/
3080d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3081d71ae5a4SJacob Faibussowitsch {
3082194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3083194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3084194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30859566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3086194d53e6SMatthew G. Knepley   *offsets = prob->off;
30873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3088194d53e6SMatthew G. Knepley }
3089194d53e6SMatthew G. Knepley 
3090194d53e6SMatthew G. Knepley /*@
3091194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3092194d53e6SMatthew G. Knepley 
3093194d53e6SMatthew G. Knepley   Not collective
3094194d53e6SMatthew G. Knepley 
3095194d53e6SMatthew G. Knepley   Input Parameter:
3096dce8aebaSBarry Smith . prob - The `PetscDS` object
3097194d53e6SMatthew G. Knepley 
3098194d53e6SMatthew G. Knepley   Output Parameter:
3099194d53e6SMatthew G. Knepley . offsets - The offsets
3100194d53e6SMatthew G. Knepley 
3101194d53e6SMatthew G. Knepley   Level: beginner
3102194d53e6SMatthew G. Knepley 
3103dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3104194d53e6SMatthew G. Knepley @*/
3105d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3106d71ae5a4SJacob Faibussowitsch {
3107194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3108194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3109194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
31109566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3111194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3113194d53e6SMatthew G. Knepley }
3114194d53e6SMatthew G. Knepley 
31159ee2af8cSMatthew G. Knepley /*@
31169ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31179ee2af8cSMatthew G. Knepley 
31189ee2af8cSMatthew G. Knepley   Not collective
31199ee2af8cSMatthew G. Knepley 
31209ee2af8cSMatthew G. Knepley   Input Parameters:
3121dce8aebaSBarry Smith + ds - The `PetscDS` object
31229ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31239ee2af8cSMatthew G. Knepley 
31249ee2af8cSMatthew G. Knepley   Output Parameter:
31259ee2af8cSMatthew G. Knepley . offsets - The offsets
31269ee2af8cSMatthew G. Knepley 
31279ee2af8cSMatthew G. Knepley   Level: beginner
31289ee2af8cSMatthew G. Knepley 
3129dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31309ee2af8cSMatthew G. Knepley @*/
3131d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3132d71ae5a4SJacob Faibussowitsch {
31339ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31349ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31359ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
313628b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
313763a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31399ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31419ee2af8cSMatthew G. Knepley }
31429ee2af8cSMatthew G. Knepley 
31439ee2af8cSMatthew G. Knepley /*@
31449ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31459ee2af8cSMatthew G. Knepley 
31469ee2af8cSMatthew G. Knepley   Not collective
31479ee2af8cSMatthew G. Knepley 
31489ee2af8cSMatthew G. Knepley   Input Parameters:
3149dce8aebaSBarry Smith + ds - The `PetscDS` object
31509ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31519ee2af8cSMatthew G. Knepley 
31529ee2af8cSMatthew G. Knepley   Output Parameter:
31539ee2af8cSMatthew G. Knepley . offsets - The offsets
31549ee2af8cSMatthew G. Knepley 
31559ee2af8cSMatthew G. Knepley   Level: beginner
31569ee2af8cSMatthew G. Knepley 
3157dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31589ee2af8cSMatthew G. Knepley @*/
3159d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3160d71ae5a4SJacob Faibussowitsch {
31619ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31629ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31639ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
316428b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
316563a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31669566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31679ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31699ee2af8cSMatthew G. Knepley }
31709ee2af8cSMatthew G. Knepley 
317168c9edb9SMatthew G. Knepley /*@C
317268c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
317368c9edb9SMatthew G. Knepley 
317468c9edb9SMatthew G. Knepley   Not collective
317568c9edb9SMatthew G. Knepley 
317668c9edb9SMatthew G. Knepley   Input Parameter:
3177dce8aebaSBarry Smith . prob - The `PetscDS` object
317868c9edb9SMatthew G. Knepley 
3179ef0bb6c7SMatthew G. Knepley   Output Parameter:
3180ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
318168c9edb9SMatthew G. Knepley 
318268c9edb9SMatthew G. Knepley   Level: intermediate
318368c9edb9SMatthew G. Knepley 
3184dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
318568c9edb9SMatthew G. Knepley @*/
3186d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3187d71ae5a4SJacob Faibussowitsch {
31882764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31892764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3190ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
31919566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3192ef0bb6c7SMatthew G. Knepley   *T = prob->T;
31933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31942764a2aaSMatthew G. Knepley }
31952764a2aaSMatthew G. Knepley 
319668c9edb9SMatthew G. Knepley /*@C
31974d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
319868c9edb9SMatthew G. Knepley 
319968c9edb9SMatthew G. Knepley   Not collective
320068c9edb9SMatthew G. Knepley 
320168c9edb9SMatthew G. Knepley   Input Parameter:
3202dce8aebaSBarry Smith . prob - The `PetscDS` object
320368c9edb9SMatthew G. Knepley 
3204ef0bb6c7SMatthew G. Knepley   Output Parameter:
3205a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
320668c9edb9SMatthew G. Knepley 
320768c9edb9SMatthew G. Knepley   Level: intermediate
320868c9edb9SMatthew G. Knepley 
3209dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
321068c9edb9SMatthew G. Knepley @*/
3211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3212d71ae5a4SJacob Faibussowitsch {
32132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32142764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3215ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
32169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3217ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32192764a2aaSMatthew G. Knepley }
32202764a2aaSMatthew G. Knepley 
3221d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3222d71ae5a4SJacob Faibussowitsch {
32232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32242764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32259566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32269371c9d4SSatish Balay   if (u) {
32279371c9d4SSatish Balay     PetscValidPointer(u, 2);
32289371c9d4SSatish Balay     *u = prob->u;
32299371c9d4SSatish Balay   }
32309371c9d4SSatish Balay   if (u_t) {
32319371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
32329371c9d4SSatish Balay     *u_t = prob->u_t;
32339371c9d4SSatish Balay   }
32349371c9d4SSatish Balay   if (u_x) {
32359371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
32369371c9d4SSatish Balay     *u_x = prob->u_x;
32379371c9d4SSatish Balay   }
32383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32392764a2aaSMatthew G. Knepley }
32402764a2aaSMatthew G. Knepley 
3241d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3242d71ae5a4SJacob Faibussowitsch {
32432764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32442764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32459566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32469371c9d4SSatish Balay   if (f0) {
32479371c9d4SSatish Balay     PetscValidPointer(f0, 2);
32489371c9d4SSatish Balay     *f0 = prob->f0;
32499371c9d4SSatish Balay   }
32509371c9d4SSatish Balay   if (f1) {
32519371c9d4SSatish Balay     PetscValidPointer(f1, 3);
32529371c9d4SSatish Balay     *f1 = prob->f1;
32539371c9d4SSatish Balay   }
32549371c9d4SSatish Balay   if (g0) {
32559371c9d4SSatish Balay     PetscValidPointer(g0, 4);
32569371c9d4SSatish Balay     *g0 = prob->g0;
32579371c9d4SSatish Balay   }
32589371c9d4SSatish Balay   if (g1) {
32599371c9d4SSatish Balay     PetscValidPointer(g1, 5);
32609371c9d4SSatish Balay     *g1 = prob->g1;
32619371c9d4SSatish Balay   }
32629371c9d4SSatish Balay   if (g2) {
32639371c9d4SSatish Balay     PetscValidPointer(g2, 6);
32649371c9d4SSatish Balay     *g2 = prob->g2;
32659371c9d4SSatish Balay   }
32669371c9d4SSatish Balay   if (g3) {
32679371c9d4SSatish Balay     PetscValidPointer(g3, 7);
32689371c9d4SSatish Balay     *g3 = prob->g3;
32699371c9d4SSatish Balay   }
32703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32712764a2aaSMatthew G. Knepley }
32722764a2aaSMatthew G. Knepley 
3273d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3274d71ae5a4SJacob Faibussowitsch {
32752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32762764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32779566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32789371c9d4SSatish Balay   if (x) {
32799371c9d4SSatish Balay     PetscValidPointer(x, 2);
32809371c9d4SSatish Balay     *x = prob->x;
32819371c9d4SSatish Balay   }
32829371c9d4SSatish Balay   if (basisReal) {
32839371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
32849371c9d4SSatish Balay     *basisReal = prob->basisReal;
32859371c9d4SSatish Balay   }
32869371c9d4SSatish Balay   if (basisDerReal) {
32879371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
32889371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
32899371c9d4SSatish Balay   }
32909371c9d4SSatish Balay   if (testReal) {
32919371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
32929371c9d4SSatish Balay     *testReal = prob->testReal;
32939371c9d4SSatish Balay   }
32949371c9d4SSatish Balay   if (testDerReal) {
32959371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
32969371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
32979371c9d4SSatish Balay   }
32983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32992764a2aaSMatthew G. Knepley }
33002764a2aaSMatthew G. Knepley 
330158ebd649SToby Isaac /*@C
3302dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3303dce8aebaSBarry 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
3304dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
330558ebd649SToby Isaac 
3306783e2ec8SMatthew G. Knepley   Collective on ds
3307783e2ec8SMatthew G. Knepley 
330858ebd649SToby Isaac   Input Parameters:
330958ebd649SToby Isaac + ds       - The PetscDS object
3310dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
331158ebd649SToby Isaac . name     - The BC name
331245480ffeSMatthew G. Knepley . label    - The label defining constrained points
3313dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
331445480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
331558ebd649SToby Isaac . field    - The field to constrain
331645480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
331758ebd649SToby Isaac . comps    - An array of constrained component numbers
331858ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3319a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
332058ebd649SToby Isaac - ctx      - An optional user context for bcFunc
332158ebd649SToby Isaac 
332245480ffeSMatthew G. Knepley   Output Parameters:
332345480ffeSMatthew G. Knepley - bd       - The boundary number
332445480ffeSMatthew G. Knepley 
332558ebd649SToby Isaac   Options Database Keys:
332658ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
332758ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
332858ebd649SToby Isaac 
3329dce8aebaSBarry Smith   Level: developer
3330dce8aebaSBarry Smith 
333156cf3b9cSMatthew G. Knepley   Note:
3332dce8aebaSBarry 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:
333356cf3b9cSMatthew G. Knepley 
333456cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
333556cf3b9cSMatthew G. Knepley 
3336dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3337dce8aebaSBarry Smith .vb
3338dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3339dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3340dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3341dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3342dce8aebaSBarry Smith .ve
334356cf3b9cSMatthew G. Knepley + dim - the spatial dimension
334456cf3b9cSMatthew G. Knepley . Nf - the number of fields
334556cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
334656cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
334756cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
334856cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
334956cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
335056cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
335156cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
335256cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
335356cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
335456cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
335556cf3b9cSMatthew G. Knepley . t - current time
335656cf3b9cSMatthew G. Knepley . x - coordinates of the current point
335756cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
335856cf3b9cSMatthew G. Knepley . constants - constant parameters
335956cf3b9cSMatthew G. Knepley - bcval - output values at the current point
336056cf3b9cSMatthew G. Knepley 
3361dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
336258ebd649SToby Isaac @*/
3363d71ae5a4SJacob 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)
3364d71ae5a4SJacob Faibussowitsch {
336545480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
336645480ffeSMatthew G. Knepley   PetscInt    n    = 0;
336745480ffeSMatthew G. Knepley   const char *lname;
336858ebd649SToby Isaac 
336958ebd649SToby Isaac   PetscFunctionBegin;
337058ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3371783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
337245480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
337345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
337445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
337545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
337645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3377dce9da9cSMatthew 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);
3378d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3379d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3380d57bb9dbSMatthew G. Knepley     PetscInt  c;
3381d57bb9dbSMatthew G. Knepley 
33829566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
338363a3b9bcSJacob 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);
3384d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
33851dca8a05SBarry 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);
3386d57bb9dbSMatthew G. Knepley     }
3387d57bb9dbSMatthew G. Knepley   }
33889566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33899566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33919566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33929566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33939566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
33949566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
33959566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
33969566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
33979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3398f971fd6bSMatthew G. Knepley   b->type   = type;
339945480ffeSMatthew G. Knepley   b->label  = label;
340045480ffeSMatthew G. Knepley   b->Nv     = Nv;
340158ebd649SToby Isaac   b->field  = field;
340245480ffeSMatthew G. Knepley   b->Nc     = Nc;
340358ebd649SToby Isaac   b->func   = bcFunc;
340456cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
340558ebd649SToby Isaac   b->ctx    = ctx;
340645480ffeSMatthew G. Knepley   b->next   = NULL;
340745480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
340845480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
340945480ffeSMatthew G. Knepley   while (head) {
341045480ffeSMatthew G. Knepley     if (!head->next) {
341145480ffeSMatthew G. Knepley       head->next = b;
341245480ffeSMatthew G. Knepley       head       = b;
341345480ffeSMatthew G. Knepley     }
341445480ffeSMatthew G. Knepley     head = head->next;
341545480ffeSMatthew G. Knepley     ++n;
341645480ffeSMatthew G. Knepley   }
34179371c9d4SSatish Balay   if (bd) {
34189371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34199371c9d4SSatish Balay     *bd = n;
34209371c9d4SSatish Balay   }
34213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
342245480ffeSMatthew G. Knepley }
342345480ffeSMatthew G. Knepley 
342445480ffeSMatthew G. Knepley /*@C
3425dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3426dce8aebaSBarry 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
3427dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
342845480ffeSMatthew G. Knepley 
342945480ffeSMatthew G. Knepley   Collective on ds
343045480ffeSMatthew G. Knepley 
343145480ffeSMatthew G. Knepley   Input Parameters:
3432dce8aebaSBarry Smith + ds       - The `PetscDS` object
3433dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
343445480ffeSMatthew G. Knepley . name     - The BC name
343545480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3436dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
343745480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
343845480ffeSMatthew G. Knepley . field    - The field to constrain
343945480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
344045480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
344145480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3442a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
344345480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
344445480ffeSMatthew G. Knepley 
344545480ffeSMatthew G. Knepley   Output Parameters:
344645480ffeSMatthew G. Knepley - bd       - The boundary number
344745480ffeSMatthew G. Knepley 
344845480ffeSMatthew G. Knepley   Options Database Keys:
344945480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
345045480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
345145480ffeSMatthew G. Knepley 
3452dce8aebaSBarry Smith   Calling Sequence of bcFunc() and bcFunc_t():
3453dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3454dce8aebaSBarry Smith .vb
3455dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3456dce8aebaSBarry Smith .ve
3457dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3458dce8aebaSBarry Smith .vb
3459dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3460dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3461dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3462dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3463dce8aebaSBarry Smith .ve
346445480ffeSMatthew G. Knepley + dim - the spatial dimension
346545480ffeSMatthew G. Knepley . Nf - the number of fields
346645480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
346745480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
346845480ffeSMatthew G. Knepley . u - each field evaluated at the current point
346945480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
347045480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
347145480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
347245480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
347345480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
347445480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
347545480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
347645480ffeSMatthew G. Knepley . t - current time
347745480ffeSMatthew G. Knepley . x - coordinates of the current point
347845480ffeSMatthew G. Knepley . numConstants - number of constant parameters
347945480ffeSMatthew G. Knepley . constants - constant parameters
348045480ffeSMatthew G. Knepley - bcval - output values at the current point
348145480ffeSMatthew G. Knepley 
348245480ffeSMatthew G. Knepley   Level: developer
348345480ffeSMatthew G. Knepley 
3484dce8aebaSBarry Smith   Note:
3485dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3486dce8aebaSBarry Smith 
3487dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
348845480ffeSMatthew G. Knepley @*/
3489d71ae5a4SJacob 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)
3490d71ae5a4SJacob Faibussowitsch {
349145480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
349245480ffeSMatthew G. Knepley   PetscInt   n    = 0;
349345480ffeSMatthew G. Knepley 
349445480ffeSMatthew G. Knepley   PetscFunctionBegin;
349545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
349645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
349745480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
349845480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
349945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
350045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
350145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35029566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35039566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35049566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35059566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35069566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35079566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35089566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35099566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35109566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
351145480ffeSMatthew G. Knepley   b->type   = type;
351245480ffeSMatthew G. Knepley   b->label  = NULL;
351345480ffeSMatthew G. Knepley   b->Nv     = Nv;
351445480ffeSMatthew G. Knepley   b->field  = field;
351545480ffeSMatthew G. Knepley   b->Nc     = Nc;
351645480ffeSMatthew G. Knepley   b->func   = bcFunc;
351745480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
351845480ffeSMatthew G. Knepley   b->ctx    = ctx;
351945480ffeSMatthew G. Knepley   b->next   = NULL;
352045480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
352145480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
352245480ffeSMatthew G. Knepley   while (head) {
352345480ffeSMatthew G. Knepley     if (!head->next) {
352445480ffeSMatthew G. Knepley       head->next = b;
352545480ffeSMatthew G. Knepley       head       = b;
352645480ffeSMatthew G. Knepley     }
352745480ffeSMatthew G. Knepley     head = head->next;
352845480ffeSMatthew G. Knepley     ++n;
352945480ffeSMatthew G. Knepley   }
35309371c9d4SSatish Balay   if (bd) {
35319371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35329371c9d4SSatish Balay     *bd = n;
35339371c9d4SSatish Balay   }
35343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
353558ebd649SToby Isaac }
353658ebd649SToby Isaac 
3537b67eacb3SMatthew G. Knepley /*@C
3538dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3539dce8aebaSBarry 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
3540dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3541b67eacb3SMatthew G. Knepley 
3542b67eacb3SMatthew G. Knepley   Input Parameters:
3543dce8aebaSBarry Smith + ds       - The `PetscDS` object
3544b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3545dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3546b67eacb3SMatthew G. Knepley . name     - The BC name
354745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3548dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
354945480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3550b67eacb3SMatthew G. Knepley . field    - The field to constrain
355145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3552b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3553b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3554a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3555b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3556b67eacb3SMatthew G. Knepley 
3557b67eacb3SMatthew G. Knepley   Level: developer
3558b67eacb3SMatthew G. Knepley 
3559dce8aebaSBarry Smith   Note:
3560dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3561dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3562dce8aebaSBarry Smith 
3563dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3564b67eacb3SMatthew G. Knepley @*/
3565d71ae5a4SJacob 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)
3566d71ae5a4SJacob Faibussowitsch {
3567b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3568b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3569b67eacb3SMatthew G. Knepley 
3570b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3571b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3572b67eacb3SMatthew G. Knepley   while (b) {
3573b67eacb3SMatthew G. Knepley     if (n == bd) break;
3574b67eacb3SMatthew G. Knepley     b = b->next;
3575b67eacb3SMatthew G. Knepley     ++n;
3576b67eacb3SMatthew G. Knepley   }
357763a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3578b67eacb3SMatthew G. Knepley   if (name) {
35799566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
35809566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3581b67eacb3SMatthew G. Knepley   }
3582b67eacb3SMatthew G. Knepley   b->type = type;
358345480ffeSMatthew G. Knepley   if (label) {
358445480ffeSMatthew G. Knepley     const char *name;
358545480ffeSMatthew G. Knepley 
358645480ffeSMatthew G. Knepley     b->label = label;
35879566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
35889566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
35899566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
359045480ffeSMatthew G. Knepley   }
359145480ffeSMatthew G. Knepley   if (Nv >= 0) {
359245480ffeSMatthew G. Knepley     b->Nv = Nv;
35939566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
35949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
35959566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
359645480ffeSMatthew G. Knepley   }
359745480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
359845480ffeSMatthew G. Knepley   if (Nc >= 0) {
359945480ffeSMatthew G. Knepley     b->Nc = Nc;
36009566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36019566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36029566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
360345480ffeSMatthew G. Knepley   }
360445480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
360545480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
360645480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3608b67eacb3SMatthew G. Knepley }
3609b67eacb3SMatthew G. Knepley 
361058ebd649SToby Isaac /*@
361158ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
361258ebd649SToby Isaac 
361358ebd649SToby Isaac   Input Parameters:
3614dce8aebaSBarry Smith . ds - The `PetscDS` object
361558ebd649SToby Isaac 
361658ebd649SToby Isaac   Output Parameters:
361758ebd649SToby Isaac . numBd - The number of BC
361858ebd649SToby Isaac 
361958ebd649SToby Isaac   Level: intermediate
362058ebd649SToby Isaac 
3621dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
362258ebd649SToby Isaac @*/
3623d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3624d71ae5a4SJacob Faibussowitsch {
362558ebd649SToby Isaac   DSBoundary b = ds->boundary;
362658ebd649SToby Isaac 
362758ebd649SToby Isaac   PetscFunctionBegin;
362858ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3629dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
363058ebd649SToby Isaac   *numBd = 0;
36319371c9d4SSatish Balay   while (b) {
36329371c9d4SSatish Balay     ++(*numBd);
36339371c9d4SSatish Balay     b = b->next;
36349371c9d4SSatish Balay   }
36353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
363658ebd649SToby Isaac }
363758ebd649SToby Isaac 
363858ebd649SToby Isaac /*@C
36399a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
364058ebd649SToby Isaac 
364158ebd649SToby Isaac   Input Parameters:
3642dce8aebaSBarry Smith + ds          - The `PetscDS` object
364358ebd649SToby Isaac - bd          - The BC number
364458ebd649SToby Isaac 
364558ebd649SToby Isaac   Output Parameters:
3646dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3647dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
364858ebd649SToby Isaac . name     - The BC name
364945480ffeSMatthew G. Knepley . label    - The label defining constrained points
3650dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
365145480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
365258ebd649SToby Isaac . field    - The field to constrain
365345480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
365458ebd649SToby Isaac . comps    - An array of constrained component numbers
365558ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3656a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
365758ebd649SToby Isaac - ctx      - An optional user context for bcFunc
365858ebd649SToby Isaac 
365958ebd649SToby Isaac   Options Database Keys:
366058ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
366158ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
366258ebd649SToby Isaac 
366358ebd649SToby Isaac   Level: developer
366458ebd649SToby Isaac 
3665dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
366658ebd649SToby Isaac @*/
3667d71ae5a4SJacob 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)
3668d71ae5a4SJacob Faibussowitsch {
366958ebd649SToby Isaac   DSBoundary b = ds->boundary;
367058ebd649SToby Isaac   PetscInt   n = 0;
367158ebd649SToby Isaac 
367258ebd649SToby Isaac   PetscFunctionBegin;
367358ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
367458ebd649SToby Isaac   while (b) {
367558ebd649SToby Isaac     if (n == bd) break;
367658ebd649SToby Isaac     b = b->next;
367758ebd649SToby Isaac     ++n;
367858ebd649SToby Isaac   }
367963a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
368045480ffeSMatthew G. Knepley   if (wf) {
368145480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
368245480ffeSMatthew G. Knepley     *wf = b->wf;
368345480ffeSMatthew G. Knepley   }
3684f971fd6bSMatthew G. Knepley   if (type) {
368545480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3686f971fd6bSMatthew G. Knepley     *type = b->type;
368758ebd649SToby Isaac   }
368858ebd649SToby Isaac   if (name) {
368945480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
369058ebd649SToby Isaac     *name = b->name;
369158ebd649SToby Isaac   }
369245480ffeSMatthew G. Knepley   if (label) {
369345480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
369445480ffeSMatthew G. Knepley     *label = b->label;
369545480ffeSMatthew G. Knepley   }
369645480ffeSMatthew G. Knepley   if (Nv) {
369745480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
369845480ffeSMatthew G. Knepley     *Nv = b->Nv;
369945480ffeSMatthew G. Knepley   }
370045480ffeSMatthew G. Knepley   if (values) {
370145480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
370245480ffeSMatthew G. Knepley     *values = b->values;
370358ebd649SToby Isaac   }
370458ebd649SToby Isaac   if (field) {
370545480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
370658ebd649SToby Isaac     *field = b->field;
370758ebd649SToby Isaac   }
370845480ffeSMatthew G. Knepley   if (Nc) {
370945480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
371045480ffeSMatthew G. Knepley     *Nc = b->Nc;
371158ebd649SToby Isaac   }
371258ebd649SToby Isaac   if (comps) {
371345480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
371458ebd649SToby Isaac     *comps = b->comps;
371558ebd649SToby Isaac   }
371658ebd649SToby Isaac   if (func) {
371745480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
371858ebd649SToby Isaac     *func = b->func;
371958ebd649SToby Isaac   }
372056cf3b9cSMatthew G. Knepley   if (func_t) {
372145480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
372256cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
372356cf3b9cSMatthew G. Knepley   }
372458ebd649SToby Isaac   if (ctx) {
372545480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
372658ebd649SToby Isaac     *ctx = b->ctx;
372758ebd649SToby Isaac   }
37283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
372958ebd649SToby Isaac }
373058ebd649SToby Isaac 
3731d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3732d71ae5a4SJacob Faibussowitsch {
373345480ffeSMatthew G. Knepley   PetscFunctionBegin;
37349566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37369566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37379566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37389566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
373945480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
374045480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
374145480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37439566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
374445480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
374545480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37469566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37479566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
374845480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
374945480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
375045480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
37513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375245480ffeSMatthew G. Knepley }
375345480ffeSMatthew G. Knepley 
37549252d075SMatthew G. Knepley /*@
37559252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
37569252d075SMatthew G. Knepley 
37579252d075SMatthew G. Knepley   Not collective
37589252d075SMatthew G. Knepley 
375936951cb5SMatthew G. Knepley   Input Parameters:
3760dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3761dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
376236951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
37639252d075SMatthew G. Knepley 
37649252d075SMatthew G. Knepley   Output Parameter:
3765dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
37669252d075SMatthew G. Knepley 
37679252d075SMatthew G. Knepley   Level: intermediate
37689252d075SMatthew G. Knepley 
3769dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37709252d075SMatthew G. Knepley @*/
3771d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3772d71ae5a4SJacob Faibussowitsch {
377345480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3774dff059c6SToby Isaac 
3775dff059c6SToby Isaac   PetscFunctionBegin;
377636951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
377736951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
37783ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
37799566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
378036951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
378136951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3782dff059c6SToby Isaac     DSBoundary bNew;
378336951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3784dff059c6SToby Isaac 
378536951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
378636951cb5SMatthew G. Knepley       PetscInt f;
378736951cb5SMatthew G. Knepley 
37889371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
37899371c9d4SSatish Balay         if (b->field == fields[f]) break;
379036951cb5SMatthew G. Knepley       if (f == numFields) continue;
379136951cb5SMatthew G. Knepley       fieldNew = f;
379236951cb5SMatthew G. Knepley     }
37939566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
379436951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3795dff059c6SToby Isaac     *lastnext   = bNew;
3796dff059c6SToby Isaac     lastnext    = &(bNew->next);
3797dff059c6SToby Isaac   }
37983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3799dff059c6SToby Isaac }
3800dff059c6SToby Isaac 
38016c1eb96dSMatthew G. Knepley /*@
3802dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
380345480ffeSMatthew G. Knepley 
380445480ffeSMatthew G. Knepley   Not collective
380545480ffeSMatthew G. Knepley 
380645480ffeSMatthew G. Knepley   Input Parameter:
3807dce8aebaSBarry Smith . ds - The `PetscDS` object
380845480ffeSMatthew G. Knepley 
380945480ffeSMatthew G. Knepley   Level: intermediate
381045480ffeSMatthew G. Knepley 
3811dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
381245480ffeSMatthew G. Knepley @*/
3813d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3814d71ae5a4SJacob Faibussowitsch {
381545480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
381645480ffeSMatthew G. Knepley 
381745480ffeSMatthew G. Knepley   PetscFunctionBegin;
381845480ffeSMatthew G. Knepley   while (next) {
381945480ffeSMatthew G. Knepley     DSBoundary b = next;
382045480ffeSMatthew G. Knepley 
382145480ffeSMatthew G. Knepley     next = b->next;
38229566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38239566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38249566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38259566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38269566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38279566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
382845480ffeSMatthew G. Knepley   }
38293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
383045480ffeSMatthew G. Knepley }
383145480ffeSMatthew G. Knepley 
383245480ffeSMatthew G. Knepley /*@
38336c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38346c1eb96dSMatthew G. Knepley 
38356c1eb96dSMatthew G. Knepley   Not collective
38366c1eb96dSMatthew G. Knepley 
3837d8d19677SJose E. Roman   Input Parameters:
3838dce8aebaSBarry Smith + prob - The `PetscDS` object
38396c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38406c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
38416c1eb96dSMatthew G. Knepley 
38426c1eb96dSMatthew G. Knepley   Output Parameter:
3843dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38446c1eb96dSMatthew G. Knepley 
38456c1eb96dSMatthew G. Knepley   Level: intermediate
38466c1eb96dSMatthew G. Knepley 
3847dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38486c1eb96dSMatthew G. Knepley @*/
3849d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3850d71ae5a4SJacob Faibussowitsch {
38516c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
38526c1eb96dSMatthew G. Knepley 
38536c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
38546c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3855dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38566c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38579566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38589566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
385945480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
38606c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38616c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
38626c1eb96dSMatthew G. Knepley     PetscObject    disc;
38636c1eb96dSMatthew G. Knepley 
38646c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
38659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
38669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
38676c1eb96dSMatthew G. Knepley   }
38683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38696c1eb96dSMatthew G. Knepley }
38706c1eb96dSMatthew G. Knepley 
38716c1eb96dSMatthew G. Knepley /*@
38729252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
38739252d075SMatthew G. Knepley 
38749252d075SMatthew G. Knepley   Not collective
38759252d075SMatthew G. Knepley 
3876d8d19677SJose E. Roman   Input Parameters:
3877dce8aebaSBarry Smith + prob - The `PetscDS` object
38789252d075SMatthew G. Knepley . numFields - Number of new fields
38799252d075SMatthew G. Knepley - fields - Old field number for each new field
38809252d075SMatthew G. Knepley 
38819252d075SMatthew G. Knepley   Output Parameter:
3882dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38839252d075SMatthew G. Knepley 
38849252d075SMatthew G. Knepley   Level: intermediate
38859252d075SMatthew G. Knepley 
3886dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38879252d075SMatthew G. Knepley @*/
3888d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3889d71ae5a4SJacob Faibussowitsch {
38909252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
38919252d075SMatthew G. Knepley 
38929252d075SMatthew G. Knepley   PetscFunctionBegin;
38939252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3894dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38959252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38969566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38979566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
389863a3b9bcSJacob 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);
38999252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39009252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39019252d075SMatthew G. Knepley     PetscPointFunc   obj;
39029252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39039252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39049252d075SMatthew G. Knepley     PetscRiemannFunc r;
39059252d075SMatthew G. Knepley 
3906c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39079566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39089566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39099566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39109566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39119566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39129566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39139566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39149566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39159252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39169252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39179252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39189252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39199252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39209252d075SMatthew G. Knepley 
3921c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39229566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39239566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39249566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39259566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39269566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39279566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39289252d075SMatthew G. Knepley     }
39299252d075SMatthew G. Knepley   }
39303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39319252d075SMatthew G. Knepley }
39329252d075SMatthew G. Knepley 
3933da51fcedSMatthew G. Knepley /*@
3934dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3935da51fcedSMatthew G. Knepley 
3936da51fcedSMatthew G. Knepley   Not collective
3937da51fcedSMatthew G. Knepley 
3938da51fcedSMatthew G. Knepley   Input Parameter:
3939dce8aebaSBarry Smith . prob - The `PetscDS` object
3940da51fcedSMatthew G. Knepley 
3941da51fcedSMatthew G. Knepley   Output Parameter:
3942dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3943da51fcedSMatthew G. Knepley 
3944da51fcedSMatthew G. Knepley   Level: intermediate
3945da51fcedSMatthew G. Knepley 
3946dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3947da51fcedSMatthew G. Knepley @*/
3948d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3949d71ae5a4SJacob Faibussowitsch {
3950b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
39519252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3952da51fcedSMatthew G. Knepley 
3953da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3954da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3955da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39569566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39579566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
395863a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
39599566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
39609566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
39619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
39623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39639252d075SMatthew G. Knepley }
396445480ffeSMatthew G. Knepley 
39659252d075SMatthew G. Knepley /*@
3966dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3967da51fcedSMatthew G. Knepley 
39689252d075SMatthew G. Knepley   Not collective
39699252d075SMatthew G. Knepley 
39709252d075SMatthew G. Knepley   Input Parameter:
3971dce8aebaSBarry Smith . prob - The `PetscDS` object
39729252d075SMatthew G. Knepley 
39739252d075SMatthew G. Knepley   Output Parameter:
3974dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39759252d075SMatthew G. Knepley 
39769252d075SMatthew G. Knepley   Level: intermediate
39779252d075SMatthew G. Knepley 
3978dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39799252d075SMatthew G. Knepley @*/
3980d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3981d71ae5a4SJacob Faibussowitsch {
39829252d075SMatthew G. Knepley   PetscInt           Nc;
39839252d075SMatthew G. Knepley   const PetscScalar *constants;
39849252d075SMatthew G. Knepley 
39859252d075SMatthew G. Knepley   PetscFunctionBegin;
39869252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39879252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39889566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
39899566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
39903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3991da51fcedSMatthew G. Knepley }
3992da51fcedSMatthew G. Knepley 
399345480ffeSMatthew G. Knepley /*@
3994dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
399545480ffeSMatthew G. Knepley 
399645480ffeSMatthew G. Knepley   Not collective
399745480ffeSMatthew G. Knepley 
399845480ffeSMatthew G. Knepley   Input Parameter:
3999dce8aebaSBarry Smith . ds - The `PetscDS` object
400045480ffeSMatthew G. Knepley 
400145480ffeSMatthew G. Knepley   Output Parameter:
4002dce8aebaSBarry Smith . newds - The `PetscDS` copy
400345480ffeSMatthew G. Knepley 
400445480ffeSMatthew G. Knepley   Level: intermediate
400545480ffeSMatthew G. Knepley 
4006dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
400745480ffeSMatthew G. Knepley @*/
4008d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4009d71ae5a4SJacob Faibussowitsch {
401045480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
401145480ffeSMatthew G. Knepley   void                *ctx;
401245480ffeSMatthew G. Knepley   PetscInt             Nf, f;
401345480ffeSMatthew G. Knepley 
401445480ffeSMatthew G. Knepley   PetscFunctionBegin;
401545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
401645480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40179566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
401845480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40199566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40209566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40219566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40229566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
402345480ffeSMatthew G. Knepley   }
40243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
402545480ffeSMatthew G. Knepley }
402645480ffeSMatthew G. Knepley 
4027d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4028d71ae5a4SJacob Faibussowitsch {
4029df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4030b1353e8eSMatthew G. Knepley 
4031b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4032b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4033b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
40349371c9d4SSatish Balay   if (height == 0) {
40359371c9d4SSatish Balay     *subprob = prob;
40363ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
40379371c9d4SSatish Balay   }
40389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40399566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
404063a3b9bcSJacob 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);
40419566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4042df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4043b1353e8eSMatthew G. Knepley     PetscInt cdim;
4044b1353e8eSMatthew G. Knepley 
40459566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
40469566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
40479566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4048b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4049b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4050b1353e8eSMatthew G. Knepley       PetscObject  obj;
4051b1353e8eSMatthew G. Knepley       PetscClassId id;
4052b1353e8eSMatthew G. Knepley 
40539566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40549566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
40559566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
405663a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
40579566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4058b1353e8eSMatthew G. Knepley     }
4059b1353e8eSMatthew G. Knepley   }
4060df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
40613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4062b1353e8eSMatthew G. Knepley }
4063b1353e8eSMatthew G. Knepley 
4064d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4065d71ae5a4SJacob Faibussowitsch {
4066c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4067c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4068c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4069c7bd5f0bSMatthew G. Knepley 
4070c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4071c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4072665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4073665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
40749566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
407563a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
40769566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4077665f567fSMatthew G. Knepley   if (obj) {
40789566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4079665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4080665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4081665f567fSMatthew G. Knepley   }
40823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4083c7bd5f0bSMatthew G. Knepley }
4084c7bd5f0bSMatthew G. Knepley 
4085d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4086d71ae5a4SJacob Faibussowitsch {
40872764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40889566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
40893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40902764a2aaSMatthew G. Knepley }
40912764a2aaSMatthew G. Knepley 
4092d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4093d71ae5a4SJacob Faibussowitsch {
40942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40956528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
40966528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
40976528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
40986528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
40993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41002764a2aaSMatthew G. Knepley }
41012764a2aaSMatthew G. Knepley 
41022764a2aaSMatthew G. Knepley /*MC
41032764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
41042764a2aaSMatthew G. Knepley 
41052764a2aaSMatthew G. Knepley   Level: intermediate
41062764a2aaSMatthew G. Knepley 
4107db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
41082764a2aaSMatthew G. Knepley M*/
41092764a2aaSMatthew G. Knepley 
4110d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4111d71ae5a4SJacob Faibussowitsch {
41122764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
41132764a2aaSMatthew G. Knepley 
41142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41164dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
41176528b96dSMatthew G. Knepley   ds->data = b;
41182764a2aaSMatthew G. Knepley 
41199566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
41203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41212764a2aaSMatthew G. Knepley }
4122