xref: /petsc/src/dm/dt/interface/dtds.c (revision 49ae0b562d1cf772c12858790981bb97a53e466a)
1af0996ceSBarry Smith #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/
22764a2aaSMatthew G. Knepley 
32764a2aaSMatthew G. Knepley PetscClassId PETSCDS_CLASSID = 0;
42764a2aaSMatthew G. Knepley 
52764a2aaSMatthew G. Knepley PetscFunctionList PetscDSList              = NULL;
62764a2aaSMatthew G. Knepley PetscBool         PetscDSRegisterAllCalled = PETSC_FALSE;
72764a2aaSMatthew G. Knepley 
894dcdc3fSMatthew G. Knepley /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of
994dcdc3fSMatthew G. Knepley    nonlinear continuum equations. The equations can have multiple fields, each field having a different
1094dcdc3fSMatthew G. Knepley    discretization. In addition, different pieces of the domain can have different field combinations and equations.
1194dcdc3fSMatthew G. Knepley 
1294dcdc3fSMatthew G. Knepley    The DS provides the user a description of the approximation space on any given cell. It also gives pointwise
1394dcdc3fSMatthew G. Knepley    functions representing the equations.
1494dcdc3fSMatthew G. Knepley 
1594dcdc3fSMatthew G. Knepley    Each field is associated with a label, marking the cells on which it is supported. Note that a field can be
1694dcdc3fSMatthew G. Knepley    supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM
1794dcdc3fSMatthew G. Knepley    then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for
1894dcdc3fSMatthew G. Knepley    the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop.
1994dcdc3fSMatthew G. Knepley */
2094dcdc3fSMatthew G. Knepley 
212764a2aaSMatthew G. Knepley /*@C
22dce8aebaSBarry Smith   PetscDSRegister - Adds a new `PetscDS` implementation
232764a2aaSMatthew G. Knepley 
242764a2aaSMatthew G. Knepley   Not Collective
252764a2aaSMatthew G. Knepley 
262764a2aaSMatthew G. Knepley   Input Parameters:
272764a2aaSMatthew G. Knepley + name        - The name of a new user-defined creation routine
282764a2aaSMatthew G. Knepley - create_func - The creation routine itself
292764a2aaSMatthew G. Knepley 
302764a2aaSMatthew G. Knepley   Sample usage:
312764a2aaSMatthew G. Knepley .vb
322764a2aaSMatthew G. Knepley     PetscDSRegister("my_ds", MyPetscDSCreate);
332764a2aaSMatthew G. Knepley .ve
342764a2aaSMatthew G. Knepley 
352764a2aaSMatthew G. Knepley   Then, your PetscDS type can be chosen with the procedural interface via
362764a2aaSMatthew G. Knepley .vb
372764a2aaSMatthew G. Knepley     PetscDSCreate(MPI_Comm, PetscDS *);
382764a2aaSMatthew G. Knepley     PetscDSSetType(PetscDS, "my_ds");
392764a2aaSMatthew G. Knepley .ve
402764a2aaSMatthew G. Knepley    or at runtime via the option
412764a2aaSMatthew G. Knepley .vb
422764a2aaSMatthew G. Knepley     -petscds_type my_ds
432764a2aaSMatthew G. Knepley .ve
442764a2aaSMatthew G. Knepley 
452764a2aaSMatthew G. Knepley   Level: advanced
462764a2aaSMatthew G. Knepley 
47dce8aebaSBarry Smith   Note:
48dce8aebaSBarry Smith   `PetscDSRegister()` may be called multiple times to add several user-defined `PetscDSs`
49dce8aebaSBarry Smith 
50dce8aebaSBarry Smith   Fortran Note:
51f5f57ec0SBarry Smith   Not available from Fortran
52f5f57ec0SBarry Smith 
53dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
542764a2aaSMatthew G. Knepley @*/
55d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
56d71ae5a4SJacob Faibussowitsch {
572764a2aaSMatthew G. Knepley   PetscFunctionBegin;
589566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
602764a2aaSMatthew G. Knepley }
612764a2aaSMatthew G. Knepley 
622764a2aaSMatthew G. Knepley /*@C
63dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
642764a2aaSMatthew G. Knepley 
65d083f849SBarry Smith   Collective on prob
662764a2aaSMatthew G. Knepley 
672764a2aaSMatthew G. Knepley   Input Parameters:
68dce8aebaSBarry Smith + prob - The `PetscDS` object
69dce8aebaSBarry Smith - name - The `PetscDSType`
702764a2aaSMatthew G. Knepley 
712764a2aaSMatthew G. Knepley   Options Database Key:
722764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
732764a2aaSMatthew G. Knepley 
742764a2aaSMatthew G. Knepley   Level: intermediate
752764a2aaSMatthew G. Knepley 
76dce8aebaSBarry Smith   Fortran Note:
77f5f57ec0SBarry Smith   Not available from Fortran
78f5f57ec0SBarry Smith 
79dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
802764a2aaSMatthew G. Knepley @*/
81d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
82d71ae5a4SJacob Faibussowitsch {
832764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
842764a2aaSMatthew G. Knepley   PetscBool match;
852764a2aaSMatthew G. Knepley 
862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
872764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
893ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
902764a2aaSMatthew G. Knepley 
919566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
929566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
9328b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
942764a2aaSMatthew G. Knepley 
95dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
962764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
97dbbe0bcdSBarry Smith 
989566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
999566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1012764a2aaSMatthew G. Knepley }
1022764a2aaSMatthew G. Knepley 
1032764a2aaSMatthew G. Knepley /*@C
104dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
1052764a2aaSMatthew G. Knepley 
1062764a2aaSMatthew G. Knepley   Not Collective
1072764a2aaSMatthew G. Knepley 
1082764a2aaSMatthew G. Knepley   Input Parameter:
109dce8aebaSBarry Smith . prob  - The `PetscDS`
1102764a2aaSMatthew G. Knepley 
1112764a2aaSMatthew G. Knepley   Output Parameter:
112dce8aebaSBarry Smith . name - The `PetscDSType` name
1132764a2aaSMatthew G. Knepley 
1142764a2aaSMatthew G. Knepley   Level: intermediate
1152764a2aaSMatthew G. Knepley 
116dce8aebaSBarry Smith   Fortran Note:
117f5f57ec0SBarry Smith   Not available from Fortran
118f5f57ec0SBarry Smith 
119dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
1202764a2aaSMatthew G. Knepley @*/
121d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
122d71ae5a4SJacob Faibussowitsch {
1232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1242764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
125c959eef4SJed Brown   PetscValidPointer(name, 2);
1269566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1272764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1292764a2aaSMatthew G. Knepley }
1302764a2aaSMatthew G. Knepley 
131d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
132d71ae5a4SJacob Faibussowitsch {
1337d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
13497b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1355fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1367d8a60eaSMatthew G. Knepley 
1377d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
14063a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
14263a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1439566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1445fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
14540967b3bSMatthew G. Knepley     DSBoundary      b;
1467d8a60eaSMatthew G. Knepley     PetscObject     obj;
1477d8a60eaSMatthew G. Knepley     PetscClassId    id;
148f35450b9SMatthew G. Knepley     PetscQuadrature q;
1497d8a60eaSMatthew G. Knepley     const char     *name;
150f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1517d8a60eaSMatthew G. Knepley 
1529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1539566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1549566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1559566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1577d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1589566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1599566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1609566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1617d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1639566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1659371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
16663a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
16763a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1689566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1699566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1703e60c2a6SMatthew G. Knepley     if (q) {
1719566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
17263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1733e60c2a6SMatthew G. Knepley     }
17463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1759566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1769566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1779566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1789566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1799566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1809566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
18140967b3bSMatthew G. Knepley 
1825fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
18306ad1575SMatthew G. Knepley       char    *name;
18440967b3bSMatthew G. Knepley       PetscInt c, i;
18540967b3bSMatthew G. Knepley 
18640967b3bSMatthew G. Knepley       if (b->field != f) continue;
1879566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1889566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
18945480ffeSMatthew G. Knepley       if (!b->Nc) {
1909566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
19140967b3bSMatthew G. Knepley       } else {
1929566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1939566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
19445480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1959566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
19663a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
19740967b3bSMatthew G. Knepley         }
1989566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1999566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20040967b3bSMatthew G. Knepley       }
2019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
2029566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
20345480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
2049566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
20563a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
20640967b3bSMatthew G. Knepley       }
2079566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
2089566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20915943bb8SPierre Jolivet #if defined(__clang__)
21015943bb8SPierre Jolivet   #pragma clang diagnostic push
21115943bb8SPierre Jolivet   #pragma clang diagnostic ignored "-Wformat-pedantic"
21215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
21315943bb8SPierre Jolivet   #pragma GCC diagnostic push
21415943bb8SPierre Jolivet   #pragma GCC diagnostic ignored "-Wformat"
21515943bb8SPierre Jolivet #endif
2168e0d8d9cSMatthew G. Knepley       if (b->func) {
2179566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2189566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2199566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2209566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2218e0d8d9cSMatthew G. Knepley       }
2228e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2239566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2249566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2259566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2269566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2278e0d8d9cSMatthew G. Knepley       }
22815943bb8SPierre Jolivet #if defined(__clang__)
22915943bb8SPierre Jolivet   #pragma clang diagnostic pop
23015943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
23115943bb8SPierre Jolivet   #pragma GCC diagnostic pop
23215943bb8SPierre Jolivet #endif
2339566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
23540967b3bSMatthew G. Knepley     }
2367d8a60eaSMatthew G. Knepley   }
2379566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
23897b6e6e8SMatthew G. Knepley   if (numConstants) {
23963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2409566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2419566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2429566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
24397b6e6e8SMatthew G. Knepley   }
2449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2459566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2477d8a60eaSMatthew G. Knepley }
2487d8a60eaSMatthew G. Knepley 
2492764a2aaSMatthew G. Knepley /*@C
250dce8aebaSBarry Smith    PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
251fe2efc57SMark 
252fe2efc57SMark    Collective on PetscDS
253fe2efc57SMark 
254fe2efc57SMark    Input Parameters:
255dce8aebaSBarry Smith +  A - the `PetscDS` object
256736c3998SJose E. Roman .  obj - Optional object
257736c3998SJose E. Roman -  name - command line option
258fe2efc57SMark 
259fe2efc57SMark    Level: intermediate
260dce8aebaSBarry Smith 
261dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
262fe2efc57SMark @*/
263d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
264d71ae5a4SJacob Faibussowitsch {
265fe2efc57SMark   PetscFunctionBegin;
266fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2679566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
269fe2efc57SMark }
270fe2efc57SMark 
271fe2efc57SMark /*@C
272dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2732764a2aaSMatthew G. Knepley 
274d083f849SBarry Smith   Collective on prob
2752764a2aaSMatthew G. Knepley 
276d8d19677SJose E. Roman   Input Parameters:
277dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2782764a2aaSMatthew G. Knepley - v  - the viewer
2792764a2aaSMatthew G. Knepley 
2802764a2aaSMatthew G. Knepley   Level: developer
2812764a2aaSMatthew G. Knepley 
282dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`
2832764a2aaSMatthew G. Knepley @*/
284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
285d71ae5a4SJacob Faibussowitsch {
2867d8a60eaSMatthew G. Knepley   PetscBool iascii;
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2892764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2909566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
291ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2939566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
294dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2962764a2aaSMatthew G. Knepley }
2972764a2aaSMatthew G. Knepley 
2982764a2aaSMatthew G. Knepley /*@
299dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
3002764a2aaSMatthew G. Knepley 
301d083f849SBarry Smith   Collective on prob
3022764a2aaSMatthew G. Knepley 
3032764a2aaSMatthew G. Knepley   Input Parameter:
304dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
3052764a2aaSMatthew G. Knepley 
306dce8aebaSBarry Smith   Options Database Keys:
307dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
308dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
309147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
310147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
311147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
3122764a2aaSMatthew G. Knepley 
313dce8aebaSBarry Smith   Level: intermediate
3142764a2aaSMatthew G. Knepley 
315dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3162764a2aaSMatthew G. Knepley @*/
317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
318d71ae5a4SJacob Faibussowitsch {
319f1fd5e65SToby Isaac   DSBoundary  b;
3202764a2aaSMatthew G. Knepley   const char *defaultType;
3212764a2aaSMatthew G. Knepley   char        name[256];
3222764a2aaSMatthew G. Knepley   PetscBool   flg;
3232764a2aaSMatthew G. Knepley 
3242764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3252764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3262764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3272764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3282764a2aaSMatthew G. Knepley   } else {
3292764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3302764a2aaSMatthew G. Knepley   }
3319566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3322764a2aaSMatthew G. Knepley 
333d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
334f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
335f1fd5e65SToby Isaac     char      optname[1024];
336f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
337f1fd5e65SToby Isaac     PetscBool flg;
338f1fd5e65SToby Isaac 
3399566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3409566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3419566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
342f1fd5e65SToby Isaac     if (flg) {
34345480ffeSMatthew G. Knepley       b->Nv = len;
3449566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3459566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3469566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3479566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
348f1fd5e65SToby Isaac     }
349e7b0402cSSander Arens     len = 1024;
3509566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3519566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
353f1fd5e65SToby Isaac     if (flg) {
35445480ffeSMatthew G. Knepley       b->Nc = len;
3559566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3569566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3579566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
358f1fd5e65SToby Isaac     }
359f1fd5e65SToby Isaac   }
3609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3612764a2aaSMatthew G. Knepley   if (flg) {
3629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3632764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3652764a2aaSMatthew G. Knepley   }
3669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
36712fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
368dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3692764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
370dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
371d0609cedSBarry Smith   PetscOptionsEnd();
3729566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3742764a2aaSMatthew G. Knepley }
3752764a2aaSMatthew G. Knepley 
3762764a2aaSMatthew G. Knepley /*@C
377dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3782764a2aaSMatthew G. Knepley 
379d083f849SBarry Smith   Collective on prob
3802764a2aaSMatthew G. Knepley 
3812764a2aaSMatthew G. Knepley   Input Parameter:
382dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3832764a2aaSMatthew G. Knepley 
3842764a2aaSMatthew G. Knepley   Level: developer
3852764a2aaSMatthew G. Knepley 
386dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3872764a2aaSMatthew G. Knepley @*/
388d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
389d71ae5a4SJacob Faibussowitsch {
3902764a2aaSMatthew G. Knepley   const PetscInt Nf   = prob->Nf;
391f9244615SMatthew G. Knepley   PetscBool      hasH = PETSC_FALSE;
3924bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
393*49ae0b56SMatthew G. Knepley   PetscInt       gorder = -1, fgorder = -1;
3942764a2aaSMatthew G. Knepley 
3952764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3962764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3973ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3982764a2aaSMatthew G. Knepley   /* Calculate sizes */
3999566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
4009566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
401f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
4029566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
4039566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
4049566063dSJacob 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]));
4059566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
40612fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
40712fc5b22SMatthew G. Knepley     PetscQuadrature mq = NULL, mfq = NULL;
40812fc5b22SMatthew G. Knepley     PetscInt        maxOrder = -1, maxFOrder = -1;
40912fc5b22SMatthew G. Knepley 
41012fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
41112fc5b22SMatthew G. Knepley       PetscObject     obj;
41212fc5b22SMatthew G. Knepley       PetscClassId    id;
41312fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
41412fc5b22SMatthew G. Knepley       PetscInt        order = -1, forder = -1;
41512fc5b22SMatthew G. Knepley 
41612fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41712fc5b22SMatthew G. Knepley       if (!obj) continue;
41812fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
41912fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
42012fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
42112fc5b22SMatthew G. Knepley 
42212fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
42312fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
42412fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
42512fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
42612fc5b22SMatthew G. Knepley 
42712fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
42812fc5b22SMatthew G. Knepley       }
42912fc5b22SMatthew G. Knepley       if (q) PetscCall(PetscQuadratureGetOrder(q, &order));
43012fc5b22SMatthew G. Knepley       if (fq) PetscCall(PetscQuadratureGetOrder(fq, &forder));
43112fc5b22SMatthew G. Knepley       if (order > maxOrder) {
43212fc5b22SMatthew G. Knepley         maxOrder = order;
43312fc5b22SMatthew G. Knepley         mq       = q;
43412fc5b22SMatthew G. Knepley       }
43512fc5b22SMatthew G. Knepley       if (forder > maxFOrder) {
43612fc5b22SMatthew G. Knepley         maxFOrder = forder;
43712fc5b22SMatthew G. Knepley         mfq       = fq;
43812fc5b22SMatthew G. Knepley       }
43912fc5b22SMatthew G. Knepley     }
44012fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
44112fc5b22SMatthew G. Knepley       PetscObject  obj;
44212fc5b22SMatthew G. Knepley       PetscClassId id;
44312fc5b22SMatthew G. Knepley 
44412fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
44512fc5b22SMatthew G. Knepley       if (!obj) continue;
44612fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44712fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44812fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44912fc5b22SMatthew G. Knepley 
45012fc5b22SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, mq));
45112fc5b22SMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, mfq));
45212fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
45312fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
45412fc5b22SMatthew G. Knepley 
45512fc5b22SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, mq));
45612fc5b22SMatthew G. Knepley       }
45712fc5b22SMatthew G. Knepley     }
45812fc5b22SMatthew G. Knepley   }
4592764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4609de99aefSMatthew G. Knepley     PetscObject     obj;
4619de99aefSMatthew G. Knepley     PetscClassId    id;
462665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4639de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4642764a2aaSMatthew G. Knepley 
4659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
466f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
467665f567fSMatthew G. Knepley     if (!obj) {
468665f567fSMatthew G. Knepley       /* Empty mesh */
469665f567fSMatthew G. Knepley       Nb = Nc    = 0;
470665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
471665f567fSMatthew G. Knepley     } else {
4729566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4739de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4749de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4759de99aefSMatthew G. Knepley 
4769566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
477*49ae0b56SMatthew G. Knepley         {
478*49ae0b56SMatthew G. Knepley           PetscQuadrature fq;
479*49ae0b56SMatthew G. Knepley           PetscInt        order, forder;
480*49ae0b56SMatthew G. Knepley 
481*49ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
482*49ae0b56SMatthew G. Knepley           if (gorder < 0) gorder = order;
483*49ae0b56SMatthew 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);
484*49ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
485*49ae0b56SMatthew G. Knepley           if (fq) {
486*49ae0b56SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &forder));
487*49ae0b56SMatthew G. Knepley             if (fgorder < 0) fgorder = forder;
488*49ae0b56SMatthew 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);
489*49ae0b56SMatthew G. Knepley           }
490*49ae0b56SMatthew G. Knepley         }
4919566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4929566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4949566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4959de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4969de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4979de99aefSMatthew G. Knepley 
4989566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4999566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
5009c3cf19fSMatthew G. Knepley         Nb = Nc;
5019566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
5024d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
50363a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
504665f567fSMatthew G. Knepley     }
50547e57110SSander Arens     prob->Nc[f]                    = Nc;
50647e57110SSander Arens     prob->Nb[f]                    = Nb;
507194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
508194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5099ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5109ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5119ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5129ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5139ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5149ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5159566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5162764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5174bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5182764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5199c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5202764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5215fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5225fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5232764a2aaSMatthew G. Knepley   }
5249ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5259ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5262764a2aaSMatthew G. Knepley   /* Allocate works space */
5275fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5289566063dSJacob 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));
5299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5309371c9d4SSatish 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,
5319371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
532dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5332764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5352764a2aaSMatthew G. Knepley }
5362764a2aaSMatthew G. Knepley 
537d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
538d71ae5a4SJacob Faibussowitsch {
5392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5409566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5429566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5439566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5449566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5459566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5482764a2aaSMatthew G. Knepley }
5492764a2aaSMatthew G. Knepley 
550d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
551d71ae5a4SJacob Faibussowitsch {
552f744cafaSSander Arens   PetscObject          *tmpd;
55334aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
554f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5555fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5566528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
557f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
558f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5590c2f2876SMatthew G. Knepley   void                **tmpctx;
56034aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5612764a2aaSMatthew G. Knepley 
5622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5633ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5642764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5659566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5669566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5679371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5689371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5699371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5709371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5719371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5729371c9d4SSatish Balay   }
5739371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5749371c9d4SSatish Balay     tmpd[f] = NULL;
5759371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5769371c9d4SSatish Balay     tmpk[f] = 1;
5779371c9d4SSatish Balay   }
5789566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5802764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5812764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
582249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5835fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
584f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5859566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58632d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5870c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58832d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5890c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5909566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59132d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5920c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5939566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
594c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59595cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
596f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
597f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
598c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
59995cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
600f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
601f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
6029566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
603c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60495cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
605f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
606f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6082764a2aaSMatthew G. Knepley }
6092764a2aaSMatthew G. Knepley 
6102764a2aaSMatthew G. Knepley /*@
6112764a2aaSMatthew G. Knepley   PetscDSDestroy - Destroys a PetscDS object
6122764a2aaSMatthew G. Knepley 
613d083f849SBarry Smith   Collective on prob
6142764a2aaSMatthew G. Knepley 
6152764a2aaSMatthew G. Knepley   Input Parameter:
6162764a2aaSMatthew G. Knepley . prob - the PetscDS object to destroy
6172764a2aaSMatthew G. Knepley 
6182764a2aaSMatthew G. Knepley   Level: developer
6192764a2aaSMatthew G. Knepley 
620dce8aebaSBarry Smith .seealso: `PetscDSView()`
6212764a2aaSMatthew G. Knepley @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
623d71ae5a4SJacob Faibussowitsch {
6242764a2aaSMatthew G. Knepley   PetscInt f;
6252764a2aaSMatthew G. Knepley 
6262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6273ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6292764a2aaSMatthew G. Knepley 
6309371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6319371c9d4SSatish Balay     *ds = NULL;
6323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6339371c9d4SSatish Balay   }
6346528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6356528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
636df3a45bdSMatthew G. Knepley     PetscInt dim, d;
637df3a45bdSMatthew G. Knepley 
6389566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6399566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
640df3a45bdSMatthew G. Knepley   }
6419566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6429566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64348a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6449566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6469566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6479566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
648dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6499566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6509566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6519566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6532764a2aaSMatthew G. Knepley }
6542764a2aaSMatthew G. Knepley 
6552764a2aaSMatthew G. Knepley /*@
656dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6572764a2aaSMatthew G. Knepley 
658d083f849SBarry Smith   Collective
6592764a2aaSMatthew G. Knepley 
6602764a2aaSMatthew G. Knepley   Input Parameter:
661dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6622764a2aaSMatthew G. Knepley 
6632764a2aaSMatthew G. Knepley   Output Parameter:
664dce8aebaSBarry Smith . ds   - The `PetscDS` object
6652764a2aaSMatthew G. Knepley 
6662764a2aaSMatthew G. Knepley   Level: beginner
6672764a2aaSMatthew G. Knepley 
668dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6692764a2aaSMatthew G. Knepley @*/
670d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
671d71ae5a4SJacob Faibussowitsch {
6722764a2aaSMatthew G. Knepley   PetscDS p;
6732764a2aaSMatthew G. Knepley 
6742764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6756528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6766528b96dSMatthew G. Knepley   *ds = NULL;
6779566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6782764a2aaSMatthew G. Knepley 
6799566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6802764a2aaSMatthew G. Knepley 
6812764a2aaSMatthew G. Knepley   p->Nf           = 0;
6822764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
68397b6e6e8SMatthew G. Knepley   p->numConstants = 0;
68497b6e6e8SMatthew G. Knepley   p->constants    = NULL;
685a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
68655c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
68712fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6889566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6892764a2aaSMatthew G. Knepley 
6906528b96dSMatthew G. Knepley   *ds = p;
6913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6922764a2aaSMatthew G. Knepley }
6932764a2aaSMatthew G. Knepley 
694bc4ae4beSMatthew G. Knepley /*@
695dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
696bc4ae4beSMatthew G. Knepley 
697bc4ae4beSMatthew G. Knepley   Not collective
698bc4ae4beSMatthew G. Knepley 
699bc4ae4beSMatthew G. Knepley   Input Parameter:
700bc4ae4beSMatthew G. Knepley . prob - The PetscDS object
701bc4ae4beSMatthew G. Knepley 
702bc4ae4beSMatthew G. Knepley   Output Parameter:
703bc4ae4beSMatthew G. Knepley . Nf - The number of fields
704bc4ae4beSMatthew G. Knepley 
705bc4ae4beSMatthew G. Knepley   Level: beginner
706bc4ae4beSMatthew G. Knepley 
707dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
708bc4ae4beSMatthew G. Knepley @*/
709d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
710d71ae5a4SJacob Faibussowitsch {
7112764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7122764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
713dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
7142764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7162764a2aaSMatthew G. Knepley }
7172764a2aaSMatthew G. Knepley 
718bc4ae4beSMatthew G. Knepley /*@
719dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
720bc4ae4beSMatthew G. Knepley 
721bc4ae4beSMatthew G. Knepley   Not collective
722bc4ae4beSMatthew G. Knepley 
723bc4ae4beSMatthew G. Knepley   Input Parameter:
724dce8aebaSBarry Smith . prob - The `PetscDS` object
725bc4ae4beSMatthew G. Knepley 
726bc4ae4beSMatthew G. Knepley   Output Parameter:
727bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
728bc4ae4beSMatthew G. Knepley 
729bc4ae4beSMatthew G. Knepley   Level: beginner
730bc4ae4beSMatthew G. Knepley 
731dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
732bc4ae4beSMatthew G. Knepley @*/
733d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
734d71ae5a4SJacob Faibussowitsch {
7352764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7362764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
737dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7382764a2aaSMatthew G. Knepley   *dim = 0;
7399de99aefSMatthew G. Knepley   if (prob->Nf) {
7409de99aefSMatthew G. Knepley     PetscObject  obj;
7419de99aefSMatthew G. Knepley     PetscClassId id;
7429de99aefSMatthew G. Knepley 
7439566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
744665f567fSMatthew G. Knepley     if (obj) {
7459566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7469566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7479566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
74898921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7499de99aefSMatthew G. Knepley     }
750665f567fSMatthew G. Knepley   }
7513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7522764a2aaSMatthew G. Knepley }
7532764a2aaSMatthew G. Knepley 
754bc4ae4beSMatthew G. Knepley /*@
755dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
756a859676bSMatthew G. Knepley 
757a859676bSMatthew G. Knepley   Not collective
758a859676bSMatthew G. Knepley 
759a859676bSMatthew G. Knepley   Input Parameter:
760dce8aebaSBarry Smith . prob - The `PetscDS` object
761a859676bSMatthew G. Knepley 
762a859676bSMatthew G. Knepley   Output Parameter:
763a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
764a859676bSMatthew G. Knepley 
765a859676bSMatthew G. Knepley   Level: beginner
766a859676bSMatthew G. Knepley 
767dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
768a859676bSMatthew G. Knepley @*/
769d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
770d71ae5a4SJacob Faibussowitsch {
771a859676bSMatthew G. Knepley   PetscFunctionBegin;
772a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
773dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
77408401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
775a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
777a859676bSMatthew G. Knepley }
778a859676bSMatthew G. Knepley 
779a859676bSMatthew G. Knepley /*@
780dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
781a859676bSMatthew G. Knepley 
782d083f849SBarry Smith   Logically collective on prob
783a859676bSMatthew G. Knepley 
784a859676bSMatthew G. Knepley   Input Parameters:
785dce8aebaSBarry Smith + prob - The `PetscDS` object
786a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
787a859676bSMatthew G. Knepley 
788a859676bSMatthew G. Knepley   Level: beginner
789a859676bSMatthew G. Knepley 
790dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
791a859676bSMatthew G. Knepley @*/
792d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
793d71ae5a4SJacob Faibussowitsch {
794a859676bSMatthew G. Knepley   PetscFunctionBegin;
795a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
79663a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
797a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
7983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
799a859676bSMatthew G. Knepley }
800a859676bSMatthew G. Knepley 
801a859676bSMatthew G. Knepley /*@
80212fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
80312fc5b22SMatthew G. Knepley 
80412fc5b22SMatthew G. Knepley   Not collective
80512fc5b22SMatthew G. Knepley 
80612fc5b22SMatthew G. Knepley   Input Parameter:
80712fc5b22SMatthew G. Knepley . prob - The `PetscDS` object
80812fc5b22SMatthew G. Knepley 
80912fc5b22SMatthew G. Knepley   Output Parameter:
81012fc5b22SMatthew G. Knepley . forceQuad - The flag
81112fc5b22SMatthew G. Knepley 
81212fc5b22SMatthew G. Knepley   Level: intermediate
81312fc5b22SMatthew G. Knepley 
81412fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
81512fc5b22SMatthew G. Knepley @*/
81612fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
81712fc5b22SMatthew G. Knepley {
81812fc5b22SMatthew G. Knepley   PetscFunctionBegin;
81912fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
82012fc5b22SMatthew G. Knepley   PetscValidIntPointer(forceQuad, 2);
82112fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
82212fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
82312fc5b22SMatthew G. Knepley }
82412fc5b22SMatthew G. Knepley 
82512fc5b22SMatthew G. Knepley /*@
82612fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
82712fc5b22SMatthew G. Knepley 
82812fc5b22SMatthew G. Knepley   Logically collective on ds
82912fc5b22SMatthew G. Knepley 
83012fc5b22SMatthew G. Knepley   Input Parameters:
83112fc5b22SMatthew G. Knepley + ds - The `PetscDS` object
83212fc5b22SMatthew G. Knepley - forceQuad - The flag
83312fc5b22SMatthew G. Knepley 
83412fc5b22SMatthew G. Knepley   Level: intermediate
83512fc5b22SMatthew G. Knepley 
83612fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
83712fc5b22SMatthew G. Knepley @*/
83812fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
83912fc5b22SMatthew G. Knepley {
84012fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84112fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
84212fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
84312fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
84412fc5b22SMatthew G. Knepley }
84512fc5b22SMatthew G. Knepley 
84612fc5b22SMatthew G. Knepley /*@
847dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8488edf6225SMatthew G. Knepley 
8498edf6225SMatthew G. Knepley   Not collective
8508edf6225SMatthew G. Knepley 
8518edf6225SMatthew G. Knepley   Input Parameter:
852dce8aebaSBarry Smith . ds - The `PetscDS` object
8538edf6225SMatthew G. Knepley 
8548edf6225SMatthew G. Knepley   Output Parameter:
8555fedec97SMatthew G. Knepley . isCohesive - The flag
8568edf6225SMatthew G. Knepley 
8578edf6225SMatthew G. Knepley   Level: developer
8588edf6225SMatthew G. Knepley 
859dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8608edf6225SMatthew G. Knepley @*/
861d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
862d71ae5a4SJacob Faibussowitsch {
8638edf6225SMatthew G. Knepley   PetscFunctionBegin;
8645fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
865dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8665fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8688edf6225SMatthew G. Knepley }
8698edf6225SMatthew G. Knepley 
8708edf6225SMatthew G. Knepley /*@
8715fedec97SMatthew G. Knepley   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
8725fedec97SMatthew G. Knepley 
8735fedec97SMatthew G. Knepley   Not collective
8745fedec97SMatthew G. Knepley 
8755fedec97SMatthew G. Knepley   Input Parameter:
876dce8aebaSBarry Smith . ds - The `PetscDS` object
8775fedec97SMatthew G. Knepley 
8785fedec97SMatthew G. Knepley   Output Parameter:
8795fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8805fedec97SMatthew G. Knepley 
8815fedec97SMatthew G. Knepley   Level: developer
8825fedec97SMatthew G. Knepley 
883dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8845fedec97SMatthew G. Knepley @*/
885d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
886d71ae5a4SJacob Faibussowitsch {
8875fedec97SMatthew G. Knepley   PetscInt f;
8885fedec97SMatthew G. Knepley 
8895fedec97SMatthew G. Knepley   PetscFunctionBegin;
8905fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
891dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
8925fedec97SMatthew G. Knepley   *numCohesive = 0;
8935fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
8943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8955fedec97SMatthew G. Knepley }
8965fedec97SMatthew G. Knepley 
8975fedec97SMatthew G. Knepley /*@
8985fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
8995fedec97SMatthew G. Knepley 
9005fedec97SMatthew G. Knepley   Not collective
9015fedec97SMatthew G. Knepley 
902f1a722f8SMatthew G. Knepley   Input Parameters:
903dce8aebaSBarry Smith + ds - The `PetscDS` object
9045fedec97SMatthew G. Knepley - f  - The field index
9055fedec97SMatthew G. Knepley 
9065fedec97SMatthew G. Knepley   Output Parameter:
9075fedec97SMatthew G. Knepley . isCohesive - The flag
9085fedec97SMatthew G. Knepley 
9095fedec97SMatthew G. Knepley   Level: developer
9105fedec97SMatthew G. Knepley 
911dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9125fedec97SMatthew G. Knepley @*/
913d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
914d71ae5a4SJacob Faibussowitsch {
9155fedec97SMatthew G. Knepley   PetscFunctionBegin;
9165fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
917dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
91863a3b9bcSJacob 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);
9195fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9215fedec97SMatthew G. Knepley }
9225fedec97SMatthew G. Knepley 
9235fedec97SMatthew G. Knepley /*@
9245fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9258edf6225SMatthew G. Knepley 
9268edf6225SMatthew G. Knepley   Not collective
9278edf6225SMatthew G. Knepley 
9288edf6225SMatthew G. Knepley   Input Parameters:
929dce8aebaSBarry Smith + ds - The `PetscDS` object
9305fedec97SMatthew G. Knepley . f  - The field index
9315fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9328edf6225SMatthew G. Knepley 
9338edf6225SMatthew G. Knepley   Level: developer
9348edf6225SMatthew G. Knepley 
935dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9368edf6225SMatthew G. Knepley @*/
937d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
938d71ae5a4SJacob Faibussowitsch {
9395fedec97SMatthew G. Knepley   PetscInt i;
9405fedec97SMatthew G. Knepley 
9418edf6225SMatthew G. Knepley   PetscFunctionBegin;
9425fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
94363a3b9bcSJacob 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);
9445fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9455fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9465fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9488edf6225SMatthew G. Knepley }
9498edf6225SMatthew G. Knepley 
9508edf6225SMatthew G. Knepley /*@
951bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
952bc4ae4beSMatthew G. Knepley 
953bc4ae4beSMatthew G. Knepley   Not collective
954bc4ae4beSMatthew G. Knepley 
955bc4ae4beSMatthew G. Knepley   Input Parameter:
956dce8aebaSBarry Smith . prob - The `PetscDS` object
957bc4ae4beSMatthew G. Knepley 
958bc4ae4beSMatthew G. Knepley   Output Parameter:
959bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
960bc4ae4beSMatthew G. Knepley 
961bc4ae4beSMatthew G. Knepley   Level: beginner
962bc4ae4beSMatthew G. Knepley 
963dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
964bc4ae4beSMatthew G. Knepley @*/
965d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
966d71ae5a4SJacob Faibussowitsch {
9672764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9682764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9699566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
970dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9712764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9732764a2aaSMatthew G. Knepley }
9742764a2aaSMatthew G. Knepley 
975bc4ae4beSMatthew G. Knepley /*@
976bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
977bc4ae4beSMatthew G. Knepley 
978bc4ae4beSMatthew G. Knepley   Not collective
979bc4ae4beSMatthew G. Knepley 
980bc4ae4beSMatthew G. Knepley   Input Parameter:
981dce8aebaSBarry Smith . prob - The `PetscDS` object
982bc4ae4beSMatthew G. Knepley 
983bc4ae4beSMatthew G. Knepley   Output Parameter:
984bc4ae4beSMatthew G. Knepley . dim - The total number of components
985bc4ae4beSMatthew G. Knepley 
986bc4ae4beSMatthew G. Knepley   Level: beginner
987bc4ae4beSMatthew G. Knepley 
988dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
989bc4ae4beSMatthew G. Knepley @*/
990d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
991d71ae5a4SJacob Faibussowitsch {
9922764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9932764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9949566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
995dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
9962764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
9973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9982764a2aaSMatthew G. Knepley }
9992764a2aaSMatthew G. Knepley 
1000bc4ae4beSMatthew G. Knepley /*@
1001bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1002bc4ae4beSMatthew G. Knepley 
1003bc4ae4beSMatthew G. Knepley   Not collective
1004bc4ae4beSMatthew G. Knepley 
1005bc4ae4beSMatthew G. Knepley   Input Parameters:
1006dce8aebaSBarry Smith + prob - The `PetscDS` object
1007bc4ae4beSMatthew G. Knepley - f - The field number
1008bc4ae4beSMatthew G. Knepley 
1009bc4ae4beSMatthew G. Knepley   Output Parameter:
1010bc4ae4beSMatthew G. Knepley . disc - The discretization object
1011bc4ae4beSMatthew G. Knepley 
1012bc4ae4beSMatthew G. Knepley   Level: beginner
1013bc4ae4beSMatthew G. Knepley 
1014dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1015bc4ae4beSMatthew G. Knepley @*/
1016d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1017d71ae5a4SJacob Faibussowitsch {
10186528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10192764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10202764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
102163a3b9bcSJacob 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);
10222764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10242764a2aaSMatthew G. Knepley }
10252764a2aaSMatthew G. Knepley 
1026bc4ae4beSMatthew G. Knepley /*@
1027bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1028bc4ae4beSMatthew G. Knepley 
1029bc4ae4beSMatthew G. Knepley   Not collective
1030bc4ae4beSMatthew G. Knepley 
1031bc4ae4beSMatthew G. Knepley   Input Parameters:
1032dce8aebaSBarry Smith + prob - The `PetscDS` object
1033bc4ae4beSMatthew G. Knepley . f - The field number
1034bc4ae4beSMatthew G. Knepley - disc - The discretization object
1035bc4ae4beSMatthew G. Knepley 
1036bc4ae4beSMatthew G. Knepley   Level: beginner
1037bc4ae4beSMatthew G. Knepley 
1038dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1039bc4ae4beSMatthew G. Knepley @*/
1040d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1041d71ae5a4SJacob Faibussowitsch {
10422764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10432764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1044665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
104563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10469566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10479566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10482764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10499566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1050665f567fSMatthew G. Knepley   if (disc) {
1051249df284SMatthew G. Knepley     PetscClassId id;
1052249df284SMatthew G. Knepley 
10539566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10541cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10559566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10561cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10579566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1058a6cbbb48SMatthew G. Knepley     }
10599566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1060249df284SMatthew G. Knepley   }
10613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10622764a2aaSMatthew G. Knepley }
10632764a2aaSMatthew G. Knepley 
1064bc4ae4beSMatthew G. Knepley /*@
10656528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10666528b96dSMatthew G. Knepley 
10676528b96dSMatthew G. Knepley   Not collective
10686528b96dSMatthew G. Knepley 
10696528b96dSMatthew G. Knepley   Input Parameter:
1070dce8aebaSBarry Smith . ds - The `PetscDS` object
10716528b96dSMatthew G. Knepley 
10726528b96dSMatthew G. Knepley   Output Parameter:
10736528b96dSMatthew G. Knepley . wf - The weak form object
10746528b96dSMatthew G. Knepley 
10756528b96dSMatthew G. Knepley   Level: beginner
10766528b96dSMatthew G. Knepley 
1077dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10786528b96dSMatthew G. Knepley @*/
1079d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1080d71ae5a4SJacob Faibussowitsch {
10816528b96dSMatthew G. Knepley   PetscFunctionBegin;
10826528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10836528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10846528b96dSMatthew G. Knepley   *wf = ds->wf;
10853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10866528b96dSMatthew G. Knepley }
10876528b96dSMatthew G. Knepley 
10886528b96dSMatthew G. Knepley /*@
10896528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10906528b96dSMatthew G. Knepley 
10916528b96dSMatthew G. Knepley   Not collective
10926528b96dSMatthew G. Knepley 
10936528b96dSMatthew G. Knepley   Input Parameters:
1094dce8aebaSBarry Smith + ds - The `PetscDS` object
10956528b96dSMatthew G. Knepley - wf - The weak form object
10966528b96dSMatthew G. Knepley 
10976528b96dSMatthew G. Knepley   Level: beginner
10986528b96dSMatthew G. Knepley 
1099dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11006528b96dSMatthew G. Knepley @*/
1101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1102d71ae5a4SJacob Faibussowitsch {
11036528b96dSMatthew G. Knepley   PetscFunctionBegin;
11046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11056528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11069566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11076528b96dSMatthew G. Knepley   ds->wf = wf;
11089566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11099566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11116528b96dSMatthew G. Knepley }
11126528b96dSMatthew G. Knepley 
11136528b96dSMatthew G. Knepley /*@
1114bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1115bc4ae4beSMatthew G. Knepley 
1116bc4ae4beSMatthew G. Knepley   Not collective
1117bc4ae4beSMatthew G. Knepley 
1118bc4ae4beSMatthew G. Knepley   Input Parameters:
1119dce8aebaSBarry Smith + prob - The `PetscDS` object
1120bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1121bc4ae4beSMatthew G. Knepley 
1122bc4ae4beSMatthew G. Knepley   Level: beginner
1123bc4ae4beSMatthew G. Knepley 
1124dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1125bc4ae4beSMatthew G. Knepley @*/
1126d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1127d71ae5a4SJacob Faibussowitsch {
11282764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11312764a2aaSMatthew G. Knepley }
11322764a2aaSMatthew G. Knepley 
1133249df284SMatthew G. Knepley /*@
1134dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1135083401c6SMatthew G. Knepley 
1136083401c6SMatthew G. Knepley   Not collective
1137083401c6SMatthew G. Knepley 
1138083401c6SMatthew G. Knepley   Input Parameter:
1139dce8aebaSBarry Smith . prob - The `PetscDS` object
1140083401c6SMatthew G. Knepley 
1141083401c6SMatthew G. Knepley   Output Parameter:
1142083401c6SMatthew G. Knepley . q - The quadrature object
1143083401c6SMatthew G. Knepley 
1144083401c6SMatthew G. Knepley   Level: intermediate
1145083401c6SMatthew G. Knepley 
1146dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1147083401c6SMatthew G. Knepley @*/
1148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1149d71ae5a4SJacob Faibussowitsch {
1150083401c6SMatthew G. Knepley   PetscObject  obj;
1151083401c6SMatthew G. Knepley   PetscClassId id;
1152083401c6SMatthew G. Knepley 
1153083401c6SMatthew G. Knepley   PetscFunctionBegin;
1154083401c6SMatthew G. Knepley   *q = NULL;
11553ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11569566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11579566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11589566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11599566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116098921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1162083401c6SMatthew G. Knepley }
1163083401c6SMatthew G. Knepley 
1164083401c6SMatthew G. Knepley /*@
1165dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1166249df284SMatthew G. Knepley 
1167249df284SMatthew G. Knepley   Not collective
1168249df284SMatthew G. Knepley 
1169249df284SMatthew G. Knepley   Input Parameters:
1170dce8aebaSBarry Smith + prob - The `PetscDS` object
1171249df284SMatthew G. Knepley - f - The field number
1172249df284SMatthew G. Knepley 
1173249df284SMatthew G. Knepley   Output Parameter:
1174249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1175249df284SMatthew G. Knepley 
1176249df284SMatthew G. Knepley   Level: developer
1177249df284SMatthew G. Knepley 
1178dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1179249df284SMatthew G. Knepley @*/
1180d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1181d71ae5a4SJacob Faibussowitsch {
1182249df284SMatthew G. Knepley   PetscFunctionBegin;
1183249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1184dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
118563a3b9bcSJacob 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);
1186249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1188249df284SMatthew G. Knepley }
1189249df284SMatthew G. Knepley 
1190249df284SMatthew G. Knepley /*@
1191dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1192249df284SMatthew G. Knepley 
1193249df284SMatthew G. Knepley   Not collective
1194249df284SMatthew G. Knepley 
1195249df284SMatthew G. Knepley   Input Parameters:
1196dce8aebaSBarry Smith + prob - The `PetscDS` object
1197249df284SMatthew G. Knepley . f - The field number
1198249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1199249df284SMatthew G. Knepley 
1200249df284SMatthew G. Knepley   Level: developer
1201249df284SMatthew G. Knepley 
1202dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1203249df284SMatthew G. Knepley @*/
1204d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1205d71ae5a4SJacob Faibussowitsch {
1206249df284SMatthew G. Knepley   PetscFunctionBegin;
1207249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
120863a3b9bcSJacob 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);
1209249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1211249df284SMatthew G. Knepley }
1212249df284SMatthew G. Knepley 
1213f9244615SMatthew G. Knepley /*@
1214f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1215f9244615SMatthew G. Knepley 
1216f9244615SMatthew G. Knepley   Not collective
1217f9244615SMatthew G. Knepley 
1218f9244615SMatthew G. Knepley   Input Parameters:
1219dce8aebaSBarry Smith + ds - The `PetscDS` object
1220f9244615SMatthew G. Knepley - f  - The field number
1221f9244615SMatthew G. Knepley 
1222f9244615SMatthew G. Knepley   Output Parameter:
1223f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1224f9244615SMatthew G. Knepley 
1225f9244615SMatthew G. Knepley   Level: developer
1226f9244615SMatthew G. Knepley 
1227dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1228f9244615SMatthew G. Knepley @*/
1229d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1230d71ae5a4SJacob Faibussowitsch {
1231f9244615SMatthew G. Knepley   PetscFunctionBegin;
1232f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1233dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
123463a3b9bcSJacob 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);
1235f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1237f9244615SMatthew G. Knepley }
1238f9244615SMatthew G. Knepley 
1239f9244615SMatthew G. Knepley /*@
1240f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1241f9244615SMatthew G. Knepley 
1242f9244615SMatthew G. Knepley   Not collective
1243f9244615SMatthew G. Knepley 
1244f9244615SMatthew G. Knepley   Input Parameters:
1245dce8aebaSBarry Smith + ds - The `PetscDS` object
1246f9244615SMatthew G. Knepley . f  - The field number
1247f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1248f9244615SMatthew G. Knepley 
1249f9244615SMatthew G. Knepley   Level: developer
1250f9244615SMatthew G. Knepley 
1251dce8aebaSBarry Smith .seealso: ``PetscDS`, PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1252f9244615SMatthew G. Knepley @*/
1253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1254d71ae5a4SJacob Faibussowitsch {
1255f9244615SMatthew G. Knepley   PetscFunctionBegin;
1256f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
125763a3b9bcSJacob 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);
1258f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1260f9244615SMatthew G. Knepley }
1261f9244615SMatthew G. Knepley 
1262d71ae5a4SJacob 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[]))
1263d71ae5a4SJacob Faibussowitsch {
12646528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
12656528b96dSMatthew G. Knepley   PetscInt        n;
12666528b96dSMatthew G. Knepley 
12672764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12696528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
127063a3b9bcSJacob 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);
12719566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
12726528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
12733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12742764a2aaSMatthew G. Knepley }
12752764a2aaSMatthew G. Knepley 
1276d71ae5a4SJacob 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[]))
1277d71ae5a4SJacob Faibussowitsch {
12782764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12806528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
128163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
12833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12842764a2aaSMatthew G. Knepley }
12852764a2aaSMatthew G. Knepley 
1286194d53e6SMatthew G. Knepley /*@C
1287194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1288194d53e6SMatthew G. Knepley 
1289194d53e6SMatthew G. Knepley   Not collective
1290194d53e6SMatthew G. Knepley 
1291194d53e6SMatthew G. Knepley   Input Parameters:
1292dce8aebaSBarry Smith + ds - The `PetscDS`
1293194d53e6SMatthew G. Knepley - f  - The test field number
1294194d53e6SMatthew G. Knepley 
1295194d53e6SMatthew G. Knepley   Output Parameters:
1296194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1297194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1298194d53e6SMatthew G. Knepley 
1299dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1300dce8aebaSBarry Smith .vb
1301dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1302dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1303dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1304dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1305dce8aebaSBarry Smith .ve
1306194d53e6SMatthew G. Knepley + dim - the spatial dimension
1307194d53e6SMatthew G. Knepley . Nf - the number of fields
1308194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1309194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1310194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1311194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1312194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1313194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1314194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1315194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1316194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1317194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1318194d53e6SMatthew G. Knepley . t - current time
1319194d53e6SMatthew G. Knepley . x - coordinates of the current point
132097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
132197b6e6e8SMatthew G. Knepley . constants - constant parameters
1322194d53e6SMatthew G. Knepley - f0 - output values at the current point
1323194d53e6SMatthew G. Knepley 
1324194d53e6SMatthew G. Knepley   Level: intermediate
1325194d53e6SMatthew G. Knepley 
1326dce8aebaSBarry Smith   Note:
1327dce8aebaSBarry 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)
1328dce8aebaSBarry Smith 
1329dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1330194d53e6SMatthew G. Knepley @*/
1331d71ae5a4SJacob 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[]))
1332d71ae5a4SJacob Faibussowitsch {
13336528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
13346528b96dSMatthew G. Knepley   PetscInt        n0, n1;
13356528b96dSMatthew G. Knepley 
13362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
133863a3b9bcSJacob 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);
13399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13406528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13416528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13432764a2aaSMatthew G. Knepley }
13442764a2aaSMatthew G. Knepley 
1345194d53e6SMatthew G. Knepley /*@C
1346194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1347194d53e6SMatthew G. Knepley 
1348194d53e6SMatthew G. Knepley   Not collective
1349194d53e6SMatthew G. Knepley 
1350194d53e6SMatthew G. Knepley   Input Parameters:
1351dce8aebaSBarry Smith + ds - The `PetscDS`
1352194d53e6SMatthew G. Knepley . f  - The test field number
1353194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1354194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1355194d53e6SMatthew G. Knepley 
1356dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1357dce8aebaSBarry Smith .vb
1358dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1359dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1360dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1361dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1362dce8aebaSBarry Smith .ve
1363194d53e6SMatthew G. Knepley + dim - the spatial dimension
1364194d53e6SMatthew G. Knepley . Nf - the number of fields
1365194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1366194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1367194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1368194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1369194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1370194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1371194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1372194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1373194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1374194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1375194d53e6SMatthew G. Knepley . t - current time
1376194d53e6SMatthew G. Knepley . x - coordinates of the current point
137797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
137897b6e6e8SMatthew G. Knepley . constants - constant parameters
1379194d53e6SMatthew G. Knepley - f0 - output values at the current point
1380194d53e6SMatthew G. Knepley 
1381194d53e6SMatthew G. Knepley   Level: intermediate
1382194d53e6SMatthew G. Knepley 
1383dce8aebaSBarry Smith   Note:
1384dce8aebaSBarry 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)
1385dce8aebaSBarry Smith 
1386dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1387194d53e6SMatthew G. Knepley @*/
1388d71ae5a4SJacob 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[]))
1389d71ae5a4SJacob Faibussowitsch {
13902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1392f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1393f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
139463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
13963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13972764a2aaSMatthew G. Knepley }
13982764a2aaSMatthew G. Knepley 
13993e75805dSMatthew G. Knepley /*@C
1400cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1401cb36c0f9SMatthew G. Knepley 
1402cb36c0f9SMatthew G. Knepley   Not collective
1403cb36c0f9SMatthew G. Knepley 
1404cb36c0f9SMatthew G. Knepley   Input Parameters:
1405dce8aebaSBarry Smith + ds - The `PetscDS`
1406cb36c0f9SMatthew G. Knepley - f  - The test field number
1407cb36c0f9SMatthew G. Knepley 
1408cb36c0f9SMatthew G. Knepley   Output Parameters:
1409cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1410cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1411cb36c0f9SMatthew G. Knepley 
1412dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1413dce8aebaSBarry Smith .vb
1414dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1415dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1416dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1417dce8aebaSBarry Smith     PetscReal t, const PetscReal x[], PetscScalar f0[])
1418dce8aebaSBarry Smith .ve
1419cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1420cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1421cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1422cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1423cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1424cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1425cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1426cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1427cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1428cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1429cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1430cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1431cb36c0f9SMatthew G. Knepley . t - current time
1432cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1433cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1434cb36c0f9SMatthew G. Knepley . constants - constant parameters
1435cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1436cb36c0f9SMatthew G. Knepley 
1437cb36c0f9SMatthew G. Knepley   Level: intermediate
1438cb36c0f9SMatthew G. Knepley 
1439dce8aebaSBarry Smith   Note:
1440dce8aebaSBarry 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)
1441dce8aebaSBarry Smith 
1442dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1443cb36c0f9SMatthew G. Knepley @*/
1444d71ae5a4SJacob 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[]))
1445d71ae5a4SJacob Faibussowitsch {
1446cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1447cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1448cb36c0f9SMatthew G. Knepley 
1449cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1450cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
145163a3b9bcSJacob 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);
14529566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1453cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1454cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1456cb36c0f9SMatthew G. Knepley }
1457cb36c0f9SMatthew G. Knepley 
1458cb36c0f9SMatthew G. Knepley /*@C
1459cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1460cb36c0f9SMatthew G. Knepley 
1461cb36c0f9SMatthew G. Knepley   Not collective
1462cb36c0f9SMatthew G. Knepley 
1463cb36c0f9SMatthew G. Knepley   Input Parameters:
1464dce8aebaSBarry Smith + ds - The `PetscDS`
1465cb36c0f9SMatthew G. Knepley . f  - The test field number
1466cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1467cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1468cb36c0f9SMatthew G. Knepley 
1469dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1470dce8aebaSBarry Smith .vb
1471dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1472dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1473dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1474dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1475dce8aebaSBarry Smith .ve
1476cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1477cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1478cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1479cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1480cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1481cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1482cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1483cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1484cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1485cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1486cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1487cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1488cb36c0f9SMatthew G. Knepley . t - current time
1489cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1490cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1491cb36c0f9SMatthew G. Knepley . constants - constant parameters
1492cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1493cb36c0f9SMatthew G. Knepley 
1494cb36c0f9SMatthew G. Knepley   Level: intermediate
1495cb36c0f9SMatthew G. Knepley 
1496dce8aebaSBarry Smith   Note:
1497dce8aebaSBarry 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)
1498dce8aebaSBarry Smith 
1499dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1500cb36c0f9SMatthew G. Knepley @*/
1501d71ae5a4SJacob 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[]))
1502d71ae5a4SJacob Faibussowitsch {
1503cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1504cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1505cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1506cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
150763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1510cb36c0f9SMatthew G. Knepley }
1511cb36c0f9SMatthew G. Knepley 
1512cb36c0f9SMatthew G. Knepley /*@C
1513dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15143e75805dSMatthew G. Knepley 
15153e75805dSMatthew G. Knepley   Not collective
15163e75805dSMatthew G. Knepley 
15173e75805dSMatthew G. Knepley   Input Parameter:
1518dce8aebaSBarry Smith . prob - The `PetscDS`
15193e75805dSMatthew G. Knepley 
15203e75805dSMatthew G. Knepley   Output Parameter:
15213e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15223e75805dSMatthew G. Knepley 
15233e75805dSMatthew G. Knepley   Level: intermediate
15243e75805dSMatthew G. Knepley 
1525dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15263e75805dSMatthew G. Knepley @*/
1527d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1528d71ae5a4SJacob Faibussowitsch {
15293e75805dSMatthew G. Knepley   PetscFunctionBegin;
15306528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
15323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15333e75805dSMatthew G. Knepley }
15343e75805dSMatthew G. Knepley 
1535194d53e6SMatthew G. Knepley /*@C
1536194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1537194d53e6SMatthew G. Knepley 
1538194d53e6SMatthew G. Knepley   Not collective
1539194d53e6SMatthew G. Knepley 
1540194d53e6SMatthew G. Knepley   Input Parameters:
1541dce8aebaSBarry Smith + ds - The `PetscDS`
1542194d53e6SMatthew G. Knepley . f  - The test field number
1543194d53e6SMatthew G. Knepley - g  - The field number
1544194d53e6SMatthew G. Knepley 
1545194d53e6SMatthew G. Knepley   Output Parameters:
1546194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1547194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1548194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1549194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1550194d53e6SMatthew G. Knepley 
1551dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1552dce8aebaSBarry Smith .vb
1553dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1554dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1555dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1556dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1557dce8aebaSBarry Smith .ve
1558194d53e6SMatthew G. Knepley + dim - the spatial dimension
1559194d53e6SMatthew G. Knepley . Nf - the number of fields
1560194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1561194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1562194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1563194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1564194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1565194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1566194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1567194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1568194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1569194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1570194d53e6SMatthew G. Knepley . t - current time
15712aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1572194d53e6SMatthew G. Knepley . x - coordinates of the current point
157397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
157497b6e6e8SMatthew G. Knepley . constants - constant parameters
1575194d53e6SMatthew G. Knepley - g0 - output values at the current point
1576194d53e6SMatthew G. Knepley 
1577194d53e6SMatthew G. Knepley   Level: intermediate
1578194d53e6SMatthew G. Knepley 
1579dce8aebaSBarry Smith   Note:
1580dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1581dce8aebaSBarry 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
1582dce8aebaSBarry Smith 
1583dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1584194d53e6SMatthew G. Knepley @*/
1585d71ae5a4SJacob 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[]))
1586d71ae5a4SJacob Faibussowitsch {
15876528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
15886528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
15896528b96dSMatthew G. Knepley 
15902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
159263a3b9bcSJacob 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);
159363a3b9bcSJacob 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);
15949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
15956528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
15966528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
15976528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
15986528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
15993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16002764a2aaSMatthew G. Knepley }
16012764a2aaSMatthew G. Knepley 
1602194d53e6SMatthew G. Knepley /*@C
1603194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1604194d53e6SMatthew G. Knepley 
1605194d53e6SMatthew G. Knepley   Not collective
1606194d53e6SMatthew G. Knepley 
1607194d53e6SMatthew G. Knepley   Input Parameters:
1608dce8aebaSBarry Smith + ds - The `PetscDS`
1609194d53e6SMatthew G. Knepley . f  - The test field number
1610194d53e6SMatthew G. Knepley . g  - The field number
1611194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1612194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1613194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1614194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1615194d53e6SMatthew G. Knepley 
1616dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1617dce8aebaSBarry Smith .vb
1618dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1619dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1620dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1621dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1622dce8aebaSBarry Smith .ve
1623194d53e6SMatthew G. Knepley + dim - the spatial dimension
1624194d53e6SMatthew G. Knepley . Nf - the number of fields
1625194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1626194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1627194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1628194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1629194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1630194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1631194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1632194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1633194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1634194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1635194d53e6SMatthew G. Knepley . t - current time
16362aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1637194d53e6SMatthew G. Knepley . x - coordinates of the current point
163897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
163997b6e6e8SMatthew G. Knepley . constants - constant parameters
1640194d53e6SMatthew G. Knepley - g0 - output values at the current point
1641194d53e6SMatthew G. Knepley 
1642194d53e6SMatthew G. Knepley   Level: intermediate
1643194d53e6SMatthew G. Knepley 
1644dce8aebaSBarry Smith   Note:
1645dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1646dce8aebaSBarry 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
1647dce8aebaSBarry Smith 
1648dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1649194d53e6SMatthew G. Knepley @*/
1650d71ae5a4SJacob 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[]))
1651d71ae5a4SJacob Faibussowitsch {
16522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16542764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
16552764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
16562764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
16572764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
165863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
165963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
16609566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
16613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16622764a2aaSMatthew G. Knepley }
16632764a2aaSMatthew G. Knepley 
1664475e0ac9SMatthew G. Knepley /*@C
1665dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
166655c1f793SMatthew G. Knepley 
166755c1f793SMatthew G. Knepley   Not collective
166855c1f793SMatthew G. Knepley 
166955c1f793SMatthew G. Knepley   Input Parameters:
1670dce8aebaSBarry Smith + prob - The `PetscDS`
167155c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
167255c1f793SMatthew G. Knepley 
167355c1f793SMatthew G. Knepley   Level: intermediate
167455c1f793SMatthew G. Knepley 
1675dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
167655c1f793SMatthew G. Knepley @*/
1677d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1678d71ae5a4SJacob Faibussowitsch {
167955c1f793SMatthew G. Knepley   PetscFunctionBegin;
168055c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
168155c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
16823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
168355c1f793SMatthew G. Knepley }
168455c1f793SMatthew G. Knepley 
168555c1f793SMatthew G. Knepley /*@C
1686dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1687475e0ac9SMatthew G. Knepley 
1688475e0ac9SMatthew G. Knepley   Not collective
1689475e0ac9SMatthew G. Knepley 
1690475e0ac9SMatthew G. Knepley   Input Parameter:
1691dce8aebaSBarry Smith . prob - The `PetscDS`
1692475e0ac9SMatthew G. Knepley 
1693475e0ac9SMatthew G. Knepley   Output Parameter:
1694475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1695475e0ac9SMatthew G. Knepley 
1696475e0ac9SMatthew G. Knepley   Level: intermediate
1697475e0ac9SMatthew G. Knepley 
1698dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1699475e0ac9SMatthew G. Knepley @*/
1700d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1701d71ae5a4SJacob Faibussowitsch {
1702475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1704475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17053ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17069566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1708475e0ac9SMatthew G. Knepley }
1709475e0ac9SMatthew G. Knepley 
1710475e0ac9SMatthew G. Knepley /*@C
1711dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1712dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1713475e0ac9SMatthew G. Knepley 
1714475e0ac9SMatthew G. Knepley   Not collective
1715475e0ac9SMatthew G. Knepley 
1716475e0ac9SMatthew G. Knepley   Input Parameters:
1717dce8aebaSBarry Smith + ds - The `PetscDS`
1718475e0ac9SMatthew G. Knepley . f  - The test field number
1719475e0ac9SMatthew G. Knepley - g  - The field number
1720475e0ac9SMatthew G. Knepley 
1721475e0ac9SMatthew G. Knepley   Output Parameters:
1722475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1723475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1724475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1725475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1726475e0ac9SMatthew G. Knepley 
1727dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1728dce8aebaSBarry Smith .vb
1729dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1730dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1731dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1732dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1733dce8aebaSBarry Smith .ve
1734475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1735475e0ac9SMatthew G. Knepley . Nf - the number of fields
1736475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1737475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1738475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1739475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1740475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1741475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1742475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1743475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1744475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1745475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1746475e0ac9SMatthew G. Knepley . t - current time
1747475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1748475e0ac9SMatthew G. Knepley . x - coordinates of the current point
174997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
175097b6e6e8SMatthew G. Knepley . constants - constant parameters
1751475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1752475e0ac9SMatthew G. Knepley 
1753475e0ac9SMatthew G. Knepley   Level: intermediate
1754475e0ac9SMatthew G. Knepley 
1755dce8aebaSBarry Smith   Note:
1756dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1757dce8aebaSBarry 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
1758dce8aebaSBarry Smith 
1759dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1760475e0ac9SMatthew G. Knepley @*/
1761d71ae5a4SJacob 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[]))
1762d71ae5a4SJacob Faibussowitsch {
17636528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17646528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17656528b96dSMatthew G. Knepley 
1766475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
176863a3b9bcSJacob 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);
176963a3b9bcSJacob 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);
17709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17716528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17726528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17736528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17746528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1776475e0ac9SMatthew G. Knepley }
1777475e0ac9SMatthew G. Knepley 
1778475e0ac9SMatthew G. Knepley /*@C
1779dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1780dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1781475e0ac9SMatthew G. Knepley 
1782475e0ac9SMatthew G. Knepley   Not collective
1783475e0ac9SMatthew G. Knepley 
1784475e0ac9SMatthew G. Knepley   Input Parameters:
1785dce8aebaSBarry Smith + ds - The `PetscDS`
1786475e0ac9SMatthew G. Knepley . f  - The test field number
1787475e0ac9SMatthew G. Knepley . g  - The field number
1788475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1789475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1790475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1791475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1792475e0ac9SMatthew G. Knepley 
1793dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1794dce8aebaSBarry Smith .vb
1795dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1796dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1797dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1798dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1799dce8aebaSBarry Smith .ve
1800475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1801475e0ac9SMatthew G. Knepley . Nf - the number of fields
1802475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1803475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1804475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1805475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1806475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1807475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1808475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1809475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1810475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1811475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1812475e0ac9SMatthew G. Knepley . t - current time
1813475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1814475e0ac9SMatthew G. Knepley . x - coordinates of the current point
181597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
181697b6e6e8SMatthew G. Knepley . constants - constant parameters
1817475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1818475e0ac9SMatthew G. Knepley 
1819475e0ac9SMatthew G. Knepley   Level: intermediate
1820475e0ac9SMatthew G. Knepley 
1821dce8aebaSBarry Smith   Note:
1822dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1823dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1824dce8aebaSBarry Smith 
1825dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1826475e0ac9SMatthew G. Knepley @*/
1827d71ae5a4SJacob 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[]))
1828d71ae5a4SJacob Faibussowitsch {
1829475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18306528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1831475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1832475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1833475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1834475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
183563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
183663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18379566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1839475e0ac9SMatthew G. Knepley }
1840475e0ac9SMatthew G. Knepley 
1841b7e05686SMatthew G. Knepley /*@C
1842b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1843b7e05686SMatthew G. Knepley 
1844b7e05686SMatthew G. Knepley   Not collective
1845b7e05686SMatthew G. Knepley 
1846b7e05686SMatthew G. Knepley   Input Parameter:
1847dce8aebaSBarry Smith . ds - The `PetscDS`
1848b7e05686SMatthew G. Knepley 
1849b7e05686SMatthew G. Knepley   Output Parameter:
1850b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1851b7e05686SMatthew G. Knepley 
1852b7e05686SMatthew G. Knepley   Level: intermediate
1853b7e05686SMatthew G. Knepley 
1854dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1855b7e05686SMatthew G. Knepley @*/
1856d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1857d71ae5a4SJacob Faibussowitsch {
1858b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18596528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18609566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
18613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1862b7e05686SMatthew G. Knepley }
1863b7e05686SMatthew G. Knepley 
1864b7e05686SMatthew G. Knepley /*@C
1865b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1866b7e05686SMatthew G. Knepley 
1867b7e05686SMatthew G. Knepley   Not collective
1868b7e05686SMatthew G. Knepley 
1869b7e05686SMatthew G. Knepley   Input Parameters:
1870dce8aebaSBarry Smith + ds - The `PetscDS`
1871b7e05686SMatthew G. Knepley . f  - The test field number
1872b7e05686SMatthew G. Knepley - g  - The field number
1873b7e05686SMatthew G. Knepley 
1874b7e05686SMatthew G. Knepley   Output Parameters:
1875b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1876b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1877b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1878b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1879b7e05686SMatthew G. Knepley 
1880dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
1881dce8aebaSBarry Smith .vb
1882dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1883dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1884dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1885dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1886dce8aebaSBarry Smith .ve
1887b7e05686SMatthew G. Knepley + dim - the spatial dimension
1888b7e05686SMatthew G. Knepley . Nf - the number of fields
1889b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1890b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1891b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1892b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1893b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1894b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1895b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1896b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1897b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1898b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1899b7e05686SMatthew G. Knepley . t - current time
1900b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1901b7e05686SMatthew G. Knepley . x - coordinates of the current point
190297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
190397b6e6e8SMatthew G. Knepley . constants - constant parameters
1904b7e05686SMatthew G. Knepley - g0 - output values at the current point
1905b7e05686SMatthew G. Knepley 
1906b7e05686SMatthew G. Knepley   Level: intermediate
1907b7e05686SMatthew G. Knepley 
1908dce8aebaSBarry Smith   Note:
1909dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1910dce8aebaSBarry 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
1911dce8aebaSBarry Smith 
1912dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1913b7e05686SMatthew G. Knepley @*/
1914d71ae5a4SJacob 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[]))
1915d71ae5a4SJacob Faibussowitsch {
19166528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19176528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19186528b96dSMatthew G. Knepley 
1919b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19206528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
192163a3b9bcSJacob 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);
192263a3b9bcSJacob 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);
19239566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19246528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19256528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19266528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19276528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1929b7e05686SMatthew G. Knepley }
1930b7e05686SMatthew G. Knepley 
1931b7e05686SMatthew G. Knepley /*@C
1932b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1933b7e05686SMatthew G. Knepley 
1934b7e05686SMatthew G. Knepley   Not collective
1935b7e05686SMatthew G. Knepley 
1936b7e05686SMatthew G. Knepley   Input Parameters:
1937dce8aebaSBarry Smith + ds - The `PetscDS`
1938b7e05686SMatthew G. Knepley . f  - The test field number
1939b7e05686SMatthew G. Knepley . g  - The field number
1940b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1941b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1942b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1943b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1944b7e05686SMatthew G. Knepley 
1945dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1946dce8aebaSBarry Smith .vb
1947dce8aebaSBarry Smith    g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1948dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1949dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1950dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1951dce8aebaSBarry Smith .ve
1952b7e05686SMatthew G. Knepley + dim - the spatial dimension
1953b7e05686SMatthew G. Knepley . Nf - the number of fields
1954b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1955b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1956b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1957b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1958b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1959b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1960b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1961b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1962b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1963b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1964b7e05686SMatthew G. Knepley . t - current time
1965b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1966b7e05686SMatthew G. Knepley . x - coordinates of the current point
196797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
196897b6e6e8SMatthew G. Knepley . constants - constant parameters
1969b7e05686SMatthew G. Knepley - g0 - output values at the current point
1970b7e05686SMatthew G. Knepley 
1971b7e05686SMatthew G. Knepley   Level: intermediate
1972b7e05686SMatthew G. Knepley 
1973dce8aebaSBarry Smith   Note:
1974dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1975dce8aebaSBarry 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
1976dce8aebaSBarry Smith 
1977dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1978b7e05686SMatthew G. Knepley @*/
1979d71ae5a4SJacob 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[]))
1980d71ae5a4SJacob Faibussowitsch {
1981b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19826528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1983b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1984b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1985b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1986b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
198763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
198863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1991b7e05686SMatthew G. Knepley }
1992b7e05686SMatthew G. Knepley 
19930c2f2876SMatthew G. Knepley /*@C
19940c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
19950c2f2876SMatthew G. Knepley 
19960c2f2876SMatthew G. Knepley   Not collective
19970c2f2876SMatthew G. Knepley 
19984165533cSJose E. Roman   Input Parameters:
1999dce8aebaSBarry Smith + ds - The `PetscDS` object
20000c2f2876SMatthew G. Knepley - f  - The field number
20010c2f2876SMatthew G. Knepley 
20024165533cSJose E. Roman   Output Parameter:
20030c2f2876SMatthew G. Knepley . r    - Riemann solver
20040c2f2876SMatthew G. Knepley 
20050c2f2876SMatthew G. Knepley   Calling sequence for r:
2006dce8aebaSBarry Smith .vb
2007dce8aebaSBarry Smith   r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2008dce8aebaSBarry Smith .ve
20095db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20105db36cf9SMatthew G. Knepley . Nf   - The number of fields
20115db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20120c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20130c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20140c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20150c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
201697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
201797b6e6e8SMatthew G. Knepley . constants - constant parameters
20180c2f2876SMatthew G. Knepley - ctx  - optional user context
20190c2f2876SMatthew G. Knepley 
20200c2f2876SMatthew G. Knepley   Level: intermediate
20210c2f2876SMatthew G. Knepley 
2022dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20230c2f2876SMatthew G. Knepley @*/
2024d71ae5a4SJacob 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))
2025d71ae5a4SJacob Faibussowitsch {
20266528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20276528b96dSMatthew G. Knepley   PetscInt          n;
20286528b96dSMatthew G. Knepley 
20290c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20306528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20310c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
203263a3b9bcSJacob 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);
20339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20346528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20360c2f2876SMatthew G. Knepley }
20370c2f2876SMatthew G. Knepley 
20380c2f2876SMatthew G. Knepley /*@C
20390c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20400c2f2876SMatthew G. Knepley 
20410c2f2876SMatthew G. Knepley   Not collective
20420c2f2876SMatthew G. Knepley 
20434165533cSJose E. Roman   Input Parameters:
2044dce8aebaSBarry Smith + ds - The `PetscDS` object
20450c2f2876SMatthew G. Knepley . f  - The field number
20460c2f2876SMatthew G. Knepley - r  - Riemann solver
20470c2f2876SMatthew G. Knepley 
20480c2f2876SMatthew G. Knepley   Calling sequence for r:
2049dce8aebaSBarry Smith .vb
2050dce8aebaSBarry Smith    r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2051dce8aebaSBarry Smith .ve
20525db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20535db36cf9SMatthew G. Knepley . Nf   - The number of fields
20545db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20550c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20560c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20570c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20580c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
205997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
206097b6e6e8SMatthew G. Knepley . constants - constant parameters
20610c2f2876SMatthew G. Knepley - ctx  - optional user context
20620c2f2876SMatthew G. Knepley 
20630c2f2876SMatthew G. Knepley   Level: intermediate
20640c2f2876SMatthew G. Knepley 
2065dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
20660c2f2876SMatthew G. Knepley @*/
2067d71ae5a4SJacob 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))
2068d71ae5a4SJacob Faibussowitsch {
20690c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20706528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2071de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
207263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
20743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20750c2f2876SMatthew G. Knepley }
20760c2f2876SMatthew G. Knepley 
207732d2bbc9SMatthew G. Knepley /*@C
207832d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
207932d2bbc9SMatthew G. Knepley 
208032d2bbc9SMatthew G. Knepley   Not collective
208132d2bbc9SMatthew G. Knepley 
208232d2bbc9SMatthew G. Knepley   Input Parameters:
2083dce8aebaSBarry Smith + ds - The `PetscDS`
208432d2bbc9SMatthew G. Knepley - f  - The field number
208532d2bbc9SMatthew G. Knepley 
2086f899ff85SJose E. Roman   Output Parameter:
2087a2b725a8SWilliam Gropp . update - update function
208832d2bbc9SMatthew G. Knepley 
2089dce8aebaSBarry Smith   Calling sequence for the callback update:
2090dce8aebaSBarry Smith .vb
2091dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2092dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2093dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2094dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2095dce8aebaSBarry Smith .ve
209632d2bbc9SMatthew G. Knepley + dim - the spatial dimension
209732d2bbc9SMatthew G. Knepley . Nf - the number of fields
209832d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
209932d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
210032d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
210132d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
210232d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
210332d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
210432d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
210532d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
210632d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
210732d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
210832d2bbc9SMatthew G. Knepley . t - current time
210932d2bbc9SMatthew G. Knepley . x - coordinates of the current point
211032d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
211132d2bbc9SMatthew G. Knepley 
211232d2bbc9SMatthew G. Knepley   Level: intermediate
211332d2bbc9SMatthew G. Knepley 
2114dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
211532d2bbc9SMatthew G. Knepley @*/
2116d71ae5a4SJacob 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[]))
2117d71ae5a4SJacob Faibussowitsch {
211832d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21196528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
212063a3b9bcSJacob 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);
21219371c9d4SSatish Balay   if (update) {
21229371c9d4SSatish Balay     PetscValidPointer(update, 3);
21239371c9d4SSatish Balay     *update = ds->update[f];
21249371c9d4SSatish Balay   }
21253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
212632d2bbc9SMatthew G. Knepley }
212732d2bbc9SMatthew G. Knepley 
212832d2bbc9SMatthew G. Knepley /*@C
21293fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
213032d2bbc9SMatthew G. Knepley 
213132d2bbc9SMatthew G. Knepley   Not collective
213232d2bbc9SMatthew G. Knepley 
213332d2bbc9SMatthew G. Knepley   Input Parameters:
2134dce8aebaSBarry Smith + ds     - The `PetscDS`
213532d2bbc9SMatthew G. Knepley . f      - The field number
213632d2bbc9SMatthew G. Knepley - update - update function
213732d2bbc9SMatthew G. Knepley 
2138dce8aebaSBarry Smith   Calling sequence for the callback update:
2139dce8aebaSBarry Smith .vb
2140dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2141dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2142dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2143dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2144dce8aebaSBarry Smith .ve
214532d2bbc9SMatthew G. Knepley + dim - the spatial dimension
214632d2bbc9SMatthew G. Knepley . Nf - the number of fields
214732d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
214832d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
214932d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
215032d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
215132d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
215232d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
215332d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
215432d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
215532d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
215632d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
215732d2bbc9SMatthew G. Knepley . t - current time
215832d2bbc9SMatthew G. Knepley . x - coordinates of the current point
215932d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
216032d2bbc9SMatthew G. Knepley 
216132d2bbc9SMatthew G. Knepley   Level: intermediate
216232d2bbc9SMatthew G. Knepley 
2163dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
216432d2bbc9SMatthew G. Knepley @*/
2165d71ae5a4SJacob 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[]))
2166d71ae5a4SJacob Faibussowitsch {
216732d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216932d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
217063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21719566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21726528b96dSMatthew G. Knepley   ds->update[f] = update;
21733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217432d2bbc9SMatthew G. Knepley }
217532d2bbc9SMatthew G. Knepley 
2176d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2177d71ae5a4SJacob Faibussowitsch {
21780c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
218063a3b9bcSJacob 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);
21810c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
21823ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
21833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21840c2f2876SMatthew G. Knepley }
21850c2f2876SMatthew G. Knepley 
2186d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2187d71ae5a4SJacob Faibussowitsch {
21880c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
219063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21919566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21926528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
21933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21940c2f2876SMatthew G. Knepley }
21950c2f2876SMatthew G. Knepley 
2196194d53e6SMatthew G. Knepley /*@C
2197194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2198194d53e6SMatthew G. Knepley 
2199194d53e6SMatthew G. Knepley   Not collective
2200194d53e6SMatthew G. Knepley 
2201194d53e6SMatthew G. Knepley   Input Parameters:
22026528b96dSMatthew G. Knepley + ds - The PetscDS
2203194d53e6SMatthew G. Knepley - f  - The test field number
2204194d53e6SMatthew G. Knepley 
2205194d53e6SMatthew G. Knepley   Output Parameters:
2206194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2207194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2208194d53e6SMatthew G. Knepley 
2209dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2210dce8aebaSBarry Smith .vb
2211dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2212dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2213dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2214dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2215dce8aebaSBarry Smith .ve
2216194d53e6SMatthew G. Knepley + dim - the spatial dimension
2217194d53e6SMatthew G. Knepley . Nf - the number of fields
2218194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2219194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2220194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2221194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2222194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2223194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2224194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2225194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2226194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2227194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2228194d53e6SMatthew G. Knepley . t - current time
2229194d53e6SMatthew G. Knepley . x - coordinates of the current point
2230194d53e6SMatthew G. Knepley . n - unit normal at the current point
223197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
223297b6e6e8SMatthew G. Knepley . constants - constant parameters
2233194d53e6SMatthew G. Knepley - f0 - output values at the current point
2234194d53e6SMatthew G. Knepley 
2235194d53e6SMatthew G. Knepley   Level: intermediate
2236194d53e6SMatthew G. Knepley 
2237dce8aebaSBarry Smith   Note:
2238dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2239dce8aebaSBarry 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
2240dce8aebaSBarry Smith 
2241dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2242194d53e6SMatthew G. Knepley @*/
2243d71ae5a4SJacob 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[]))
2244d71ae5a4SJacob Faibussowitsch {
22456528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22466528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22476528b96dSMatthew G. Knepley 
22482764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22496528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225063a3b9bcSJacob 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);
22519566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22526528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22536528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22552764a2aaSMatthew G. Knepley }
22562764a2aaSMatthew G. Knepley 
2257194d53e6SMatthew G. Knepley /*@C
2258194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2259194d53e6SMatthew G. Knepley 
2260194d53e6SMatthew G. Knepley   Not collective
2261194d53e6SMatthew G. Knepley 
2262194d53e6SMatthew G. Knepley   Input Parameters:
2263dce8aebaSBarry Smith + ds - The `PetscDS`
2264194d53e6SMatthew G. Knepley . f  - The test field number
2265194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2266194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2267194d53e6SMatthew G. Knepley 
2268dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2269dce8aebaSBarry Smith .vb
2270dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2271dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2272dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2273dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2274dce8aebaSBarry Smith .ve
2275194d53e6SMatthew G. Knepley + dim - the spatial dimension
2276194d53e6SMatthew G. Knepley . Nf - the number of fields
2277194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2278194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2279194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2280194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2281194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2282194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2283194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2284194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2285194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2286194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2287194d53e6SMatthew G. Knepley . t - current time
2288194d53e6SMatthew G. Knepley . x - coordinates of the current point
2289194d53e6SMatthew G. Knepley . n - unit normal at the current point
229097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
229197b6e6e8SMatthew G. Knepley . constants - constant parameters
2292194d53e6SMatthew G. Knepley - f0 - output values at the current point
2293194d53e6SMatthew G. Knepley 
2294194d53e6SMatthew G. Knepley   Level: intermediate
2295194d53e6SMatthew G. Knepley 
2296dce8aebaSBarry Smith   Note:
2297dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2298dce8aebaSBarry 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
2299dce8aebaSBarry Smith 
2300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2301194d53e6SMatthew G. Knepley @*/
2302d71ae5a4SJacob 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[]))
2303d71ae5a4SJacob Faibussowitsch {
23042764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23056528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
230663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23079566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23092764a2aaSMatthew G. Knepley }
23102764a2aaSMatthew G. Knepley 
231127f02ce8SMatthew G. Knepley /*@
2312dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
231327f02ce8SMatthew G. Knepley 
231427f02ce8SMatthew G. Knepley   Not collective
231527f02ce8SMatthew G. Knepley 
231627f02ce8SMatthew G. Knepley   Input Parameter:
2317dce8aebaSBarry Smith . ds - The `PetscDS`
231827f02ce8SMatthew G. Knepley 
231927f02ce8SMatthew G. Knepley   Output Parameter:
232027f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
232127f02ce8SMatthew G. Knepley 
232227f02ce8SMatthew G. Knepley   Level: intermediate
232327f02ce8SMatthew G. Knepley 
2324dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
232527f02ce8SMatthew G. Knepley @*/
2326d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2327d71ae5a4SJacob Faibussowitsch {
232827f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23296528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23306528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
23319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
233327f02ce8SMatthew G. Knepley }
233427f02ce8SMatthew G. Knepley 
2335194d53e6SMatthew G. Knepley /*@C
2336194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2337194d53e6SMatthew G. Knepley 
2338194d53e6SMatthew G. Knepley   Not collective
2339194d53e6SMatthew G. Knepley 
2340194d53e6SMatthew G. Knepley   Input Parameters:
2341dce8aebaSBarry Smith + ds - The `PetscDS`
2342194d53e6SMatthew G. Knepley . f  - The test field number
2343194d53e6SMatthew G. Knepley - g  - The field number
2344194d53e6SMatthew G. Knepley 
2345194d53e6SMatthew G. Knepley   Output Parameters:
2346194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2347194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2348194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2349194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2350194d53e6SMatthew G. Knepley 
2351dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2352dce8aebaSBarry Smith .vb
2353dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2354dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2355dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2356dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2357dce8aebaSBarry Smith .ve
2358194d53e6SMatthew G. Knepley + dim - the spatial dimension
2359194d53e6SMatthew G. Knepley . Nf - the number of fields
2360194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2361194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2362194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2363194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2364194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2365194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2366194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2367194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2368194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2369194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2370194d53e6SMatthew G. Knepley . t - current time
23712aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2372194d53e6SMatthew G. Knepley . x - coordinates of the current point
2373194d53e6SMatthew G. Knepley . n - normal at the current point
237497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
237597b6e6e8SMatthew G. Knepley . constants - constant parameters
2376194d53e6SMatthew G. Knepley - g0 - output values at the current point
2377194d53e6SMatthew G. Knepley 
2378194d53e6SMatthew G. Knepley   Level: intermediate
2379194d53e6SMatthew G. Knepley 
2380dce8aebaSBarry Smith   Note:
2381dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2382dce8aebaSBarry 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
2383dce8aebaSBarry Smith 
2384dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2385194d53e6SMatthew G. Knepley @*/
2386d71ae5a4SJacob 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[]))
2387d71ae5a4SJacob Faibussowitsch {
23886528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
23896528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
23906528b96dSMatthew G. Knepley 
23912764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23926528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
239363a3b9bcSJacob 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);
239463a3b9bcSJacob 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);
23959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
23966528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
23976528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
23986528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
23996528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24012764a2aaSMatthew G. Knepley }
24022764a2aaSMatthew G. Knepley 
2403194d53e6SMatthew G. Knepley /*@C
2404194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2405194d53e6SMatthew G. Knepley 
2406194d53e6SMatthew G. Knepley   Not collective
2407194d53e6SMatthew G. Knepley 
2408194d53e6SMatthew G. Knepley   Input Parameters:
24096528b96dSMatthew G. Knepley + ds - The PetscDS
2410194d53e6SMatthew G. Knepley . f  - The test field number
2411194d53e6SMatthew G. Knepley . g  - The field number
2412194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2413194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2414194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2415194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2416194d53e6SMatthew G. Knepley 
2417dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2418dce8aebaSBarry Smith .vb
2419dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2420dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2421dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2422dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2423dce8aebaSBarry Smith .ve
2424194d53e6SMatthew G. Knepley + dim - the spatial dimension
2425194d53e6SMatthew G. Knepley . Nf - the number of fields
2426194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2427194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2428194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2429194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2430194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2431194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2432194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2433194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2434194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2435194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2436194d53e6SMatthew G. Knepley . t - current time
24372aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2438194d53e6SMatthew G. Knepley . x - coordinates of the current point
2439194d53e6SMatthew G. Knepley . n - normal at the current point
244097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
244197b6e6e8SMatthew G. Knepley . constants - constant parameters
2442194d53e6SMatthew G. Knepley - g0 - output values at the current point
2443194d53e6SMatthew G. Knepley 
2444194d53e6SMatthew G. Knepley   Level: intermediate
2445194d53e6SMatthew G. Knepley 
2446dce8aebaSBarry Smith   Note:
2447dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2448dce8aebaSBarry 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
2449dce8aebaSBarry Smith 
2450dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2451194d53e6SMatthew G. Knepley @*/
2452d71ae5a4SJacob 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[]))
2453d71ae5a4SJacob Faibussowitsch {
24542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24556528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24562764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24572764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24582764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24592764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
246063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
246163a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24629566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24642764a2aaSMatthew G. Knepley }
24652764a2aaSMatthew G. Knepley 
246627f02ce8SMatthew G. Knepley /*@
246727f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
246827f02ce8SMatthew G. Knepley 
246927f02ce8SMatthew G. Knepley   Not collective
247027f02ce8SMatthew G. Knepley 
247127f02ce8SMatthew G. Knepley   Input Parameter:
2472dce8aebaSBarry Smith . ds - The `PetscDS`
247327f02ce8SMatthew G. Knepley 
247427f02ce8SMatthew G. Knepley   Output Parameter:
247527f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
247627f02ce8SMatthew G. Knepley 
247727f02ce8SMatthew G. Knepley   Level: intermediate
247827f02ce8SMatthew G. Knepley 
2479dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
248027f02ce8SMatthew G. Knepley @*/
2481d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2482d71ae5a4SJacob Faibussowitsch {
248327f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24846528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24856528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
24869566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
24873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
248827f02ce8SMatthew G. Knepley }
248927f02ce8SMatthew G. Knepley 
249027f02ce8SMatthew G. Knepley /*@C
249127f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
249227f02ce8SMatthew G. Knepley 
249327f02ce8SMatthew G. Knepley   Not collective
249427f02ce8SMatthew G. Knepley 
249527f02ce8SMatthew G. Knepley   Input Parameters:
2496dce8aebaSBarry Smith + ds - The `PetscDS`
249727f02ce8SMatthew G. Knepley . f  - The test field number
249827f02ce8SMatthew G. Knepley - g  - The field number
249927f02ce8SMatthew G. Knepley 
250027f02ce8SMatthew G. Knepley   Output Parameters:
250127f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
250227f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
250327f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
250427f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
250527f02ce8SMatthew G. Knepley 
2506dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2507dce8aebaSBarry Smith .vb
2508dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2509dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2510dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2511dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2512dce8aebaSBarry Smith .ve
251327f02ce8SMatthew G. Knepley + dim - the spatial dimension
251427f02ce8SMatthew G. Knepley . Nf - the number of fields
251527f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
251627f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
251727f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
251827f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
251927f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
252027f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
252127f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
252227f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
252327f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
252427f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
252527f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
252627f02ce8SMatthew G. Knepley . t - current time
252727f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
252827f02ce8SMatthew G. Knepley . x - coordinates of the current point
252927f02ce8SMatthew G. Knepley . n - normal at the current point
253027f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
253127f02ce8SMatthew G. Knepley . constants - constant parameters
253227f02ce8SMatthew G. Knepley - g0 - output values at the current point
253327f02ce8SMatthew G. Knepley 
253427f02ce8SMatthew G. Knepley   Level: intermediate
253527f02ce8SMatthew G. Knepley 
2536dce8aebaSBarry Smith   Note:
2537dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2538dce8aebaSBarry 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
2539dce8aebaSBarry Smith 
2540dce8aebaSBarry Smith   Fortran Note:
2541dce8aebaSBarry Smith   This is not yet available in Fortran.
2542dce8aebaSBarry Smith 
2543dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
254427f02ce8SMatthew G. Knepley @*/
2545d71ae5a4SJacob 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[]))
2546d71ae5a4SJacob Faibussowitsch {
25476528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25486528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25496528b96dSMatthew G. Knepley 
255027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25516528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
255263a3b9bcSJacob 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);
255363a3b9bcSJacob 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);
25549566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25556528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25566528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25576528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25586528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
256027f02ce8SMatthew G. Knepley }
256127f02ce8SMatthew G. Knepley 
256227f02ce8SMatthew G. Knepley /*@C
256327f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
256427f02ce8SMatthew G. Knepley 
256527f02ce8SMatthew G. Knepley   Not collective
256627f02ce8SMatthew G. Knepley 
256727f02ce8SMatthew G. Knepley   Input Parameters:
2568dce8aebaSBarry Smith + ds - The `PetscDS`
256927f02ce8SMatthew G. Knepley . f  - The test field number
257027f02ce8SMatthew G. Knepley . g  - The field number
257127f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
257227f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
257327f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
257427f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
257527f02ce8SMatthew G. Knepley 
2576dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2577dce8aebaSBarry Smith .vb
2578dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2579dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2580dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2581dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2582dce8aebaSBarry Smith .ve
258327f02ce8SMatthew G. Knepley + dim - the spatial dimension
258427f02ce8SMatthew G. Knepley . Nf - the number of fields
258527f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
258627f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
258727f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
258827f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
258927f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
259027f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
259127f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
259227f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
259327f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
259427f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
259527f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
259627f02ce8SMatthew G. Knepley . t - current time
259727f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
259827f02ce8SMatthew G. Knepley . x - coordinates of the current point
259927f02ce8SMatthew G. Knepley . n - normal at the current point
260027f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
260127f02ce8SMatthew G. Knepley . constants - constant parameters
260227f02ce8SMatthew G. Knepley - g0 - output values at the current point
260327f02ce8SMatthew G. Knepley 
260427f02ce8SMatthew G. Knepley   Level: intermediate
260527f02ce8SMatthew G. Knepley 
2606dce8aebaSBarry Smith   Note:
2607dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2608dce8aebaSBarry 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
2609dce8aebaSBarry Smith 
2610dce8aebaSBarry Smith   Fortran Note:
2611dce8aebaSBarry Smith   This is not yet available in Fortran.
2612dce8aebaSBarry Smith 
2613dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
261427f02ce8SMatthew G. Knepley @*/
2615d71ae5a4SJacob 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[]))
2616d71ae5a4SJacob Faibussowitsch {
261727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26186528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
261927f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
262027f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
262127f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
262227f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
262363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
262463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262727f02ce8SMatthew G. Knepley }
262827f02ce8SMatthew G. Knepley 
26290d3e9b51SMatthew G. Knepley /*@C
2630c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2631c371a6d1SMatthew G. Knepley 
2632c371a6d1SMatthew G. Knepley   Not collective
2633c371a6d1SMatthew G. Knepley 
2634c371a6d1SMatthew G. Knepley   Input Parameters:
2635c371a6d1SMatthew G. Knepley + prob - The PetscDS
2636c371a6d1SMatthew G. Knepley - f    - The test field number
2637c371a6d1SMatthew G. Knepley 
2638d8d19677SJose E. Roman   Output Parameters:
263995cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
264095cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2641c371a6d1SMatthew G. Knepley 
2642dce8aebaSBarry Smith   Calling sequence for the solution functions:
2643dce8aebaSBarry Smith .vb
2644dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2645dce8aebaSBarry Smith .ve
2646c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2647c371a6d1SMatthew G. Knepley . t - current time
2648c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2649c371a6d1SMatthew G. Knepley . Nc - the number of field components
2650c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2651c371a6d1SMatthew G. Knepley - ctx - a user context
2652c371a6d1SMatthew G. Knepley 
2653c371a6d1SMatthew G. Knepley   Level: intermediate
2654c371a6d1SMatthew G. Knepley 
2655dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2656c371a6d1SMatthew G. Knepley @*/
2657d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2658d71ae5a4SJacob Faibussowitsch {
2659c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2660c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
266163a3b9bcSJacob 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);
26629371c9d4SSatish Balay   if (sol) {
26639371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26649371c9d4SSatish Balay     *sol = prob->exactSol[f];
26659371c9d4SSatish Balay   }
26669371c9d4SSatish Balay   if (ctx) {
26679371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26689371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26699371c9d4SSatish Balay   }
26703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2671c371a6d1SMatthew G. Knepley }
2672c371a6d1SMatthew G. Knepley 
2673c371a6d1SMatthew G. Knepley /*@C
2674578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2675c371a6d1SMatthew G. Knepley 
2676c371a6d1SMatthew G. Knepley   Not collective
2677c371a6d1SMatthew G. Knepley 
2678c371a6d1SMatthew G. Knepley   Input Parameters:
2679dce8aebaSBarry Smith + prob - The `PetscDS`
2680c371a6d1SMatthew G. Knepley . f    - The test field number
268195cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
268295cbbfd3SMatthew G. Knepley - ctx  - solution context or NULL
2683c371a6d1SMatthew G. Knepley 
2684dce8aebaSBarry Smith   Calling sequence for solution functions:
2685dce8aebaSBarry Smith .vb
2686dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2687dce8aebaSBarry Smith .ve
2688c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2689c371a6d1SMatthew G. Knepley . t - current time
2690c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2691c371a6d1SMatthew G. Knepley . Nc - the number of field components
2692c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2693c371a6d1SMatthew G. Knepley - ctx - a user context
2694c371a6d1SMatthew G. Knepley 
2695c371a6d1SMatthew G. Knepley   Level: intermediate
2696c371a6d1SMatthew G. Knepley 
2697dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2698c371a6d1SMatthew G. Knepley @*/
2699d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2700d71ae5a4SJacob Faibussowitsch {
2701c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2702c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
270363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27049566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27059371c9d4SSatish Balay   if (sol) {
27069371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27079371c9d4SSatish Balay     prob->exactSol[f] = sol;
27089371c9d4SSatish Balay   }
27099371c9d4SSatish Balay   if (ctx) {
27109371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27119371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27129371c9d4SSatish Balay   }
27133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2714c371a6d1SMatthew G. Knepley }
2715c371a6d1SMatthew G. Knepley 
27165638fd0eSMatthew G. Knepley /*@C
2717f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2718f2cacb80SMatthew G. Knepley 
2719f2cacb80SMatthew G. Knepley   Not collective
2720f2cacb80SMatthew G. Knepley 
2721f2cacb80SMatthew G. Knepley   Input Parameters:
2722dce8aebaSBarry Smith + prob - The `PetscDS`
2723f2cacb80SMatthew G. Knepley - f    - The test field number
2724f2cacb80SMatthew G. Knepley 
2725d8d19677SJose E. Roman   Output Parameters:
2726f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2727f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2728f2cacb80SMatthew G. Knepley 
2729dce8aebaSBarry Smith   Calling sequence for the solution functions:
2730dce8aebaSBarry Smith .vb
2731dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2732dce8aebaSBarry Smith .ve
2733f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2734f2cacb80SMatthew G. Knepley . t - current time
2735f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2736f2cacb80SMatthew G. Knepley . Nc - the number of field components
2737f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2738f2cacb80SMatthew G. Knepley - ctx - a user context
2739f2cacb80SMatthew G. Knepley 
2740f2cacb80SMatthew G. Knepley   Level: intermediate
2741f2cacb80SMatthew G. Knepley 
2742dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2743f2cacb80SMatthew G. Knepley @*/
2744d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2745d71ae5a4SJacob Faibussowitsch {
2746f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2747f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
274863a3b9bcSJacob 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);
27499371c9d4SSatish Balay   if (sol) {
27509371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27519371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27529371c9d4SSatish Balay   }
27539371c9d4SSatish Balay   if (ctx) {
27549371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27559371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27569371c9d4SSatish Balay   }
27573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2758f2cacb80SMatthew G. Knepley }
2759f2cacb80SMatthew G. Knepley 
2760f2cacb80SMatthew G. Knepley /*@C
2761f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2762f2cacb80SMatthew G. Knepley 
2763f2cacb80SMatthew G. Knepley   Not collective
2764f2cacb80SMatthew G. Knepley 
2765f2cacb80SMatthew G. Knepley   Input Parameters:
2766dce8aebaSBarry Smith + prob - The `PetscDS`
2767f2cacb80SMatthew G. Knepley . f    - The test field number
2768f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
2769f2cacb80SMatthew G. Knepley - ctx  - time derivative of the solution context or NULL
2770f2cacb80SMatthew G. Knepley 
2771dce8aebaSBarry Smith   Calling sequence for solution functions:
2772dce8aebaSBarry Smith .vb
2773dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2774dce8aebaSBarry Smith .ve
2775f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2776f2cacb80SMatthew G. Knepley . t - current time
2777f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2778f2cacb80SMatthew G. Knepley . Nc - the number of field components
2779f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2780f2cacb80SMatthew G. Knepley - ctx - a user context
2781f2cacb80SMatthew G. Knepley 
2782f2cacb80SMatthew G. Knepley   Level: intermediate
2783f2cacb80SMatthew G. Knepley 
2784dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2785f2cacb80SMatthew G. Knepley @*/
2786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2787d71ae5a4SJacob Faibussowitsch {
2788f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2789f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
279063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27919566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27929371c9d4SSatish Balay   if (sol) {
27939371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27949371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
27959371c9d4SSatish Balay   }
27969371c9d4SSatish Balay   if (ctx) {
27979371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27989371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
27999371c9d4SSatish Balay   }
28003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2801f2cacb80SMatthew G. Knepley }
2802f2cacb80SMatthew G. Knepley 
2803f2cacb80SMatthew G. Knepley /*@C
280497b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
280597b6e6e8SMatthew G. Knepley 
280697b6e6e8SMatthew G. Knepley   Not collective
280797b6e6e8SMatthew G. Knepley 
280897b6e6e8SMatthew G. Knepley   Input Parameter:
2809dce8aebaSBarry Smith . prob - The `PetscDS` object
281097b6e6e8SMatthew G. Knepley 
281197b6e6e8SMatthew G. Knepley   Output Parameters:
281297b6e6e8SMatthew G. Knepley + numConstants - The number of constants
281397b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
281497b6e6e8SMatthew G. Knepley 
281597b6e6e8SMatthew G. Knepley   Level: intermediate
281697b6e6e8SMatthew G. Knepley 
2817dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
281897b6e6e8SMatthew G. Knepley @*/
2819d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2820d71ae5a4SJacob Faibussowitsch {
282197b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
282297b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28239371c9d4SSatish Balay   if (numConstants) {
28249371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
28259371c9d4SSatish Balay     *numConstants = prob->numConstants;
28269371c9d4SSatish Balay   }
28279371c9d4SSatish Balay   if (constants) {
28289371c9d4SSatish Balay     PetscValidPointer(constants, 3);
28299371c9d4SSatish Balay     *constants = prob->constants;
28309371c9d4SSatish Balay   }
28313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
283297b6e6e8SMatthew G. Knepley }
283397b6e6e8SMatthew G. Knepley 
28340d3e9b51SMatthew G. Knepley /*@C
283597b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
283697b6e6e8SMatthew G. Knepley 
283797b6e6e8SMatthew G. Knepley   Not collective
283897b6e6e8SMatthew G. Knepley 
283997b6e6e8SMatthew G. Knepley   Input Parameters:
2840dce8aebaSBarry Smith + prob         - The `PetscDS` object
284197b6e6e8SMatthew G. Knepley . numConstants - The number of constants
284297b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
284397b6e6e8SMatthew G. Knepley 
284497b6e6e8SMatthew G. Knepley   Level: intermediate
284597b6e6e8SMatthew G. Knepley 
2846dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
284797b6e6e8SMatthew G. Knepley @*/
2848d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2849d71ae5a4SJacob Faibussowitsch {
285097b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
285197b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285297b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28539566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
285497b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
285597b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28569566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
285720be0f5bSMatthew G. Knepley     } else {
285820be0f5bSMatthew G. Knepley       prob->constants = NULL;
285920be0f5bSMatthew G. Knepley     }
286020be0f5bSMatthew G. Knepley   }
286120be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2862dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
28639566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
286497b6e6e8SMatthew G. Knepley   }
28653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286697b6e6e8SMatthew G. Knepley }
286797b6e6e8SMatthew G. Knepley 
28684cd1e086SMatthew G. Knepley /*@
28694cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28704cd1e086SMatthew G. Knepley 
28714cd1e086SMatthew G. Knepley   Not collective
28724cd1e086SMatthew G. Knepley 
28734cd1e086SMatthew G. Knepley   Input Parameters:
2874dce8aebaSBarry Smith + prob - The `PetscDS` object
28754cd1e086SMatthew G. Knepley - disc - The discretization object
28764cd1e086SMatthew G. Knepley 
28774cd1e086SMatthew G. Knepley   Output Parameter:
28784cd1e086SMatthew G. Knepley . f - The field number
28794cd1e086SMatthew G. Knepley 
28804cd1e086SMatthew G. Knepley   Level: beginner
28814cd1e086SMatthew G. Knepley 
2882dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28834cd1e086SMatthew G. Knepley @*/
2884d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2885d71ae5a4SJacob Faibussowitsch {
28864cd1e086SMatthew G. Knepley   PetscInt g;
28874cd1e086SMatthew G. Knepley 
28884cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28894cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2890dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
28914cd1e086SMatthew G. Knepley   *f = -1;
28929371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28939371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
28949371c9d4SSatish Balay   }
289508401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
28964cd1e086SMatthew G. Knepley   *f = g;
28973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28984cd1e086SMatthew G. Knepley }
28994cd1e086SMatthew G. Knepley 
29004cd1e086SMatthew G. Knepley /*@
29014cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29024cd1e086SMatthew G. Knepley 
29034cd1e086SMatthew G. Knepley   Not collective
29044cd1e086SMatthew G. Knepley 
29054cd1e086SMatthew G. Knepley   Input Parameters:
2906dce8aebaSBarry Smith + prob - The `PetscDS` object
29074cd1e086SMatthew G. Knepley - f - The field number
29084cd1e086SMatthew G. Knepley 
29094cd1e086SMatthew G. Knepley   Output Parameter:
29104cd1e086SMatthew G. Knepley . size - The size
29114cd1e086SMatthew G. Knepley 
29124cd1e086SMatthew G. Knepley   Level: beginner
29134cd1e086SMatthew G. Knepley 
2914dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29154cd1e086SMatthew G. Knepley @*/
2916d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2917d71ae5a4SJacob Faibussowitsch {
29184cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29194cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2920dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
292163a3b9bcSJacob 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);
29229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2923d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29254cd1e086SMatthew G. Knepley }
29264cd1e086SMatthew G. Knepley 
2927bc4ae4beSMatthew G. Knepley /*@
2928bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2929bc4ae4beSMatthew G. Knepley 
2930bc4ae4beSMatthew G. Knepley   Not collective
2931bc4ae4beSMatthew G. Knepley 
2932bc4ae4beSMatthew G. Knepley   Input Parameters:
2933dce8aebaSBarry Smith + prob - The `PetscDS` object
2934bc4ae4beSMatthew G. Knepley - f - The field number
2935bc4ae4beSMatthew G. Knepley 
2936bc4ae4beSMatthew G. Knepley   Output Parameter:
2937bc4ae4beSMatthew G. Knepley . off - The offset
2938bc4ae4beSMatthew G. Knepley 
2939bc4ae4beSMatthew G. Knepley   Level: beginner
2940bc4ae4beSMatthew G. Knepley 
2941dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2942bc4ae4beSMatthew G. Knepley @*/
2943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2944d71ae5a4SJacob Faibussowitsch {
29454cd1e086SMatthew G. Knepley   PetscInt size, g;
29462764a2aaSMatthew G. Knepley 
29472764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29482764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2949dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
295063a3b9bcSJacob 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);
29512764a2aaSMatthew G. Knepley   *off = 0;
29522764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29544cd1e086SMatthew G. Knepley     *off += size;
29552764a2aaSMatthew G. Knepley   }
29563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29572764a2aaSMatthew G. Knepley }
29582764a2aaSMatthew G. Knepley 
2959bc4ae4beSMatthew G. Knepley /*@
29605fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29615fedec97SMatthew G. Knepley 
29625fedec97SMatthew G. Knepley   Not collective
29635fedec97SMatthew G. Knepley 
29645fedec97SMatthew G. Knepley   Input Parameters:
2965dce8aebaSBarry Smith + prob - The `PetscDS` object
29665fedec97SMatthew G. Knepley - f - The field number
29675fedec97SMatthew G. Knepley 
29685fedec97SMatthew G. Knepley   Output Parameter:
29695fedec97SMatthew G. Knepley . off - The offset
29705fedec97SMatthew G. Knepley 
29715fedec97SMatthew G. Knepley   Level: beginner
29725fedec97SMatthew G. Knepley 
2973dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29745fedec97SMatthew G. Knepley @*/
2975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2976d71ae5a4SJacob Faibussowitsch {
29775fedec97SMatthew G. Knepley   PetscInt size, g;
29785fedec97SMatthew G. Knepley 
29795fedec97SMatthew G. Knepley   PetscFunctionBegin;
29805fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2981dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
298263a3b9bcSJacob 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);
29835fedec97SMatthew G. Knepley   *off = 0;
29845fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29855fedec97SMatthew G. Knepley     PetscBool cohesive;
29865fedec97SMatthew G. Knepley 
29879566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29889566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29895fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29905fedec97SMatthew G. Knepley   }
29913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29925fedec97SMatthew G. Knepley }
29935fedec97SMatthew G. Knepley 
29945fedec97SMatthew G. Knepley /*@
299547e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2996bc4ae4beSMatthew G. Knepley 
2997bc4ae4beSMatthew G. Knepley   Not collective
2998bc4ae4beSMatthew G. Knepley 
299947e57110SSander Arens   Input Parameter:
3000dce8aebaSBarry Smith . prob - The `PetscDS` object
3001bc4ae4beSMatthew G. Knepley 
3002bc4ae4beSMatthew G. Knepley   Output Parameter:
300347e57110SSander Arens . dimensions - The number of dimensions
3004bc4ae4beSMatthew G. Knepley 
3005bc4ae4beSMatthew G. Knepley   Level: beginner
3006bc4ae4beSMatthew G. Knepley 
3007dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3008bc4ae4beSMatthew G. Knepley @*/
3009d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3010d71ae5a4SJacob Faibussowitsch {
30112764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30122764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30139566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
301447e57110SSander Arens   PetscValidPointer(dimensions, 2);
301547e57110SSander Arens   *dimensions = prob->Nb;
30163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30176ce16762SMatthew G. Knepley }
301847e57110SSander Arens 
301947e57110SSander Arens /*@
302047e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
302147e57110SSander Arens 
302247e57110SSander Arens   Not collective
302347e57110SSander Arens 
302447e57110SSander Arens   Input Parameter:
3025dce8aebaSBarry Smith . prob - The `PetscDS` object
302647e57110SSander Arens 
302747e57110SSander Arens   Output Parameter:
302847e57110SSander Arens . components - The number of components
302947e57110SSander Arens 
303047e57110SSander Arens   Level: beginner
303147e57110SSander Arens 
3032dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
303347e57110SSander Arens @*/
3034d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3035d71ae5a4SJacob Faibussowitsch {
303647e57110SSander Arens   PetscFunctionBegin;
303747e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
303947e57110SSander Arens   PetscValidPointer(components, 2);
304047e57110SSander Arens   *components = prob->Nc;
30413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30426ce16762SMatthew G. Knepley }
30436ce16762SMatthew G. Knepley 
30446ce16762SMatthew G. Knepley /*@
30456ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30466ce16762SMatthew G. Knepley 
30476ce16762SMatthew G. Knepley   Not collective
30486ce16762SMatthew G. Knepley 
30496ce16762SMatthew G. Knepley   Input Parameters:
3050dce8aebaSBarry Smith + prob - The `PetscDS` object
30516ce16762SMatthew G. Knepley - f - The field number
30526ce16762SMatthew G. Knepley 
30536ce16762SMatthew G. Knepley   Output Parameter:
30546ce16762SMatthew G. Knepley . off - The offset
30556ce16762SMatthew G. Knepley 
30566ce16762SMatthew G. Knepley   Level: beginner
30576ce16762SMatthew G. Knepley 
3058dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30596ce16762SMatthew G. Knepley @*/
3060d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3061d71ae5a4SJacob Faibussowitsch {
30626ce16762SMatthew G. Knepley   PetscFunctionBegin;
30636ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3064dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
306563a3b9bcSJacob 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);
30669566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
306747e57110SSander Arens   *off = prob->off[f];
30683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30692764a2aaSMatthew G. Knepley }
30702764a2aaSMatthew G. Knepley 
3071194d53e6SMatthew G. Knepley /*@
3072194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3073194d53e6SMatthew G. Knepley 
3074194d53e6SMatthew G. Knepley   Not collective
3075194d53e6SMatthew G. Knepley 
3076194d53e6SMatthew G. Knepley   Input Parameter:
3077dce8aebaSBarry Smith . prob - The `PetscDS` object
3078194d53e6SMatthew G. Knepley 
3079194d53e6SMatthew G. Knepley   Output Parameter:
3080194d53e6SMatthew G. Knepley . offsets - The offsets
3081194d53e6SMatthew G. Knepley 
3082194d53e6SMatthew G. Knepley   Level: beginner
3083194d53e6SMatthew G. Knepley 
3084dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3085194d53e6SMatthew G. Knepley @*/
3086d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3087d71ae5a4SJacob Faibussowitsch {
3088194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3089194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3090194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30919566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3092194d53e6SMatthew G. Knepley   *offsets = prob->off;
30933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3094194d53e6SMatthew G. Knepley }
3095194d53e6SMatthew G. Knepley 
3096194d53e6SMatthew G. Knepley /*@
3097194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3098194d53e6SMatthew G. Knepley 
3099194d53e6SMatthew G. Knepley   Not collective
3100194d53e6SMatthew G. Knepley 
3101194d53e6SMatthew G. Knepley   Input Parameter:
3102dce8aebaSBarry Smith . prob - The `PetscDS` object
3103194d53e6SMatthew G. Knepley 
3104194d53e6SMatthew G. Knepley   Output Parameter:
3105194d53e6SMatthew G. Knepley . offsets - The offsets
3106194d53e6SMatthew G. Knepley 
3107194d53e6SMatthew G. Knepley   Level: beginner
3108194d53e6SMatthew G. Knepley 
3109dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3110194d53e6SMatthew G. Knepley @*/
3111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3112d71ae5a4SJacob Faibussowitsch {
3113194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3114194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3115194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
31169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3117194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3119194d53e6SMatthew G. Knepley }
3120194d53e6SMatthew G. Knepley 
31219ee2af8cSMatthew G. Knepley /*@
31229ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31239ee2af8cSMatthew G. Knepley 
31249ee2af8cSMatthew G. Knepley   Not collective
31259ee2af8cSMatthew G. Knepley 
31269ee2af8cSMatthew G. Knepley   Input Parameters:
3127dce8aebaSBarry Smith + ds - The `PetscDS` object
31289ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31299ee2af8cSMatthew G. Knepley 
31309ee2af8cSMatthew G. Knepley   Output Parameter:
31319ee2af8cSMatthew G. Knepley . offsets - The offsets
31329ee2af8cSMatthew G. Knepley 
31339ee2af8cSMatthew G. Knepley   Level: beginner
31349ee2af8cSMatthew G. Knepley 
3135dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31369ee2af8cSMatthew G. Knepley @*/
3137d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3138d71ae5a4SJacob Faibussowitsch {
31399ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31409ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31419ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
314228b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
314363a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31449566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31459ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31479ee2af8cSMatthew G. Knepley }
31489ee2af8cSMatthew G. Knepley 
31499ee2af8cSMatthew G. Knepley /*@
31509ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31519ee2af8cSMatthew G. Knepley 
31529ee2af8cSMatthew G. Knepley   Not collective
31539ee2af8cSMatthew G. Knepley 
31549ee2af8cSMatthew G. Knepley   Input Parameters:
3155dce8aebaSBarry Smith + ds - The `PetscDS` object
31569ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31579ee2af8cSMatthew G. Knepley 
31589ee2af8cSMatthew G. Knepley   Output Parameter:
31599ee2af8cSMatthew G. Knepley . offsets - The offsets
31609ee2af8cSMatthew G. Knepley 
31619ee2af8cSMatthew G. Knepley   Level: beginner
31629ee2af8cSMatthew G. Knepley 
3163dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31649ee2af8cSMatthew G. Knepley @*/
3165d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3166d71ae5a4SJacob Faibussowitsch {
31679ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31689ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31699ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
317028b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
317163a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31729566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31739ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31759ee2af8cSMatthew G. Knepley }
31769ee2af8cSMatthew G. Knepley 
317768c9edb9SMatthew G. Knepley /*@C
317868c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
317968c9edb9SMatthew G. Knepley 
318068c9edb9SMatthew G. Knepley   Not collective
318168c9edb9SMatthew G. Knepley 
318268c9edb9SMatthew G. Knepley   Input Parameter:
3183dce8aebaSBarry Smith . prob - The `PetscDS` object
318468c9edb9SMatthew G. Knepley 
3185ef0bb6c7SMatthew G. Knepley   Output Parameter:
3186ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
318768c9edb9SMatthew G. Knepley 
318868c9edb9SMatthew G. Knepley   Level: intermediate
318968c9edb9SMatthew G. Knepley 
3190dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
319168c9edb9SMatthew G. Knepley @*/
3192d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3193d71ae5a4SJacob Faibussowitsch {
31942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31952764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3196ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
31979566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3198ef0bb6c7SMatthew G. Knepley   *T = prob->T;
31993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32002764a2aaSMatthew G. Knepley }
32012764a2aaSMatthew G. Knepley 
320268c9edb9SMatthew G. Knepley /*@C
32034d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
320468c9edb9SMatthew G. Knepley 
320568c9edb9SMatthew G. Knepley   Not collective
320668c9edb9SMatthew G. Knepley 
320768c9edb9SMatthew G. Knepley   Input Parameter:
3208dce8aebaSBarry Smith . prob - The `PetscDS` object
320968c9edb9SMatthew G. Knepley 
3210ef0bb6c7SMatthew G. Knepley   Output Parameter:
3211a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
321268c9edb9SMatthew G. Knepley 
321368c9edb9SMatthew G. Knepley   Level: intermediate
321468c9edb9SMatthew G. Knepley 
3215dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
321668c9edb9SMatthew G. Knepley @*/
3217d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3218d71ae5a4SJacob Faibussowitsch {
32192764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32202764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3221ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
32229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3223ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32252764a2aaSMatthew G. Knepley }
32262764a2aaSMatthew G. Knepley 
3227d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3228d71ae5a4SJacob Faibussowitsch {
32292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32302764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32319566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32329371c9d4SSatish Balay   if (u) {
32339371c9d4SSatish Balay     PetscValidPointer(u, 2);
32349371c9d4SSatish Balay     *u = prob->u;
32359371c9d4SSatish Balay   }
32369371c9d4SSatish Balay   if (u_t) {
32379371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
32389371c9d4SSatish Balay     *u_t = prob->u_t;
32399371c9d4SSatish Balay   }
32409371c9d4SSatish Balay   if (u_x) {
32419371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
32429371c9d4SSatish Balay     *u_x = prob->u_x;
32439371c9d4SSatish Balay   }
32443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32452764a2aaSMatthew G. Knepley }
32462764a2aaSMatthew G. Knepley 
3247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3248d71ae5a4SJacob Faibussowitsch {
32492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32502764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32529371c9d4SSatish Balay   if (f0) {
32539371c9d4SSatish Balay     PetscValidPointer(f0, 2);
32549371c9d4SSatish Balay     *f0 = prob->f0;
32559371c9d4SSatish Balay   }
32569371c9d4SSatish Balay   if (f1) {
32579371c9d4SSatish Balay     PetscValidPointer(f1, 3);
32589371c9d4SSatish Balay     *f1 = prob->f1;
32599371c9d4SSatish Balay   }
32609371c9d4SSatish Balay   if (g0) {
32619371c9d4SSatish Balay     PetscValidPointer(g0, 4);
32629371c9d4SSatish Balay     *g0 = prob->g0;
32639371c9d4SSatish Balay   }
32649371c9d4SSatish Balay   if (g1) {
32659371c9d4SSatish Balay     PetscValidPointer(g1, 5);
32669371c9d4SSatish Balay     *g1 = prob->g1;
32679371c9d4SSatish Balay   }
32689371c9d4SSatish Balay   if (g2) {
32699371c9d4SSatish Balay     PetscValidPointer(g2, 6);
32709371c9d4SSatish Balay     *g2 = prob->g2;
32719371c9d4SSatish Balay   }
32729371c9d4SSatish Balay   if (g3) {
32739371c9d4SSatish Balay     PetscValidPointer(g3, 7);
32749371c9d4SSatish Balay     *g3 = prob->g3;
32759371c9d4SSatish Balay   }
32763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32772764a2aaSMatthew G. Knepley }
32782764a2aaSMatthew G. Knepley 
3279d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3280d71ae5a4SJacob Faibussowitsch {
32812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32822764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32839566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32849371c9d4SSatish Balay   if (x) {
32859371c9d4SSatish Balay     PetscValidPointer(x, 2);
32869371c9d4SSatish Balay     *x = prob->x;
32879371c9d4SSatish Balay   }
32889371c9d4SSatish Balay   if (basisReal) {
32899371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
32909371c9d4SSatish Balay     *basisReal = prob->basisReal;
32919371c9d4SSatish Balay   }
32929371c9d4SSatish Balay   if (basisDerReal) {
32939371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
32949371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
32959371c9d4SSatish Balay   }
32969371c9d4SSatish Balay   if (testReal) {
32979371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
32989371c9d4SSatish Balay     *testReal = prob->testReal;
32999371c9d4SSatish Balay   }
33009371c9d4SSatish Balay   if (testDerReal) {
33019371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
33029371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33039371c9d4SSatish Balay   }
33043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33052764a2aaSMatthew G. Knepley }
33062764a2aaSMatthew G. Knepley 
330758ebd649SToby Isaac /*@C
3308dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3309dce8aebaSBarry 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
3310dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
331158ebd649SToby Isaac 
3312783e2ec8SMatthew G. Knepley   Collective on ds
3313783e2ec8SMatthew G. Knepley 
331458ebd649SToby Isaac   Input Parameters:
331558ebd649SToby Isaac + ds       - The PetscDS object
3316dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
331758ebd649SToby Isaac . name     - The BC name
331845480ffeSMatthew G. Knepley . label    - The label defining constrained points
3319dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
332045480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
332158ebd649SToby Isaac . field    - The field to constrain
332245480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
332358ebd649SToby Isaac . comps    - An array of constrained component numbers
332458ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3325a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
332658ebd649SToby Isaac - ctx      - An optional user context for bcFunc
332758ebd649SToby Isaac 
332845480ffeSMatthew G. Knepley   Output Parameters:
332945480ffeSMatthew G. Knepley - bd       - The boundary number
333045480ffeSMatthew G. Knepley 
333158ebd649SToby Isaac   Options Database Keys:
333258ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
333358ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
333458ebd649SToby Isaac 
3335dce8aebaSBarry Smith   Level: developer
3336dce8aebaSBarry Smith 
333756cf3b9cSMatthew G. Knepley   Note:
3338dce8aebaSBarry 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:
333956cf3b9cSMatthew G. Knepley 
334056cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
334156cf3b9cSMatthew G. Knepley 
3342dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3343dce8aebaSBarry Smith .vb
3344dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3345dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3346dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3347dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3348dce8aebaSBarry Smith .ve
334956cf3b9cSMatthew G. Knepley + dim - the spatial dimension
335056cf3b9cSMatthew G. Knepley . Nf - the number of fields
335156cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
335256cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
335356cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
335456cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
335556cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
335656cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
335756cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
335856cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
335956cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
336056cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
336156cf3b9cSMatthew G. Knepley . t - current time
336256cf3b9cSMatthew G. Knepley . x - coordinates of the current point
336356cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
336456cf3b9cSMatthew G. Knepley . constants - constant parameters
336556cf3b9cSMatthew G. Knepley - bcval - output values at the current point
336656cf3b9cSMatthew G. Knepley 
3367dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
336858ebd649SToby Isaac @*/
3369d71ae5a4SJacob 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)
3370d71ae5a4SJacob Faibussowitsch {
337145480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
337245480ffeSMatthew G. Knepley   PetscInt    n    = 0;
337345480ffeSMatthew G. Knepley   const char *lname;
337458ebd649SToby Isaac 
337558ebd649SToby Isaac   PetscFunctionBegin;
337658ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3377783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
337845480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
337945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
338045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
338145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
338245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3383dce9da9cSMatthew 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);
3384d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3385d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3386d57bb9dbSMatthew G. Knepley     PetscInt  c;
3387d57bb9dbSMatthew G. Knepley 
33889566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
338963a3b9bcSJacob 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);
3390d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
33911dca8a05SBarry 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);
3392d57bb9dbSMatthew G. Knepley     }
3393d57bb9dbSMatthew G. Knepley   }
33949566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33959566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33969566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33989566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33999566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34019566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34029566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34039566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3404f971fd6bSMatthew G. Knepley   b->type   = type;
340545480ffeSMatthew G. Knepley   b->label  = label;
340645480ffeSMatthew G. Knepley   b->Nv     = Nv;
340758ebd649SToby Isaac   b->field  = field;
340845480ffeSMatthew G. Knepley   b->Nc     = Nc;
340958ebd649SToby Isaac   b->func   = bcFunc;
341056cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
341158ebd649SToby Isaac   b->ctx    = ctx;
341245480ffeSMatthew G. Knepley   b->next   = NULL;
341345480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
341445480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
341545480ffeSMatthew G. Knepley   while (head) {
341645480ffeSMatthew G. Knepley     if (!head->next) {
341745480ffeSMatthew G. Knepley       head->next = b;
341845480ffeSMatthew G. Knepley       head       = b;
341945480ffeSMatthew G. Knepley     }
342045480ffeSMatthew G. Knepley     head = head->next;
342145480ffeSMatthew G. Knepley     ++n;
342245480ffeSMatthew G. Knepley   }
34239371c9d4SSatish Balay   if (bd) {
34249371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34259371c9d4SSatish Balay     *bd = n;
34269371c9d4SSatish Balay   }
34273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
342845480ffeSMatthew G. Knepley }
342945480ffeSMatthew G. Knepley 
343045480ffeSMatthew G. Knepley /*@C
3431dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3432dce8aebaSBarry 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
3433dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
343445480ffeSMatthew G. Knepley 
343545480ffeSMatthew G. Knepley   Collective on ds
343645480ffeSMatthew G. Knepley 
343745480ffeSMatthew G. Knepley   Input Parameters:
3438dce8aebaSBarry Smith + ds       - The `PetscDS` object
3439dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
344045480ffeSMatthew G. Knepley . name     - The BC name
344145480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3442dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
344345480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
344445480ffeSMatthew G. Knepley . field    - The field to constrain
344545480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
344645480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
344745480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3448a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
344945480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
345045480ffeSMatthew G. Knepley 
345145480ffeSMatthew G. Knepley   Output Parameters:
345245480ffeSMatthew G. Knepley - bd       - The boundary number
345345480ffeSMatthew G. Knepley 
345445480ffeSMatthew G. Knepley   Options Database Keys:
345545480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
345645480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
345745480ffeSMatthew G. Knepley 
3458dce8aebaSBarry Smith   Calling Sequence of bcFunc() and bcFunc_t():
3459dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3460dce8aebaSBarry Smith .vb
3461dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3462dce8aebaSBarry Smith .ve
3463dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3464dce8aebaSBarry Smith .vb
3465dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3466dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3467dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3468dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3469dce8aebaSBarry Smith .ve
347045480ffeSMatthew G. Knepley + dim - the spatial dimension
347145480ffeSMatthew G. Knepley . Nf - the number of fields
347245480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
347345480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
347445480ffeSMatthew G. Knepley . u - each field evaluated at the current point
347545480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
347645480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
347745480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
347845480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
347945480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
348045480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
348145480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
348245480ffeSMatthew G. Knepley . t - current time
348345480ffeSMatthew G. Knepley . x - coordinates of the current point
348445480ffeSMatthew G. Knepley . numConstants - number of constant parameters
348545480ffeSMatthew G. Knepley . constants - constant parameters
348645480ffeSMatthew G. Knepley - bcval - output values at the current point
348745480ffeSMatthew G. Knepley 
348845480ffeSMatthew G. Knepley   Level: developer
348945480ffeSMatthew G. Knepley 
3490dce8aebaSBarry Smith   Note:
3491dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3492dce8aebaSBarry Smith 
3493dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
349445480ffeSMatthew G. Knepley @*/
3495d71ae5a4SJacob 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)
3496d71ae5a4SJacob Faibussowitsch {
349745480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
349845480ffeSMatthew G. Knepley   PetscInt   n    = 0;
349945480ffeSMatthew G. Knepley 
350045480ffeSMatthew G. Knepley   PetscFunctionBegin;
350145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
350245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
350345480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
350445480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
350545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
350645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
350745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35089566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35099566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35139566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35159566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
351745480ffeSMatthew G. Knepley   b->type   = type;
351845480ffeSMatthew G. Knepley   b->label  = NULL;
351945480ffeSMatthew G. Knepley   b->Nv     = Nv;
352045480ffeSMatthew G. Knepley   b->field  = field;
352145480ffeSMatthew G. Knepley   b->Nc     = Nc;
352245480ffeSMatthew G. Knepley   b->func   = bcFunc;
352345480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
352445480ffeSMatthew G. Knepley   b->ctx    = ctx;
352545480ffeSMatthew G. Knepley   b->next   = NULL;
352645480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
352745480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
352845480ffeSMatthew G. Knepley   while (head) {
352945480ffeSMatthew G. Knepley     if (!head->next) {
353045480ffeSMatthew G. Knepley       head->next = b;
353145480ffeSMatthew G. Knepley       head       = b;
353245480ffeSMatthew G. Knepley     }
353345480ffeSMatthew G. Knepley     head = head->next;
353445480ffeSMatthew G. Knepley     ++n;
353545480ffeSMatthew G. Knepley   }
35369371c9d4SSatish Balay   if (bd) {
35379371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35389371c9d4SSatish Balay     *bd = n;
35399371c9d4SSatish Balay   }
35403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354158ebd649SToby Isaac }
354258ebd649SToby Isaac 
3543b67eacb3SMatthew G. Knepley /*@C
3544dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3545dce8aebaSBarry 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
3546dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3547b67eacb3SMatthew G. Knepley 
3548b67eacb3SMatthew G. Knepley   Input Parameters:
3549dce8aebaSBarry Smith + ds       - The `PetscDS` object
3550b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3551dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3552b67eacb3SMatthew G. Knepley . name     - The BC name
355345480ffeSMatthew G. Knepley . label    - The label defining constrained points
3554dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
355545480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3556b67eacb3SMatthew G. Knepley . field    - The field to constrain
355745480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3558b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3559b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3560a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3561b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3562b67eacb3SMatthew G. Knepley 
3563b67eacb3SMatthew G. Knepley   Level: developer
3564b67eacb3SMatthew G. Knepley 
3565dce8aebaSBarry Smith   Note:
3566dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3567dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3568dce8aebaSBarry Smith 
3569dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3570b67eacb3SMatthew G. Knepley @*/
3571d71ae5a4SJacob 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)
3572d71ae5a4SJacob Faibussowitsch {
3573b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3574b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3575b67eacb3SMatthew G. Knepley 
3576b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3577b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3578b67eacb3SMatthew G. Knepley   while (b) {
3579b67eacb3SMatthew G. Knepley     if (n == bd) break;
3580b67eacb3SMatthew G. Knepley     b = b->next;
3581b67eacb3SMatthew G. Knepley     ++n;
3582b67eacb3SMatthew G. Knepley   }
358363a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3584b67eacb3SMatthew G. Knepley   if (name) {
35859566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
35869566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3587b67eacb3SMatthew G. Knepley   }
3588b67eacb3SMatthew G. Knepley   b->type = type;
358945480ffeSMatthew G. Knepley   if (label) {
359045480ffeSMatthew G. Knepley     const char *name;
359145480ffeSMatthew G. Knepley 
359245480ffeSMatthew G. Knepley     b->label = label;
35939566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
35949566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
35959566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
359645480ffeSMatthew G. Knepley   }
359745480ffeSMatthew G. Knepley   if (Nv >= 0) {
359845480ffeSMatthew G. Knepley     b->Nv = Nv;
35999566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36009566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
36019566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
360245480ffeSMatthew G. Knepley   }
360345480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
360445480ffeSMatthew G. Knepley   if (Nc >= 0) {
360545480ffeSMatthew G. Knepley     b->Nc = Nc;
36069566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36079566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36089566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
360945480ffeSMatthew G. Knepley   }
361045480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
361145480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
361245480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3614b67eacb3SMatthew G. Knepley }
3615b67eacb3SMatthew G. Knepley 
361658ebd649SToby Isaac /*@
361758ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
361858ebd649SToby Isaac 
361958ebd649SToby Isaac   Input Parameters:
3620dce8aebaSBarry Smith . ds - The `PetscDS` object
362158ebd649SToby Isaac 
362258ebd649SToby Isaac   Output Parameters:
362358ebd649SToby Isaac . numBd - The number of BC
362458ebd649SToby Isaac 
362558ebd649SToby Isaac   Level: intermediate
362658ebd649SToby Isaac 
3627dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
362858ebd649SToby Isaac @*/
3629d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3630d71ae5a4SJacob Faibussowitsch {
363158ebd649SToby Isaac   DSBoundary b = ds->boundary;
363258ebd649SToby Isaac 
363358ebd649SToby Isaac   PetscFunctionBegin;
363458ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3635dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
363658ebd649SToby Isaac   *numBd = 0;
36379371c9d4SSatish Balay   while (b) {
36389371c9d4SSatish Balay     ++(*numBd);
36399371c9d4SSatish Balay     b = b->next;
36409371c9d4SSatish Balay   }
36413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364258ebd649SToby Isaac }
364358ebd649SToby Isaac 
364458ebd649SToby Isaac /*@C
36459a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
364658ebd649SToby Isaac 
364758ebd649SToby Isaac   Input Parameters:
3648dce8aebaSBarry Smith + ds          - The `PetscDS` object
364958ebd649SToby Isaac - bd          - The BC number
365058ebd649SToby Isaac 
365158ebd649SToby Isaac   Output Parameters:
3652dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3653dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
365458ebd649SToby Isaac . name     - The BC name
365545480ffeSMatthew G. Knepley . label    - The label defining constrained points
3656dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
365745480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
365858ebd649SToby Isaac . field    - The field to constrain
365945480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
366058ebd649SToby Isaac . comps    - An array of constrained component numbers
366158ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3662a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
366358ebd649SToby Isaac - ctx      - An optional user context for bcFunc
366458ebd649SToby Isaac 
366558ebd649SToby Isaac   Options Database Keys:
366658ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
366758ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
366858ebd649SToby Isaac 
366958ebd649SToby Isaac   Level: developer
367058ebd649SToby Isaac 
3671dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
367258ebd649SToby Isaac @*/
3673d71ae5a4SJacob 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)
3674d71ae5a4SJacob Faibussowitsch {
367558ebd649SToby Isaac   DSBoundary b = ds->boundary;
367658ebd649SToby Isaac   PetscInt   n = 0;
367758ebd649SToby Isaac 
367858ebd649SToby Isaac   PetscFunctionBegin;
367958ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
368058ebd649SToby Isaac   while (b) {
368158ebd649SToby Isaac     if (n == bd) break;
368258ebd649SToby Isaac     b = b->next;
368358ebd649SToby Isaac     ++n;
368458ebd649SToby Isaac   }
368563a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
368645480ffeSMatthew G. Knepley   if (wf) {
368745480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
368845480ffeSMatthew G. Knepley     *wf = b->wf;
368945480ffeSMatthew G. Knepley   }
3690f971fd6bSMatthew G. Knepley   if (type) {
369145480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3692f971fd6bSMatthew G. Knepley     *type = b->type;
369358ebd649SToby Isaac   }
369458ebd649SToby Isaac   if (name) {
369545480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
369658ebd649SToby Isaac     *name = b->name;
369758ebd649SToby Isaac   }
369845480ffeSMatthew G. Knepley   if (label) {
369945480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
370045480ffeSMatthew G. Knepley     *label = b->label;
370145480ffeSMatthew G. Knepley   }
370245480ffeSMatthew G. Knepley   if (Nv) {
370345480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
370445480ffeSMatthew G. Knepley     *Nv = b->Nv;
370545480ffeSMatthew G. Knepley   }
370645480ffeSMatthew G. Knepley   if (values) {
370745480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
370845480ffeSMatthew G. Knepley     *values = b->values;
370958ebd649SToby Isaac   }
371058ebd649SToby Isaac   if (field) {
371145480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
371258ebd649SToby Isaac     *field = b->field;
371358ebd649SToby Isaac   }
371445480ffeSMatthew G. Knepley   if (Nc) {
371545480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
371645480ffeSMatthew G. Knepley     *Nc = b->Nc;
371758ebd649SToby Isaac   }
371858ebd649SToby Isaac   if (comps) {
371945480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
372058ebd649SToby Isaac     *comps = b->comps;
372158ebd649SToby Isaac   }
372258ebd649SToby Isaac   if (func) {
372345480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
372458ebd649SToby Isaac     *func = b->func;
372558ebd649SToby Isaac   }
372656cf3b9cSMatthew G. Knepley   if (func_t) {
372745480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
372856cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
372956cf3b9cSMatthew G. Knepley   }
373058ebd649SToby Isaac   if (ctx) {
373145480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
373258ebd649SToby Isaac     *ctx = b->ctx;
373358ebd649SToby Isaac   }
37343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
373558ebd649SToby Isaac }
373658ebd649SToby Isaac 
3737d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3738d71ae5a4SJacob Faibussowitsch {
373945480ffeSMatthew G. Knepley   PetscFunctionBegin;
37409566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37419566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37429566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37439566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37449566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
374545480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
374645480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
374745480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37499566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
375045480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
375145480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37529566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37539566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
375445480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
375545480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
375645480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
37573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375845480ffeSMatthew G. Knepley }
375945480ffeSMatthew G. Knepley 
37609252d075SMatthew G. Knepley /*@
37619252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
37629252d075SMatthew G. Knepley 
37639252d075SMatthew G. Knepley   Not collective
37649252d075SMatthew G. Knepley 
376536951cb5SMatthew G. Knepley   Input Parameters:
3766dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3767dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
376836951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
37699252d075SMatthew G. Knepley 
37709252d075SMatthew G. Knepley   Output Parameter:
3771dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
37729252d075SMatthew G. Knepley 
37739252d075SMatthew G. Knepley   Level: intermediate
37749252d075SMatthew G. Knepley 
3775dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37769252d075SMatthew G. Knepley @*/
3777d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3778d71ae5a4SJacob Faibussowitsch {
377945480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3780dff059c6SToby Isaac 
3781dff059c6SToby Isaac   PetscFunctionBegin;
378236951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
378336951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
37843ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
37859566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
378636951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
378736951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3788dff059c6SToby Isaac     DSBoundary bNew;
378936951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3790dff059c6SToby Isaac 
379136951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
379236951cb5SMatthew G. Knepley       PetscInt f;
379336951cb5SMatthew G. Knepley 
37949371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
37959371c9d4SSatish Balay         if (b->field == fields[f]) break;
379636951cb5SMatthew G. Knepley       if (f == numFields) continue;
379736951cb5SMatthew G. Knepley       fieldNew = f;
379836951cb5SMatthew G. Knepley     }
37999566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
380036951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3801dff059c6SToby Isaac     *lastnext   = bNew;
3802dff059c6SToby Isaac     lastnext    = &(bNew->next);
3803dff059c6SToby Isaac   }
38043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3805dff059c6SToby Isaac }
3806dff059c6SToby Isaac 
38076c1eb96dSMatthew G. Knepley /*@
3808dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
380945480ffeSMatthew G. Knepley 
381045480ffeSMatthew G. Knepley   Not collective
381145480ffeSMatthew G. Knepley 
381245480ffeSMatthew G. Knepley   Input Parameter:
3813dce8aebaSBarry Smith . ds - The `PetscDS` object
381445480ffeSMatthew G. Knepley 
381545480ffeSMatthew G. Knepley   Level: intermediate
381645480ffeSMatthew G. Knepley 
3817dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
381845480ffeSMatthew G. Knepley @*/
3819d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3820d71ae5a4SJacob Faibussowitsch {
382145480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
382245480ffeSMatthew G. Knepley 
382345480ffeSMatthew G. Knepley   PetscFunctionBegin;
382445480ffeSMatthew G. Knepley   while (next) {
382545480ffeSMatthew G. Knepley     DSBoundary b = next;
382645480ffeSMatthew G. Knepley 
382745480ffeSMatthew G. Knepley     next = b->next;
38289566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38299566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38309566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38319566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38329566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38339566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
383445480ffeSMatthew G. Knepley   }
38353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
383645480ffeSMatthew G. Knepley }
383745480ffeSMatthew G. Knepley 
383845480ffeSMatthew G. Knepley /*@
38396c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38406c1eb96dSMatthew G. Knepley 
38416c1eb96dSMatthew G. Knepley   Not collective
38426c1eb96dSMatthew G. Knepley 
3843d8d19677SJose E. Roman   Input Parameters:
3844dce8aebaSBarry Smith + prob - The `PetscDS` object
38456c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38466c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
38476c1eb96dSMatthew G. Knepley 
38486c1eb96dSMatthew G. Knepley   Output Parameter:
3849dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38506c1eb96dSMatthew G. Knepley 
38516c1eb96dSMatthew G. Knepley   Level: intermediate
38526c1eb96dSMatthew G. Knepley 
3853dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38546c1eb96dSMatthew G. Knepley @*/
3855d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3856d71ae5a4SJacob Faibussowitsch {
38576c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
38586c1eb96dSMatthew G. Knepley 
38596c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
38606c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3861dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38626c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38639566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
386545480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
38666c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38676c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
38686c1eb96dSMatthew G. Knepley     PetscObject    disc;
38696c1eb96dSMatthew G. Knepley 
38706c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
38719566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
38729566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
38736c1eb96dSMatthew G. Knepley   }
38743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38756c1eb96dSMatthew G. Knepley }
38766c1eb96dSMatthew G. Knepley 
38776c1eb96dSMatthew G. Knepley /*@
38789252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
38799252d075SMatthew G. Knepley 
38809252d075SMatthew G. Knepley   Not collective
38819252d075SMatthew G. Knepley 
3882d8d19677SJose E. Roman   Input Parameters:
3883dce8aebaSBarry Smith + prob - The `PetscDS` object
38849252d075SMatthew G. Knepley . numFields - Number of new fields
38859252d075SMatthew G. Knepley - fields - Old field number for each new field
38869252d075SMatthew G. Knepley 
38879252d075SMatthew G. Knepley   Output Parameter:
3888dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38899252d075SMatthew G. Knepley 
38909252d075SMatthew G. Knepley   Level: intermediate
38919252d075SMatthew G. Knepley 
3892dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38939252d075SMatthew G. Knepley @*/
3894d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3895d71ae5a4SJacob Faibussowitsch {
38969252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
38979252d075SMatthew G. Knepley 
38989252d075SMatthew G. Knepley   PetscFunctionBegin;
38999252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3900dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
39019252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39029566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39039566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
390463a3b9bcSJacob 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);
39059252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39069252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39079252d075SMatthew G. Knepley     PetscPointFunc   obj;
39089252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39099252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39109252d075SMatthew G. Knepley     PetscRiemannFunc r;
39119252d075SMatthew G. Knepley 
3912c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39139566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39149566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39159566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39169566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39179566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39189566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39199566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39209566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39219252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39229252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39239252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39249252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39259252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39269252d075SMatthew G. Knepley 
3927c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39289566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39299566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39309566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39319566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39329566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39339566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39349252d075SMatthew G. Knepley     }
39359252d075SMatthew G. Knepley   }
39363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39379252d075SMatthew G. Knepley }
39389252d075SMatthew G. Knepley 
3939da51fcedSMatthew G. Knepley /*@
3940dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3941da51fcedSMatthew G. Knepley 
3942da51fcedSMatthew G. Knepley   Not collective
3943da51fcedSMatthew G. Knepley 
3944da51fcedSMatthew G. Knepley   Input Parameter:
3945dce8aebaSBarry Smith . prob - The `PetscDS` object
3946da51fcedSMatthew G. Knepley 
3947da51fcedSMatthew G. Knepley   Output Parameter:
3948dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3949da51fcedSMatthew G. Knepley 
3950da51fcedSMatthew G. Knepley   Level: intermediate
3951da51fcedSMatthew G. Knepley 
3952dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3953da51fcedSMatthew G. Knepley @*/
3954d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3955d71ae5a4SJacob Faibussowitsch {
3956b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
39579252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3958da51fcedSMatthew G. Knepley 
3959da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3960da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3961da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39629566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39639566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
396463a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
39659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
39669566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
39679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
39683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39699252d075SMatthew G. Knepley }
397045480ffeSMatthew G. Knepley 
39719252d075SMatthew G. Knepley /*@
3972dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3973da51fcedSMatthew G. Knepley 
39749252d075SMatthew G. Knepley   Not collective
39759252d075SMatthew G. Knepley 
39769252d075SMatthew G. Knepley   Input Parameter:
3977dce8aebaSBarry Smith . prob - The `PetscDS` object
39789252d075SMatthew G. Knepley 
39799252d075SMatthew G. Knepley   Output Parameter:
3980dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39819252d075SMatthew G. Knepley 
39829252d075SMatthew G. Knepley   Level: intermediate
39839252d075SMatthew G. Knepley 
3984dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39859252d075SMatthew G. Knepley @*/
3986d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3987d71ae5a4SJacob Faibussowitsch {
39889252d075SMatthew G. Knepley   PetscInt           Nc;
39899252d075SMatthew G. Knepley   const PetscScalar *constants;
39909252d075SMatthew G. Knepley 
39919252d075SMatthew G. Knepley   PetscFunctionBegin;
39929252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39939252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39949566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
39959566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
39963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3997da51fcedSMatthew G. Knepley }
3998da51fcedSMatthew G. Knepley 
399945480ffeSMatthew G. Knepley /*@
4000dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
400145480ffeSMatthew G. Knepley 
400245480ffeSMatthew G. Knepley   Not collective
400345480ffeSMatthew G. Knepley 
400445480ffeSMatthew G. Knepley   Input Parameter:
4005dce8aebaSBarry Smith . ds - The `PetscDS` object
400645480ffeSMatthew G. Knepley 
400745480ffeSMatthew G. Knepley   Output Parameter:
4008dce8aebaSBarry Smith . newds - The `PetscDS` copy
400945480ffeSMatthew G. Knepley 
401045480ffeSMatthew G. Knepley   Level: intermediate
401145480ffeSMatthew G. Knepley 
4012dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
401345480ffeSMatthew G. Knepley @*/
4014d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4015d71ae5a4SJacob Faibussowitsch {
401645480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
401745480ffeSMatthew G. Knepley   void                *ctx;
401845480ffeSMatthew G. Knepley   PetscInt             Nf, f;
401945480ffeSMatthew G. Knepley 
402045480ffeSMatthew G. Knepley   PetscFunctionBegin;
402145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
402245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
402445480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40259566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40269566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40279566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40289566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
402945480ffeSMatthew G. Knepley   }
40303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
403145480ffeSMatthew G. Knepley }
403245480ffeSMatthew G. Knepley 
4033d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4034d71ae5a4SJacob Faibussowitsch {
4035df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4036b1353e8eSMatthew G. Knepley 
4037b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4038b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4039b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
40409371c9d4SSatish Balay   if (height == 0) {
40419371c9d4SSatish Balay     *subprob = prob;
40423ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
40439371c9d4SSatish Balay   }
40449566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40459566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
404663a3b9bcSJacob 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);
40479566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4048df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4049b1353e8eSMatthew G. Knepley     PetscInt cdim;
4050b1353e8eSMatthew G. Knepley 
40519566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
40529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
40539566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4054b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4055b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4056b1353e8eSMatthew G. Knepley       PetscObject  obj;
4057b1353e8eSMatthew G. Knepley       PetscClassId id;
4058b1353e8eSMatthew G. Knepley 
40599566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40609566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
40619566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
406263a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
40639566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4064b1353e8eSMatthew G. Knepley     }
4065b1353e8eSMatthew G. Knepley   }
4066df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
40673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4068b1353e8eSMatthew G. Knepley }
4069b1353e8eSMatthew G. Knepley 
4070d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4071d71ae5a4SJacob Faibussowitsch {
4072c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4073c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4074c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4075c7bd5f0bSMatthew G. Knepley 
4076c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4077c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4078665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4079665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
40809566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
408163a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
40829566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4083665f567fSMatthew G. Knepley   if (obj) {
40849566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4085665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4086665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4087665f567fSMatthew G. Knepley   }
40883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4089c7bd5f0bSMatthew G. Knepley }
4090c7bd5f0bSMatthew G. Knepley 
4091d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4092d71ae5a4SJacob Faibussowitsch {
40932764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40949566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
40953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40962764a2aaSMatthew G. Knepley }
40972764a2aaSMatthew G. Knepley 
4098d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4099d71ae5a4SJacob Faibussowitsch {
41002764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41016528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
41026528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
41036528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
41046528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
41053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41062764a2aaSMatthew G. Knepley }
41072764a2aaSMatthew G. Knepley 
41082764a2aaSMatthew G. Knepley /*MC
41092764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
41102764a2aaSMatthew G. Knepley 
41112764a2aaSMatthew G. Knepley   Level: intermediate
41122764a2aaSMatthew G. Knepley 
4113db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
41142764a2aaSMatthew G. Knepley M*/
41152764a2aaSMatthew G. Knepley 
4116d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4117d71ae5a4SJacob Faibussowitsch {
41182764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
41192764a2aaSMatthew G. Knepley 
41202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41224dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
41236528b96dSMatthew G. Knepley   ds->data = b;
41242764a2aaSMatthew G. Knepley 
41259566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
41263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41272764a2aaSMatthew G. Knepley }
4128