xref: /petsc/src/dm/dt/interface/dtds.c (revision dce9da9c925a2faf9bf6503bbfdaef69e3587977)
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));
592764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
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));
892764a2aaSMatthew G. Knepley   if (match) PetscFunctionReturn(0);
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));
1002764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
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;
1282764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
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));
2098e0d8d9cSMatthew G. Knepley       if (b->func) {
2109566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2119566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2129566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2139566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2148e0d8d9cSMatthew G. Knepley       }
2158e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2169566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2179566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2189566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2199566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2208e0d8d9cSMatthew G. Knepley       }
2219566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2229566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
22340967b3bSMatthew G. Knepley     }
2247d8a60eaSMatthew G. Knepley   }
2259566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
22697b6e6e8SMatthew G. Knepley   if (numConstants) {
22763a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2299566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2309566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
23197b6e6e8SMatthew G. Knepley   }
2329566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2339566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2347d8a60eaSMatthew G. Knepley   PetscFunctionReturn(0);
2357d8a60eaSMatthew G. Knepley }
2367d8a60eaSMatthew G. Knepley 
2372764a2aaSMatthew G. Knepley /*@C
238dce8aebaSBarry Smith    PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
239fe2efc57SMark 
240fe2efc57SMark    Collective on PetscDS
241fe2efc57SMark 
242fe2efc57SMark    Input Parameters:
243dce8aebaSBarry Smith +  A - the `PetscDS` object
244736c3998SJose E. Roman .  obj - Optional object
245736c3998SJose E. Roman -  name - command line option
246fe2efc57SMark 
247fe2efc57SMark    Level: intermediate
248dce8aebaSBarry Smith 
249dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
250fe2efc57SMark @*/
251d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
252d71ae5a4SJacob Faibussowitsch {
253fe2efc57SMark   PetscFunctionBegin;
254fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2559566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
256fe2efc57SMark   PetscFunctionReturn(0);
257fe2efc57SMark }
258fe2efc57SMark 
259fe2efc57SMark /*@C
260dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2612764a2aaSMatthew G. Knepley 
262d083f849SBarry Smith   Collective on prob
2632764a2aaSMatthew G. Knepley 
264d8d19677SJose E. Roman   Input Parameters:
265dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2662764a2aaSMatthew G. Knepley - v  - the viewer
2672764a2aaSMatthew G. Knepley 
2682764a2aaSMatthew G. Knepley   Level: developer
2692764a2aaSMatthew G. Knepley 
270dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`
2712764a2aaSMatthew G. Knepley @*/
272d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
273d71ae5a4SJacob Faibussowitsch {
2747d8a60eaSMatthew G. Knepley   PetscBool iascii;
2752764a2aaSMatthew G. Knepley 
2762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2772764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2789566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
279ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2809566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2819566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
282dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2832764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
2842764a2aaSMatthew G. Knepley }
2852764a2aaSMatthew G. Knepley 
2862764a2aaSMatthew G. Knepley /*@
287dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2882764a2aaSMatthew G. Knepley 
289d083f849SBarry Smith   Collective on prob
2902764a2aaSMatthew G. Knepley 
2912764a2aaSMatthew G. Knepley   Input Parameter:
292dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2932764a2aaSMatthew G. Knepley 
294dce8aebaSBarry Smith   Options Database Keys:
295dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
296dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
297147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
298147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
299147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
3002764a2aaSMatthew G. Knepley 
301dce8aebaSBarry Smith   Level: intermediate
3022764a2aaSMatthew G. Knepley 
303dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3042764a2aaSMatthew G. Knepley @*/
305d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
306d71ae5a4SJacob Faibussowitsch {
307f1fd5e65SToby Isaac   DSBoundary  b;
3082764a2aaSMatthew G. Knepley   const char *defaultType;
3092764a2aaSMatthew G. Knepley   char        name[256];
3102764a2aaSMatthew G. Knepley   PetscBool   flg;
3112764a2aaSMatthew G. Knepley 
3122764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3132764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3142764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3152764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3162764a2aaSMatthew G. Knepley   } else {
3172764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3182764a2aaSMatthew G. Knepley   }
3199566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3202764a2aaSMatthew G. Knepley 
321d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
322f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
323f1fd5e65SToby Isaac     char      optname[1024];
324f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
325f1fd5e65SToby Isaac     PetscBool flg;
326f1fd5e65SToby Isaac 
3279566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3289566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3299566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
330f1fd5e65SToby Isaac     if (flg) {
33145480ffeSMatthew G. Knepley       b->Nv = len;
3329566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3339566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3349566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3359566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
336f1fd5e65SToby Isaac     }
337e7b0402cSSander Arens     len = 1024;
3389566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3399566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3409566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
341f1fd5e65SToby Isaac     if (flg) {
34245480ffeSMatthew G. Knepley       b->Nc = len;
3439566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3449566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3459566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
346f1fd5e65SToby Isaac     }
347f1fd5e65SToby Isaac   }
3489566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3492764a2aaSMatthew G. Knepley   if (flg) {
3509566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3512764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3529566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3532764a2aaSMatthew G. Knepley   }
3549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
355dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3562764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
357dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
358d0609cedSBarry Smith   PetscOptionsEnd();
3599566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3602764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
3612764a2aaSMatthew G. Knepley }
3622764a2aaSMatthew G. Knepley 
3632764a2aaSMatthew G. Knepley /*@C
364dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3652764a2aaSMatthew G. Knepley 
366d083f849SBarry Smith   Collective on prob
3672764a2aaSMatthew G. Knepley 
3682764a2aaSMatthew G. Knepley   Input Parameter:
369dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3702764a2aaSMatthew G. Knepley 
3712764a2aaSMatthew G. Knepley   Level: developer
3722764a2aaSMatthew G. Knepley 
373dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3742764a2aaSMatthew G. Knepley @*/
375d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
376d71ae5a4SJacob Faibussowitsch {
3772764a2aaSMatthew G. Knepley   const PetscInt Nf   = prob->Nf;
378f9244615SMatthew G. Knepley   PetscBool      hasH = PETSC_FALSE;
3794bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3802764a2aaSMatthew G. Knepley 
3812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3822764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3832764a2aaSMatthew G. Knepley   if (prob->setup) PetscFunctionReturn(0);
3842764a2aaSMatthew G. Knepley   /* Calculate sizes */
3859566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3869566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
387f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3899566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3909566063dSJacob Faibussowitsch   PetscCall(PetscCalloc6(Nf + 1, &prob->offCohesive[0], Nf + 1, &prob->offCohesive[1], Nf + 1, &prob->offCohesive[2], Nf + 1, &prob->offDerCohesive[0], Nf + 1, &prob->offDerCohesive[1], Nf + 1, &prob->offDerCohesive[2]));
3919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
3922764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
3939de99aefSMatthew G. Knepley     PetscObject     obj;
3949de99aefSMatthew G. Knepley     PetscClassId    id;
395665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
3969de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
3972764a2aaSMatthew G. Knepley 
3989566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
399f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
400665f567fSMatthew G. Knepley     if (!obj) {
401665f567fSMatthew G. Knepley       /* Empty mesh */
402665f567fSMatthew G. Knepley       Nb = Nc    = 0;
403665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
404665f567fSMatthew G. Knepley     } else {
4059566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4069de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4079de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4089de99aefSMatthew G. Knepley 
4099566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
4109566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4119566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4129566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4139566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4149de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4159de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4169de99aefSMatthew G. Knepley 
4179566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4189566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
4199c3cf19fSMatthew G. Knepley         Nb = Nc;
4209566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
4214d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
42263a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
423665f567fSMatthew G. Knepley     }
42447e57110SSander Arens     prob->Nc[f]                    = Nc;
42547e57110SSander Arens     prob->Nb[f]                    = Nb;
426194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
427194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
4289ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
4299ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
4309ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
4319ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
4329ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
4339ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
4349566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
4352764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
4364bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
4372764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
4389c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
4392764a2aaSMatthew G. Knepley     prob->totComp += Nc;
4405fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
4415fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
4422764a2aaSMatthew G. Knepley   }
4439ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
4449ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
4452764a2aaSMatthew G. Knepley   /* Allocate works space */
4465fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
4479566063dSJacob 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));
4489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
4499371c9d4SSatish 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,
4509371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
451dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
4522764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
4532764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
4542764a2aaSMatthew G. Knepley }
4552764a2aaSMatthew G. Knepley 
456d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
457d71ae5a4SJacob Faibussowitsch {
4582764a2aaSMatthew G. Knepley   PetscFunctionBegin;
4599566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
4609566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
4619566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
4629566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
4639566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
4649566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
4659566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
4662764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
4672764a2aaSMatthew G. Knepley }
4682764a2aaSMatthew G. Knepley 
469d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
470d71ae5a4SJacob Faibussowitsch {
471f744cafaSSander Arens   PetscObject          *tmpd;
47234aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
473f9244615SMatthew G. Knepley   PetscInt             *tmpk;
4745fedec97SMatthew G. Knepley   PetscBool            *tmpc;
4756528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
476f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
477f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
4780c2f2876SMatthew G. Knepley   void                **tmpctx;
47934aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
4802764a2aaSMatthew G. Knepley 
4812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
4822764a2aaSMatthew G. Knepley   if (Nf >= NfNew) PetscFunctionReturn(0);
4832764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
4849566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
4859566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
4869371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
4879371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
4889371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
4899371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
4909371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
4919371c9d4SSatish Balay   }
4929371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
4939371c9d4SSatish Balay     tmpd[f] = NULL;
4949371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
4959371c9d4SSatish Balay     tmpk[f] = 1;
4969371c9d4SSatish Balay   }
4979566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
4989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
4992764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5002764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
501249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5025fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
503f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5049566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
50532d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5060c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
50732d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5080c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5099566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
51032d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5110c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5129566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
513c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
51495cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
515f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
516f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
517c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
51895cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
519f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
520f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
5219566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
522c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
52395cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
524f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
525f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
5262764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
5272764a2aaSMatthew G. Knepley }
5282764a2aaSMatthew G. Knepley 
5292764a2aaSMatthew G. Knepley /*@
5302764a2aaSMatthew G. Knepley   PetscDSDestroy - Destroys a PetscDS object
5312764a2aaSMatthew G. Knepley 
532d083f849SBarry Smith   Collective on prob
5332764a2aaSMatthew G. Knepley 
5342764a2aaSMatthew G. Knepley   Input Parameter:
5352764a2aaSMatthew G. Knepley . prob - the PetscDS object to destroy
5362764a2aaSMatthew G. Knepley 
5372764a2aaSMatthew G. Knepley   Level: developer
5382764a2aaSMatthew G. Knepley 
539dce8aebaSBarry Smith .seealso: `PetscDSView()`
5402764a2aaSMatthew G. Knepley @*/
541d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
542d71ae5a4SJacob Faibussowitsch {
5432764a2aaSMatthew G. Knepley   PetscInt f;
5442764a2aaSMatthew G. Knepley 
5452764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5466528b96dSMatthew G. Knepley   if (!*ds) PetscFunctionReturn(0);
5476528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
5482764a2aaSMatthew G. Knepley 
5499371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
5509371c9d4SSatish Balay     *ds = NULL;
5519371c9d4SSatish Balay     PetscFunctionReturn(0);
5529371c9d4SSatish Balay   }
5536528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
5546528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
555df3a45bdSMatthew G. Knepley     PetscInt dim, d;
556df3a45bdSMatthew G. Knepley 
5579566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
5589566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
559df3a45bdSMatthew G. Knepley   }
5609566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
5619566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
56248a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
5639566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
5649566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
5659566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
5669566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
567dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
5689566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
5699566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
5709566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
5712764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
5722764a2aaSMatthew G. Knepley }
5732764a2aaSMatthew G. Knepley 
5742764a2aaSMatthew G. Knepley /*@
575dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
5762764a2aaSMatthew G. Knepley 
577d083f849SBarry Smith   Collective
5782764a2aaSMatthew G. Knepley 
5792764a2aaSMatthew G. Knepley   Input Parameter:
580dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
5812764a2aaSMatthew G. Knepley 
5822764a2aaSMatthew G. Knepley   Output Parameter:
583dce8aebaSBarry Smith . ds   - The `PetscDS` object
5842764a2aaSMatthew G. Knepley 
5852764a2aaSMatthew G. Knepley   Level: beginner
5862764a2aaSMatthew G. Knepley 
587dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
5882764a2aaSMatthew G. Knepley @*/
589d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
590d71ae5a4SJacob Faibussowitsch {
5912764a2aaSMatthew G. Knepley   PetscDS p;
5922764a2aaSMatthew G. Knepley 
5932764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5946528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
5956528b96dSMatthew G. Knepley   *ds = NULL;
5969566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
5972764a2aaSMatthew G. Knepley 
5989566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
5992764a2aaSMatthew G. Knepley 
6002764a2aaSMatthew G. Knepley   p->Nf           = 0;
6012764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
60297b6e6e8SMatthew G. Knepley   p->numConstants = 0;
60397b6e6e8SMatthew G. Knepley   p->constants    = NULL;
604a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
60555c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
6069566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6072764a2aaSMatthew G. Knepley 
6086528b96dSMatthew G. Knepley   *ds = p;
6092764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
6102764a2aaSMatthew G. Knepley }
6112764a2aaSMatthew G. Knepley 
612bc4ae4beSMatthew G. Knepley /*@
613dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
614bc4ae4beSMatthew G. Knepley 
615bc4ae4beSMatthew G. Knepley   Not collective
616bc4ae4beSMatthew G. Knepley 
617bc4ae4beSMatthew G. Knepley   Input Parameter:
618bc4ae4beSMatthew G. Knepley . prob - The PetscDS object
619bc4ae4beSMatthew G. Knepley 
620bc4ae4beSMatthew G. Knepley   Output Parameter:
621bc4ae4beSMatthew G. Knepley . Nf - The number of fields
622bc4ae4beSMatthew G. Knepley 
623bc4ae4beSMatthew G. Knepley   Level: beginner
624bc4ae4beSMatthew G. Knepley 
625dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
626bc4ae4beSMatthew G. Knepley @*/
627d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
628d71ae5a4SJacob Faibussowitsch {
6292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6302764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
631dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
6322764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
6332764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
6342764a2aaSMatthew G. Knepley }
6352764a2aaSMatthew G. Knepley 
636bc4ae4beSMatthew G. Knepley /*@
637dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
638bc4ae4beSMatthew G. Knepley 
639bc4ae4beSMatthew G. Knepley   Not collective
640bc4ae4beSMatthew G. Knepley 
641bc4ae4beSMatthew G. Knepley   Input Parameter:
642dce8aebaSBarry Smith . prob - The `PetscDS` object
643bc4ae4beSMatthew G. Knepley 
644bc4ae4beSMatthew G. Knepley   Output Parameter:
645bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
646bc4ae4beSMatthew G. Knepley 
647bc4ae4beSMatthew G. Knepley   Level: beginner
648bc4ae4beSMatthew G. Knepley 
649dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
650bc4ae4beSMatthew G. Knepley @*/
651d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
652d71ae5a4SJacob Faibussowitsch {
6532764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6542764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
655dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
6562764a2aaSMatthew G. Knepley   *dim = 0;
6579de99aefSMatthew G. Knepley   if (prob->Nf) {
6589de99aefSMatthew G. Knepley     PetscObject  obj;
6599de99aefSMatthew G. Knepley     PetscClassId id;
6609de99aefSMatthew G. Knepley 
6619566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
662665f567fSMatthew G. Knepley     if (obj) {
6639566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
6649566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
6659566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
66698921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
6679de99aefSMatthew G. Knepley     }
668665f567fSMatthew G. Knepley   }
6692764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
6702764a2aaSMatthew G. Knepley }
6712764a2aaSMatthew G. Knepley 
672bc4ae4beSMatthew G. Knepley /*@
673dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
674a859676bSMatthew G. Knepley 
675a859676bSMatthew G. Knepley   Not collective
676a859676bSMatthew G. Knepley 
677a859676bSMatthew G. Knepley   Input Parameter:
678dce8aebaSBarry Smith . prob - The `PetscDS` object
679a859676bSMatthew G. Knepley 
680a859676bSMatthew G. Knepley   Output Parameter:
681a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
682a859676bSMatthew G. Knepley 
683a859676bSMatthew G. Knepley   Level: beginner
684a859676bSMatthew G. Knepley 
685dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
686a859676bSMatthew G. Knepley @*/
687d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
688d71ae5a4SJacob Faibussowitsch {
689a859676bSMatthew G. Knepley   PetscFunctionBegin;
690a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
691dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
69208401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
693a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
694a859676bSMatthew G. Knepley   PetscFunctionReturn(0);
695a859676bSMatthew G. Knepley }
696a859676bSMatthew G. Knepley 
697a859676bSMatthew G. Knepley /*@
698dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
699a859676bSMatthew G. Knepley 
700d083f849SBarry Smith   Logically collective on prob
701a859676bSMatthew G. Knepley 
702a859676bSMatthew G. Knepley   Input Parameters:
703dce8aebaSBarry Smith + prob - The `PetscDS` object
704a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
705a859676bSMatthew G. Knepley 
706a859676bSMatthew G. Knepley   Level: beginner
707a859676bSMatthew G. Knepley 
708dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
709a859676bSMatthew G. Knepley @*/
710d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
711d71ae5a4SJacob Faibussowitsch {
712a859676bSMatthew G. Knepley   PetscFunctionBegin;
713a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
71463a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
715a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
716a859676bSMatthew G. Knepley   PetscFunctionReturn(0);
717a859676bSMatthew G. Knepley }
718a859676bSMatthew G. Knepley 
719a859676bSMatthew G. Knepley /*@
720dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
7218edf6225SMatthew G. Knepley 
7228edf6225SMatthew G. Knepley   Not collective
7238edf6225SMatthew G. Knepley 
7248edf6225SMatthew G. Knepley   Input Parameter:
725dce8aebaSBarry Smith . ds - The `PetscDS` object
7268edf6225SMatthew G. Knepley 
7278edf6225SMatthew G. Knepley   Output Parameter:
7285fedec97SMatthew G. Knepley . isCohesive - The flag
7298edf6225SMatthew G. Knepley 
7308edf6225SMatthew G. Knepley   Level: developer
7318edf6225SMatthew G. Knepley 
732dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
7338edf6225SMatthew G. Knepley @*/
734d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
735d71ae5a4SJacob Faibussowitsch {
7368edf6225SMatthew G. Knepley   PetscFunctionBegin;
7375fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
738dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
7395fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
7408edf6225SMatthew G. Knepley   PetscFunctionReturn(0);
7418edf6225SMatthew G. Knepley }
7428edf6225SMatthew G. Knepley 
7438edf6225SMatthew G. Knepley /*@
7445fedec97SMatthew G. Knepley   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
7455fedec97SMatthew G. Knepley 
7465fedec97SMatthew G. Knepley   Not collective
7475fedec97SMatthew G. Knepley 
7485fedec97SMatthew G. Knepley   Input Parameter:
749dce8aebaSBarry Smith . ds - The `PetscDS` object
7505fedec97SMatthew G. Knepley 
7515fedec97SMatthew G. Knepley   Output Parameter:
7525fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
7535fedec97SMatthew G. Knepley 
7545fedec97SMatthew G. Knepley   Level: developer
7555fedec97SMatthew G. Knepley 
756dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
7575fedec97SMatthew G. Knepley @*/
758d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
759d71ae5a4SJacob Faibussowitsch {
7605fedec97SMatthew G. Knepley   PetscInt f;
7615fedec97SMatthew G. Knepley 
7625fedec97SMatthew G. Knepley   PetscFunctionBegin;
7635fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
764dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
7655fedec97SMatthew G. Knepley   *numCohesive = 0;
7665fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
7675fedec97SMatthew G. Knepley   PetscFunctionReturn(0);
7685fedec97SMatthew G. Knepley }
7695fedec97SMatthew G. Knepley 
7705fedec97SMatthew G. Knepley /*@
7715fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
7725fedec97SMatthew G. Knepley 
7735fedec97SMatthew G. Knepley   Not collective
7745fedec97SMatthew G. Knepley 
775f1a722f8SMatthew G. Knepley   Input Parameters:
776dce8aebaSBarry Smith + ds - The `PetscDS` object
7775fedec97SMatthew G. Knepley - f  - The field index
7785fedec97SMatthew G. Knepley 
7795fedec97SMatthew G. Knepley   Output Parameter:
7805fedec97SMatthew G. Knepley . isCohesive - The flag
7815fedec97SMatthew G. Knepley 
7825fedec97SMatthew G. Knepley   Level: developer
7835fedec97SMatthew G. Knepley 
784dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
7855fedec97SMatthew G. Knepley @*/
786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
787d71ae5a4SJacob Faibussowitsch {
7885fedec97SMatthew G. Knepley   PetscFunctionBegin;
7895fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
790dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
79163a3b9bcSJacob 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);
7925fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
7935fedec97SMatthew G. Knepley   PetscFunctionReturn(0);
7945fedec97SMatthew G. Knepley }
7955fedec97SMatthew G. Knepley 
7965fedec97SMatthew G. Knepley /*@
7975fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
7988edf6225SMatthew G. Knepley 
7998edf6225SMatthew G. Knepley   Not collective
8008edf6225SMatthew G. Knepley 
8018edf6225SMatthew G. Knepley   Input Parameters:
802dce8aebaSBarry Smith + ds - The `PetscDS` object
8035fedec97SMatthew G. Knepley . f  - The field index
8045fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
8058edf6225SMatthew G. Knepley 
8068edf6225SMatthew G. Knepley   Level: developer
8078edf6225SMatthew G. Knepley 
808dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
8098edf6225SMatthew G. Knepley @*/
810d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
811d71ae5a4SJacob Faibussowitsch {
8125fedec97SMatthew G. Knepley   PetscInt i;
8135fedec97SMatthew G. Knepley 
8148edf6225SMatthew G. Knepley   PetscFunctionBegin;
8155fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
81663a3b9bcSJacob 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);
8175fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
8185fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
8195fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
8208edf6225SMatthew G. Knepley   PetscFunctionReturn(0);
8218edf6225SMatthew G. Knepley }
8228edf6225SMatthew G. Knepley 
8238edf6225SMatthew G. Knepley /*@
824bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
825bc4ae4beSMatthew G. Knepley 
826bc4ae4beSMatthew G. Knepley   Not collective
827bc4ae4beSMatthew G. Knepley 
828bc4ae4beSMatthew G. Knepley   Input Parameter:
829dce8aebaSBarry Smith . prob - The `PetscDS` object
830bc4ae4beSMatthew G. Knepley 
831bc4ae4beSMatthew G. Knepley   Output Parameter:
832bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
833bc4ae4beSMatthew G. Knepley 
834bc4ae4beSMatthew G. Knepley   Level: beginner
835bc4ae4beSMatthew G. Knepley 
836dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
837bc4ae4beSMatthew G. Knepley @*/
838d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
839d71ae5a4SJacob Faibussowitsch {
8402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
8412764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
8429566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
843dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
8442764a2aaSMatthew G. Knepley   *dim = prob->totDim;
8452764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
8462764a2aaSMatthew G. Knepley }
8472764a2aaSMatthew G. Knepley 
848bc4ae4beSMatthew G. Knepley /*@
849bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
850bc4ae4beSMatthew G. Knepley 
851bc4ae4beSMatthew G. Knepley   Not collective
852bc4ae4beSMatthew G. Knepley 
853bc4ae4beSMatthew G. Knepley   Input Parameter:
854dce8aebaSBarry Smith . prob - The `PetscDS` object
855bc4ae4beSMatthew G. Knepley 
856bc4ae4beSMatthew G. Knepley   Output Parameter:
857bc4ae4beSMatthew G. Knepley . dim - The total number of components
858bc4ae4beSMatthew G. Knepley 
859bc4ae4beSMatthew G. Knepley   Level: beginner
860bc4ae4beSMatthew G. Knepley 
861dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
862bc4ae4beSMatthew G. Knepley @*/
863d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
864d71ae5a4SJacob Faibussowitsch {
8652764a2aaSMatthew G. Knepley   PetscFunctionBegin;
8662764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
8679566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
868dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
8692764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
8702764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
8712764a2aaSMatthew G. Knepley }
8722764a2aaSMatthew G. Knepley 
873bc4ae4beSMatthew G. Knepley /*@
874bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
875bc4ae4beSMatthew G. Knepley 
876bc4ae4beSMatthew G. Knepley   Not collective
877bc4ae4beSMatthew G. Knepley 
878bc4ae4beSMatthew G. Knepley   Input Parameters:
879dce8aebaSBarry Smith + prob - The `PetscDS` object
880bc4ae4beSMatthew G. Knepley - f - The field number
881bc4ae4beSMatthew G. Knepley 
882bc4ae4beSMatthew G. Knepley   Output Parameter:
883bc4ae4beSMatthew G. Knepley . disc - The discretization object
884bc4ae4beSMatthew G. Knepley 
885bc4ae4beSMatthew G. Knepley   Level: beginner
886bc4ae4beSMatthew G. Knepley 
887dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
888bc4ae4beSMatthew G. Knepley @*/
889d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
890d71ae5a4SJacob Faibussowitsch {
8916528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
8922764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
8932764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
89463a3b9bcSJacob 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);
8952764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
8962764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
8972764a2aaSMatthew G. Knepley }
8982764a2aaSMatthew G. Knepley 
899bc4ae4beSMatthew G. Knepley /*@
900bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
901bc4ae4beSMatthew G. Knepley 
902bc4ae4beSMatthew G. Knepley   Not collective
903bc4ae4beSMatthew G. Knepley 
904bc4ae4beSMatthew G. Knepley   Input Parameters:
905dce8aebaSBarry Smith + prob - The `PetscDS` object
906bc4ae4beSMatthew G. Knepley . f - The field number
907bc4ae4beSMatthew G. Knepley - disc - The discretization object
908bc4ae4beSMatthew G. Knepley 
909bc4ae4beSMatthew G. Knepley   Level: beginner
910bc4ae4beSMatthew G. Knepley 
911dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
912bc4ae4beSMatthew G. Knepley @*/
913d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
914d71ae5a4SJacob Faibussowitsch {
9152764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9162764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
917665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
91863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
9199566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
9209566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
9212764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
9229566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
923665f567fSMatthew G. Knepley   if (disc) {
924249df284SMatthew G. Knepley     PetscClassId id;
925249df284SMatthew G. Knepley 
9269566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
9271cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
9289566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
9291cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
9309566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
931a6cbbb48SMatthew G. Knepley     }
9329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
933249df284SMatthew G. Knepley   }
9342764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
9352764a2aaSMatthew G. Knepley }
9362764a2aaSMatthew G. Knepley 
937bc4ae4beSMatthew G. Knepley /*@
9386528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
9396528b96dSMatthew G. Knepley 
9406528b96dSMatthew G. Knepley   Not collective
9416528b96dSMatthew G. Knepley 
9426528b96dSMatthew G. Knepley   Input Parameter:
943dce8aebaSBarry Smith . ds - The `PetscDS` object
9446528b96dSMatthew G. Knepley 
9456528b96dSMatthew G. Knepley   Output Parameter:
9466528b96dSMatthew G. Knepley . wf - The weak form object
9476528b96dSMatthew G. Knepley 
9486528b96dSMatthew G. Knepley   Level: beginner
9496528b96dSMatthew G. Knepley 
950dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
9516528b96dSMatthew G. Knepley @*/
952d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
953d71ae5a4SJacob Faibussowitsch {
9546528b96dSMatthew G. Knepley   PetscFunctionBegin;
9556528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9566528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
9576528b96dSMatthew G. Knepley   *wf = ds->wf;
9586528b96dSMatthew G. Knepley   PetscFunctionReturn(0);
9596528b96dSMatthew G. Knepley }
9606528b96dSMatthew G. Knepley 
9616528b96dSMatthew G. Knepley /*@
9626528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
9636528b96dSMatthew G. Knepley 
9646528b96dSMatthew G. Knepley   Not collective
9656528b96dSMatthew G. Knepley 
9666528b96dSMatthew G. Knepley   Input Parameters:
967dce8aebaSBarry Smith + ds - The `PetscDS` object
9686528b96dSMatthew G. Knepley - wf - The weak form object
9696528b96dSMatthew G. Knepley 
9706528b96dSMatthew G. Knepley   Level: beginner
9716528b96dSMatthew G. Knepley 
972dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
9736528b96dSMatthew G. Knepley @*/
974d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
975d71ae5a4SJacob Faibussowitsch {
9766528b96dSMatthew G. Knepley   PetscFunctionBegin;
9776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
9799566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
9806528b96dSMatthew G. Knepley   ds->wf = wf;
9819566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
9829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
9836528b96dSMatthew G. Knepley   PetscFunctionReturn(0);
9846528b96dSMatthew G. Knepley }
9856528b96dSMatthew G. Knepley 
9866528b96dSMatthew G. Knepley /*@
987bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
988bc4ae4beSMatthew G. Knepley 
989bc4ae4beSMatthew G. Knepley   Not collective
990bc4ae4beSMatthew G. Knepley 
991bc4ae4beSMatthew G. Knepley   Input Parameters:
992dce8aebaSBarry Smith + prob - The `PetscDS` object
993bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
994bc4ae4beSMatthew G. Knepley 
995bc4ae4beSMatthew G. Knepley   Level: beginner
996bc4ae4beSMatthew G. Knepley 
997dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
998bc4ae4beSMatthew G. Knepley @*/
999d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1000d71ae5a4SJacob Faibussowitsch {
10012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10029566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
10032764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
10042764a2aaSMatthew G. Knepley }
10052764a2aaSMatthew G. Knepley 
1006249df284SMatthew G. Knepley /*@
1007dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1008083401c6SMatthew G. Knepley 
1009083401c6SMatthew G. Knepley   Not collective
1010083401c6SMatthew G. Knepley 
1011083401c6SMatthew G. Knepley   Input Parameter:
1012dce8aebaSBarry Smith . prob - The `PetscDS` object
1013083401c6SMatthew G. Knepley 
1014083401c6SMatthew G. Knepley   Output Parameter:
1015083401c6SMatthew G. Knepley . q - The quadrature object
1016083401c6SMatthew G. Knepley 
1017083401c6SMatthew G. Knepley   Level: intermediate
1018083401c6SMatthew G. Knepley 
1019dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1020083401c6SMatthew G. Knepley @*/
1021d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1022d71ae5a4SJacob Faibussowitsch {
1023083401c6SMatthew G. Knepley   PetscObject  obj;
1024083401c6SMatthew G. Knepley   PetscClassId id;
1025083401c6SMatthew G. Knepley 
1026083401c6SMatthew G. Knepley   PetscFunctionBegin;
1027083401c6SMatthew G. Knepley   *q = NULL;
1028083401c6SMatthew G. Knepley   if (!prob->Nf) PetscFunctionReturn(0);
10299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
10309566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
10319566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
10329566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
103398921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
1034083401c6SMatthew G. Knepley   PetscFunctionReturn(0);
1035083401c6SMatthew G. Knepley }
1036083401c6SMatthew G. Knepley 
1037083401c6SMatthew G. Knepley /*@
1038dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1039249df284SMatthew G. Knepley 
1040249df284SMatthew G. Knepley   Not collective
1041249df284SMatthew G. Knepley 
1042249df284SMatthew G. Knepley   Input Parameters:
1043dce8aebaSBarry Smith + prob - The `PetscDS` object
1044249df284SMatthew G. Knepley - f - The field number
1045249df284SMatthew G. Knepley 
1046249df284SMatthew G. Knepley   Output Parameter:
1047249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1048249df284SMatthew G. Knepley 
1049249df284SMatthew G. Knepley   Level: developer
1050249df284SMatthew G. Knepley 
1051dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1052249df284SMatthew G. Knepley @*/
1053d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1054d71ae5a4SJacob Faibussowitsch {
1055249df284SMatthew G. Knepley   PetscFunctionBegin;
1056249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1057dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
105863a3b9bcSJacob 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);
1059249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
1060249df284SMatthew G. Knepley   PetscFunctionReturn(0);
1061249df284SMatthew G. Knepley }
1062249df284SMatthew G. Knepley 
1063249df284SMatthew G. Knepley /*@
1064dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1065249df284SMatthew G. Knepley 
1066249df284SMatthew G. Knepley   Not collective
1067249df284SMatthew G. Knepley 
1068249df284SMatthew G. Knepley   Input Parameters:
1069dce8aebaSBarry Smith + prob - The `PetscDS` object
1070249df284SMatthew G. Knepley . f - The field number
1071249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1072249df284SMatthew G. Knepley 
1073249df284SMatthew G. Knepley   Level: developer
1074249df284SMatthew G. Knepley 
1075dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1076249df284SMatthew G. Knepley @*/
1077d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1078d71ae5a4SJacob Faibussowitsch {
1079249df284SMatthew G. Knepley   PetscFunctionBegin;
1080249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
108163a3b9bcSJacob 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);
1082249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
1083249df284SMatthew G. Knepley   PetscFunctionReturn(0);
1084249df284SMatthew G. Knepley }
1085249df284SMatthew G. Knepley 
1086f9244615SMatthew G. Knepley /*@
1087f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1088f9244615SMatthew G. Knepley 
1089f9244615SMatthew G. Knepley   Not collective
1090f9244615SMatthew G. Knepley 
1091f9244615SMatthew G. Knepley   Input Parameters:
1092dce8aebaSBarry Smith + ds - The `PetscDS` object
1093f9244615SMatthew G. Knepley - f  - The field number
1094f9244615SMatthew G. Knepley 
1095f9244615SMatthew G. Knepley   Output Parameter:
1096f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1097f9244615SMatthew G. Knepley 
1098f9244615SMatthew G. Knepley   Level: developer
1099f9244615SMatthew G. Knepley 
1100dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1101f9244615SMatthew G. Knepley @*/
1102d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1103d71ae5a4SJacob Faibussowitsch {
1104f9244615SMatthew G. Knepley   PetscFunctionBegin;
1105f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1106dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
110763a3b9bcSJacob 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);
1108f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
1109f9244615SMatthew G. Knepley   PetscFunctionReturn(0);
1110f9244615SMatthew G. Knepley }
1111f9244615SMatthew G. Knepley 
1112f9244615SMatthew G. Knepley /*@
1113f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1114f9244615SMatthew G. Knepley 
1115f9244615SMatthew G. Knepley   Not collective
1116f9244615SMatthew G. Knepley 
1117f9244615SMatthew G. Knepley   Input Parameters:
1118dce8aebaSBarry Smith + ds - The `PetscDS` object
1119f9244615SMatthew G. Knepley . f  - The field number
1120f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1121f9244615SMatthew G. Knepley 
1122f9244615SMatthew G. Knepley   Level: developer
1123f9244615SMatthew G. Knepley 
1124dce8aebaSBarry Smith .seealso: ``PetscDS`, PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1125f9244615SMatthew G. Knepley @*/
1126d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1127d71ae5a4SJacob Faibussowitsch {
1128f9244615SMatthew G. Knepley   PetscFunctionBegin;
1129f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
113063a3b9bcSJacob 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);
1131f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
1132f9244615SMatthew G. Knepley   PetscFunctionReturn(0);
1133f9244615SMatthew G. Knepley }
1134f9244615SMatthew G. Knepley 
1135d71ae5a4SJacob 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[]))
1136d71ae5a4SJacob Faibussowitsch {
11376528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
11386528b96dSMatthew G. Knepley   PetscInt        n;
11396528b96dSMatthew G. Knepley 
11402764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11416528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11426528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
114363a3b9bcSJacob 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);
11449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
11456528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
11462764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
11472764a2aaSMatthew G. Knepley }
11482764a2aaSMatthew G. Knepley 
1149d71ae5a4SJacob 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[]))
1150d71ae5a4SJacob Faibussowitsch {
11512764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11526528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11536528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
115463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
11559566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
11562764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
11572764a2aaSMatthew G. Knepley }
11582764a2aaSMatthew G. Knepley 
1159194d53e6SMatthew G. Knepley /*@C
1160194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1161194d53e6SMatthew G. Knepley 
1162194d53e6SMatthew G. Knepley   Not collective
1163194d53e6SMatthew G. Knepley 
1164194d53e6SMatthew G. Knepley   Input Parameters:
1165dce8aebaSBarry Smith + ds - The `PetscDS`
1166194d53e6SMatthew G. Knepley - f  - The test field number
1167194d53e6SMatthew G. Knepley 
1168194d53e6SMatthew G. Knepley   Output Parameters:
1169194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1170194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1171194d53e6SMatthew G. Knepley 
1172dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1173dce8aebaSBarry Smith .vb
1174dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1175dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1176dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1177dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1178dce8aebaSBarry Smith .ve
1179194d53e6SMatthew G. Knepley + dim - the spatial dimension
1180194d53e6SMatthew G. Knepley . Nf - the number of fields
1181194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1182194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1183194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1184194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1185194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1186194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1187194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1188194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1189194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1190194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1191194d53e6SMatthew G. Knepley . t - current time
1192194d53e6SMatthew G. Knepley . x - coordinates of the current point
119397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
119497b6e6e8SMatthew G. Knepley . constants - constant parameters
1195194d53e6SMatthew G. Knepley - f0 - output values at the current point
1196194d53e6SMatthew G. Knepley 
1197194d53e6SMatthew G. Knepley   Level: intermediate
1198194d53e6SMatthew G. Knepley 
1199dce8aebaSBarry Smith   Note:
1200dce8aebaSBarry 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)
1201dce8aebaSBarry Smith 
1202dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1203194d53e6SMatthew G. Knepley @*/
1204d71ae5a4SJacob 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[]))
1205d71ae5a4SJacob Faibussowitsch {
12066528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
12076528b96dSMatthew G. Knepley   PetscInt        n0, n1;
12086528b96dSMatthew G. Knepley 
12092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12106528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
121163a3b9bcSJacob 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);
12129566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
12136528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
12146528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
12152764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
12162764a2aaSMatthew G. Knepley }
12172764a2aaSMatthew G. Knepley 
1218194d53e6SMatthew G. Knepley /*@C
1219194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1220194d53e6SMatthew G. Knepley 
1221194d53e6SMatthew G. Knepley   Not collective
1222194d53e6SMatthew G. Knepley 
1223194d53e6SMatthew G. Knepley   Input Parameters:
1224dce8aebaSBarry Smith + ds - The `PetscDS`
1225194d53e6SMatthew G. Knepley . f  - The test field number
1226194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1227194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1228194d53e6SMatthew G. Knepley 
1229dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1230dce8aebaSBarry Smith .vb
1231dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1232dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1233dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1234dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1235dce8aebaSBarry Smith .ve
1236194d53e6SMatthew G. Knepley + dim - the spatial dimension
1237194d53e6SMatthew G. Knepley . Nf - the number of fields
1238194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1239194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1240194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1241194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1242194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1243194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1244194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1245194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1246194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1247194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1248194d53e6SMatthew G. Knepley . t - current time
1249194d53e6SMatthew G. Knepley . x - coordinates of the current point
125097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
125197b6e6e8SMatthew G. Knepley . constants - constant parameters
1252194d53e6SMatthew G. Knepley - f0 - output values at the current point
1253194d53e6SMatthew G. Knepley 
1254194d53e6SMatthew G. Knepley   Level: intermediate
1255194d53e6SMatthew G. Knepley 
1256dce8aebaSBarry Smith   Note:
1257dce8aebaSBarry 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)
1258dce8aebaSBarry Smith 
1259dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1260194d53e6SMatthew G. Knepley @*/
1261d71ae5a4SJacob 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[]))
1262d71ae5a4SJacob Faibussowitsch {
12632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1265f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1266f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
126763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
12692764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
12702764a2aaSMatthew G. Knepley }
12712764a2aaSMatthew G. Knepley 
12723e75805dSMatthew G. Knepley /*@C
1273cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1274cb36c0f9SMatthew G. Knepley 
1275cb36c0f9SMatthew G. Knepley   Not collective
1276cb36c0f9SMatthew G. Knepley 
1277cb36c0f9SMatthew G. Knepley   Input Parameters:
1278dce8aebaSBarry Smith + ds - The `PetscDS`
1279cb36c0f9SMatthew G. Knepley - f  - The test field number
1280cb36c0f9SMatthew G. Knepley 
1281cb36c0f9SMatthew G. Knepley   Output Parameters:
1282cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1283cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1284cb36c0f9SMatthew G. Knepley 
1285dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
1286dce8aebaSBarry Smith .vb
1287dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1288dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1289dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1290dce8aebaSBarry Smith     PetscReal t, const PetscReal x[], PetscScalar f0[])
1291dce8aebaSBarry Smith .ve
1292cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1293cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1294cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1295cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1296cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1297cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1298cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1299cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1300cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1301cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1302cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1303cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1304cb36c0f9SMatthew G. Knepley . t - current time
1305cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1306cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1307cb36c0f9SMatthew G. Knepley . constants - constant parameters
1308cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1309cb36c0f9SMatthew G. Knepley 
1310cb36c0f9SMatthew G. Knepley   Level: intermediate
1311cb36c0f9SMatthew G. Knepley 
1312dce8aebaSBarry Smith   Note:
1313dce8aebaSBarry 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)
1314dce8aebaSBarry Smith 
1315dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1316cb36c0f9SMatthew G. Knepley @*/
1317d71ae5a4SJacob 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[]))
1318d71ae5a4SJacob Faibussowitsch {
1319cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1320cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1321cb36c0f9SMatthew G. Knepley 
1322cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1323cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
132463a3b9bcSJacob 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);
13259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1326cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1327cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
1328cb36c0f9SMatthew G. Knepley   PetscFunctionReturn(0);
1329cb36c0f9SMatthew G. Knepley }
1330cb36c0f9SMatthew G. Knepley 
1331cb36c0f9SMatthew G. Knepley /*@C
1332cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1333cb36c0f9SMatthew G. Knepley 
1334cb36c0f9SMatthew G. Knepley   Not collective
1335cb36c0f9SMatthew G. Knepley 
1336cb36c0f9SMatthew G. Knepley   Input Parameters:
1337dce8aebaSBarry Smith + ds - The `PetscDS`
1338cb36c0f9SMatthew G. Knepley . f  - The test field number
1339cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1340cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1341cb36c0f9SMatthew G. Knepley 
1342dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1343dce8aebaSBarry Smith .vb
1344dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1345dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1346dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1347dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1348dce8aebaSBarry Smith .ve
1349cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1350cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1351cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1352cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1353cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1354cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1355cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1356cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1357cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1358cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1359cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1360cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1361cb36c0f9SMatthew G. Knepley . t - current time
1362cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1363cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1364cb36c0f9SMatthew G. Knepley . constants - constant parameters
1365cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1366cb36c0f9SMatthew G. Knepley 
1367cb36c0f9SMatthew G. Knepley   Level: intermediate
1368cb36c0f9SMatthew G. Knepley 
1369dce8aebaSBarry Smith   Note:
1370dce8aebaSBarry 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)
1371dce8aebaSBarry Smith 
1372dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1373cb36c0f9SMatthew G. Knepley @*/
1374d71ae5a4SJacob 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[]))
1375d71ae5a4SJacob Faibussowitsch {
1376cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1377cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1378cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1379cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
138063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
1382cb36c0f9SMatthew G. Knepley   PetscFunctionReturn(0);
1383cb36c0f9SMatthew G. Knepley }
1384cb36c0f9SMatthew G. Knepley 
1385cb36c0f9SMatthew G. Knepley /*@C
1386dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
13873e75805dSMatthew G. Knepley 
13883e75805dSMatthew G. Knepley   Not collective
13893e75805dSMatthew G. Knepley 
13903e75805dSMatthew G. Knepley   Input Parameter:
1391dce8aebaSBarry Smith . prob - The `PetscDS`
13923e75805dSMatthew G. Knepley 
13933e75805dSMatthew G. Knepley   Output Parameter:
13943e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
13953e75805dSMatthew G. Knepley 
13963e75805dSMatthew G. Knepley   Level: intermediate
13973e75805dSMatthew G. Knepley 
1398dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
13993e75805dSMatthew G. Knepley @*/
1400d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1401d71ae5a4SJacob Faibussowitsch {
14023e75805dSMatthew G. Knepley   PetscFunctionBegin;
14036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
14049566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
14053e75805dSMatthew G. Knepley   PetscFunctionReturn(0);
14063e75805dSMatthew G. Knepley }
14073e75805dSMatthew G. Knepley 
1408194d53e6SMatthew G. Knepley /*@C
1409194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1410194d53e6SMatthew G. Knepley 
1411194d53e6SMatthew G. Knepley   Not collective
1412194d53e6SMatthew G. Knepley 
1413194d53e6SMatthew G. Knepley   Input Parameters:
1414dce8aebaSBarry Smith + ds - The `PetscDS`
1415194d53e6SMatthew G. Knepley . f  - The test field number
1416194d53e6SMatthew G. Knepley - g  - The field number
1417194d53e6SMatthew G. Knepley 
1418194d53e6SMatthew G. Knepley   Output Parameters:
1419194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1420194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1421194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1422194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1423194d53e6SMatthew G. Knepley 
1424dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1425dce8aebaSBarry Smith .vb
1426dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1427dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1428dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1429dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1430dce8aebaSBarry Smith .ve
1431194d53e6SMatthew G. Knepley + dim - the spatial dimension
1432194d53e6SMatthew G. Knepley . Nf - the number of fields
1433194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1434194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1435194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1436194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1437194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1438194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1439194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1440194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1441194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1442194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1443194d53e6SMatthew G. Knepley . t - current time
14442aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1445194d53e6SMatthew G. Knepley . x - coordinates of the current point
144697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
144797b6e6e8SMatthew G. Knepley . constants - constant parameters
1448194d53e6SMatthew G. Knepley - g0 - output values at the current point
1449194d53e6SMatthew G. Knepley 
1450194d53e6SMatthew G. Knepley   Level: intermediate
1451194d53e6SMatthew G. Knepley 
1452dce8aebaSBarry Smith   Note:
1453dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1454dce8aebaSBarry 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
1455dce8aebaSBarry Smith 
1456dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1457194d53e6SMatthew G. Knepley @*/
1458d71ae5a4SJacob 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[]))
1459d71ae5a4SJacob Faibussowitsch {
14606528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
14616528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
14626528b96dSMatthew G. Knepley 
14632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
146563a3b9bcSJacob 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);
146663a3b9bcSJacob 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);
14679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
14686528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
14696528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
14706528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
14716528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
14722764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
14732764a2aaSMatthew G. Knepley }
14742764a2aaSMatthew G. Knepley 
1475194d53e6SMatthew G. Knepley /*@C
1476194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1477194d53e6SMatthew G. Knepley 
1478194d53e6SMatthew G. Knepley   Not collective
1479194d53e6SMatthew G. Knepley 
1480194d53e6SMatthew G. Knepley   Input Parameters:
1481dce8aebaSBarry Smith + ds - The `PetscDS`
1482194d53e6SMatthew G. Knepley . f  - The test field number
1483194d53e6SMatthew G. Knepley . g  - The field number
1484194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1485194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1486194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1487194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1488194d53e6SMatthew G. Knepley 
1489dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1490dce8aebaSBarry Smith .vb
1491dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1492dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1493dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1494dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1495dce8aebaSBarry Smith .ve
1496194d53e6SMatthew G. Knepley + dim - the spatial dimension
1497194d53e6SMatthew G. Knepley . Nf - the number of fields
1498194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1499194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1500194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1501194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1502194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1503194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1504194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1505194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1506194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1507194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1508194d53e6SMatthew G. Knepley . t - current time
15092aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1510194d53e6SMatthew G. Knepley . x - coordinates of the current point
151197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
151297b6e6e8SMatthew G. Knepley . constants - constant parameters
1513194d53e6SMatthew G. Knepley - g0 - output values at the current point
1514194d53e6SMatthew G. Knepley 
1515194d53e6SMatthew G. Knepley   Level: intermediate
1516194d53e6SMatthew G. Knepley 
1517dce8aebaSBarry Smith   Note:
1518dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1519dce8aebaSBarry 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
1520dce8aebaSBarry Smith 
1521dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1522194d53e6SMatthew G. Knepley @*/
1523d71ae5a4SJacob 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[]))
1524d71ae5a4SJacob Faibussowitsch {
15252764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15266528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15272764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
15282764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
15292764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
15302764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
153163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
153263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
15339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
15342764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
15352764a2aaSMatthew G. Knepley }
15362764a2aaSMatthew G. Knepley 
1537475e0ac9SMatthew G. Knepley /*@C
1538dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
153955c1f793SMatthew G. Knepley 
154055c1f793SMatthew G. Knepley   Not collective
154155c1f793SMatthew G. Knepley 
154255c1f793SMatthew G. Knepley   Input Parameters:
1543dce8aebaSBarry Smith + prob - The `PetscDS`
154455c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
154555c1f793SMatthew G. Knepley 
154655c1f793SMatthew G. Knepley   Level: intermediate
154755c1f793SMatthew G. Knepley 
1548dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
154955c1f793SMatthew G. Knepley @*/
1550d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1551d71ae5a4SJacob Faibussowitsch {
155255c1f793SMatthew G. Knepley   PetscFunctionBegin;
155355c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
155455c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
155555c1f793SMatthew G. Knepley   PetscFunctionReturn(0);
155655c1f793SMatthew G. Knepley }
155755c1f793SMatthew G. Knepley 
155855c1f793SMatthew G. Knepley /*@C
1559dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1560475e0ac9SMatthew G. Knepley 
1561475e0ac9SMatthew G. Knepley   Not collective
1562475e0ac9SMatthew G. Knepley 
1563475e0ac9SMatthew G. Knepley   Input Parameter:
1564dce8aebaSBarry Smith . prob - The `PetscDS`
1565475e0ac9SMatthew G. Knepley 
1566475e0ac9SMatthew G. Knepley   Output Parameter:
1567475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1568475e0ac9SMatthew G. Knepley 
1569475e0ac9SMatthew G. Knepley   Level: intermediate
1570475e0ac9SMatthew G. Knepley 
1571dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1572475e0ac9SMatthew G. Knepley @*/
1573d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1574d71ae5a4SJacob Faibussowitsch {
1575475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
15766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1577475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
15786528b96dSMatthew G. Knepley   if (!ds->useJacPre) PetscFunctionReturn(0);
15799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
1580475e0ac9SMatthew G. Knepley   PetscFunctionReturn(0);
1581475e0ac9SMatthew G. Knepley }
1582475e0ac9SMatthew G. Knepley 
1583475e0ac9SMatthew G. Knepley /*@C
1584dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1585dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1586475e0ac9SMatthew G. Knepley 
1587475e0ac9SMatthew G. Knepley   Not collective
1588475e0ac9SMatthew G. Knepley 
1589475e0ac9SMatthew G. Knepley   Input Parameters:
1590dce8aebaSBarry Smith + ds - The `PetscDS`
1591475e0ac9SMatthew G. Knepley . f  - The test field number
1592475e0ac9SMatthew G. Knepley - g  - The field number
1593475e0ac9SMatthew G. Knepley 
1594475e0ac9SMatthew G. Knepley   Output Parameters:
1595475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1596475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1597475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1598475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1599475e0ac9SMatthew G. Knepley 
1600dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1601dce8aebaSBarry Smith .vb
1602dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1603dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1604dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1605dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1606dce8aebaSBarry Smith .ve
1607475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1608475e0ac9SMatthew G. Knepley . Nf - the number of fields
1609475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1610475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1611475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1612475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1613475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1614475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1615475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1616475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1617475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1618475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1619475e0ac9SMatthew G. Knepley . t - current time
1620475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1621475e0ac9SMatthew G. Knepley . x - coordinates of the current point
162297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
162397b6e6e8SMatthew G. Knepley . constants - constant parameters
1624475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1625475e0ac9SMatthew G. Knepley 
1626475e0ac9SMatthew G. Knepley   Level: intermediate
1627475e0ac9SMatthew G. Knepley 
1628dce8aebaSBarry Smith   Note:
1629dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1630dce8aebaSBarry 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
1631dce8aebaSBarry Smith 
1632dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1633475e0ac9SMatthew G. Knepley @*/
1634d71ae5a4SJacob 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[]))
1635d71ae5a4SJacob Faibussowitsch {
16366528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16376528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16386528b96dSMatthew G. Knepley 
1639475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16406528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
164163a3b9bcSJacob 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);
164263a3b9bcSJacob 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);
16439566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16446528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16456528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16466528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16476528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
1648475e0ac9SMatthew G. Knepley   PetscFunctionReturn(0);
1649475e0ac9SMatthew G. Knepley }
1650475e0ac9SMatthew G. Knepley 
1651475e0ac9SMatthew G. Knepley /*@C
1652dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1653dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1654475e0ac9SMatthew G. Knepley 
1655475e0ac9SMatthew G. Knepley   Not collective
1656475e0ac9SMatthew G. Knepley 
1657475e0ac9SMatthew G. Knepley   Input Parameters:
1658dce8aebaSBarry Smith + ds - The `PetscDS`
1659475e0ac9SMatthew G. Knepley . f  - The test field number
1660475e0ac9SMatthew G. Knepley . g  - The field number
1661475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1662475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1663475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1664475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1665475e0ac9SMatthew G. Knepley 
1666dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1667dce8aebaSBarry Smith .vb
1668dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1669dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1670dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1671dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1672dce8aebaSBarry Smith .ve
1673475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1674475e0ac9SMatthew G. Knepley . Nf - the number of fields
1675475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1676475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1677475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1678475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1679475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1680475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1681475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1682475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1683475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1684475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1685475e0ac9SMatthew G. Knepley . t - current time
1686475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1687475e0ac9SMatthew G. Knepley . x - coordinates of the current point
168897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
168997b6e6e8SMatthew G. Knepley . constants - constant parameters
1690475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1691475e0ac9SMatthew G. Knepley 
1692475e0ac9SMatthew G. Knepley   Level: intermediate
1693475e0ac9SMatthew G. Knepley 
1694dce8aebaSBarry Smith   Note:
1695dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1696dce8aebaSBarry 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
1697dce8aebaSBarry Smith 
1698dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1699475e0ac9SMatthew G. Knepley @*/
1700d71ae5a4SJacob 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[]))
1701d71ae5a4SJacob Faibussowitsch {
1702475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1704475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1705475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1706475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1707475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
170863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
170963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
1711475e0ac9SMatthew G. Knepley   PetscFunctionReturn(0);
1712475e0ac9SMatthew G. Knepley }
1713475e0ac9SMatthew G. Knepley 
1714b7e05686SMatthew G. Knepley /*@C
1715b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1716b7e05686SMatthew G. Knepley 
1717b7e05686SMatthew G. Knepley   Not collective
1718b7e05686SMatthew G. Knepley 
1719b7e05686SMatthew G. Knepley   Input Parameter:
1720dce8aebaSBarry Smith . ds - The `PetscDS`
1721b7e05686SMatthew G. Knepley 
1722b7e05686SMatthew G. Knepley   Output Parameter:
1723b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1724b7e05686SMatthew G. Knepley 
1725b7e05686SMatthew G. Knepley   Level: intermediate
1726b7e05686SMatthew G. Knepley 
1727dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1728b7e05686SMatthew G. Knepley @*/
1729d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1730d71ae5a4SJacob Faibussowitsch {
1731b7e05686SMatthew G. Knepley   PetscFunctionBegin;
17326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
1734b7e05686SMatthew G. Knepley   PetscFunctionReturn(0);
1735b7e05686SMatthew G. Knepley }
1736b7e05686SMatthew G. Knepley 
1737b7e05686SMatthew G. Knepley /*@C
1738b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1739b7e05686SMatthew G. Knepley 
1740b7e05686SMatthew G. Knepley   Not collective
1741b7e05686SMatthew G. Knepley 
1742b7e05686SMatthew G. Knepley   Input Parameters:
1743dce8aebaSBarry Smith + ds - The `PetscDS`
1744b7e05686SMatthew G. Knepley . f  - The test field number
1745b7e05686SMatthew G. Knepley - g  - The field number
1746b7e05686SMatthew G. Knepley 
1747b7e05686SMatthew G. Knepley   Output Parameters:
1748b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1749b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1750b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1751b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1752b7e05686SMatthew G. Knepley 
1753dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
1754dce8aebaSBarry Smith .vb
1755dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1756dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1757dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1758dce8aebaSBarry Smith      PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1759dce8aebaSBarry Smith .ve
1760b7e05686SMatthew G. Knepley + dim - the spatial dimension
1761b7e05686SMatthew G. Knepley . Nf - the number of fields
1762b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1763b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1764b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1765b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1766b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1767b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1768b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1769b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1770b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1771b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1772b7e05686SMatthew G. Knepley . t - current time
1773b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1774b7e05686SMatthew G. Knepley . x - coordinates of the current point
177597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
177697b6e6e8SMatthew G. Knepley . constants - constant parameters
1777b7e05686SMatthew G. Knepley - g0 - output values at the current point
1778b7e05686SMatthew G. Knepley 
1779b7e05686SMatthew G. Knepley   Level: intermediate
1780b7e05686SMatthew G. Knepley 
1781dce8aebaSBarry Smith   Note:
1782dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1783dce8aebaSBarry 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
1784dce8aebaSBarry Smith 
1785dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1786b7e05686SMatthew G. Knepley @*/
1787d71ae5a4SJacob 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[]))
1788d71ae5a4SJacob Faibussowitsch {
17896528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17906528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17916528b96dSMatthew G. Knepley 
1792b7e05686SMatthew G. Knepley   PetscFunctionBegin;
17936528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
179463a3b9bcSJacob 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);
179563a3b9bcSJacob 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);
17969566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17976528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17986528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17996528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18006528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
1801b7e05686SMatthew G. Knepley   PetscFunctionReturn(0);
1802b7e05686SMatthew G. Knepley }
1803b7e05686SMatthew G. Knepley 
1804b7e05686SMatthew G. Knepley /*@C
1805b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1806b7e05686SMatthew G. Knepley 
1807b7e05686SMatthew G. Knepley   Not collective
1808b7e05686SMatthew G. Knepley 
1809b7e05686SMatthew G. Knepley   Input Parameters:
1810dce8aebaSBarry Smith + ds - The `PetscDS`
1811b7e05686SMatthew G. Knepley . f  - The test field number
1812b7e05686SMatthew G. Knepley . g  - The field number
1813b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1814b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1815b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1816b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1817b7e05686SMatthew G. Knepley 
1818dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
1819dce8aebaSBarry Smith .vb
1820dce8aebaSBarry Smith    g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1821dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1822dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1823dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar g0[])
1824dce8aebaSBarry Smith .ve
1825b7e05686SMatthew G. Knepley + dim - the spatial dimension
1826b7e05686SMatthew G. Knepley . Nf - the number of fields
1827b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1828b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1829b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1830b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1831b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1832b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1833b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1834b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1835b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1836b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1837b7e05686SMatthew G. Knepley . t - current time
1838b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1839b7e05686SMatthew G. Knepley . x - coordinates of the current point
184097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
184197b6e6e8SMatthew G. Knepley . constants - constant parameters
1842b7e05686SMatthew G. Knepley - g0 - output values at the current point
1843b7e05686SMatthew G. Knepley 
1844b7e05686SMatthew G. Knepley   Level: intermediate
1845b7e05686SMatthew G. Knepley 
1846dce8aebaSBarry Smith   Note:
1847dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1848dce8aebaSBarry 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
1849dce8aebaSBarry Smith 
1850dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1851b7e05686SMatthew G. Knepley @*/
1852d71ae5a4SJacob 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[]))
1853d71ae5a4SJacob Faibussowitsch {
1854b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18556528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1856b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1857b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1858b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1859b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
186063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
186163a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18629566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
1863b7e05686SMatthew G. Knepley   PetscFunctionReturn(0);
1864b7e05686SMatthew G. Knepley }
1865b7e05686SMatthew G. Knepley 
18660c2f2876SMatthew G. Knepley /*@C
18670c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
18680c2f2876SMatthew G. Knepley 
18690c2f2876SMatthew G. Knepley   Not collective
18700c2f2876SMatthew G. Knepley 
18714165533cSJose E. Roman   Input Parameters:
1872dce8aebaSBarry Smith + ds - The `PetscDS` object
18730c2f2876SMatthew G. Knepley - f  - The field number
18740c2f2876SMatthew G. Knepley 
18754165533cSJose E. Roman   Output Parameter:
18760c2f2876SMatthew G. Knepley . r    - Riemann solver
18770c2f2876SMatthew G. Knepley 
18780c2f2876SMatthew G. Knepley   Calling sequence for r:
1879dce8aebaSBarry Smith .vb
1880dce8aebaSBarry Smith   r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1881dce8aebaSBarry Smith .ve
18825db36cf9SMatthew G. Knepley + dim  - The spatial dimension
18835db36cf9SMatthew G. Knepley . Nf   - The number of fields
18845db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
18850c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
18860c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
18870c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
18880c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
188997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
189097b6e6e8SMatthew G. Knepley . constants - constant parameters
18910c2f2876SMatthew G. Knepley - ctx  - optional user context
18920c2f2876SMatthew G. Knepley 
18930c2f2876SMatthew G. Knepley   Level: intermediate
18940c2f2876SMatthew G. Knepley 
1895dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
18960c2f2876SMatthew G. Knepley @*/
1897d71ae5a4SJacob 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))
1898d71ae5a4SJacob Faibussowitsch {
18996528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
19006528b96dSMatthew G. Knepley   PetscInt          n;
19016528b96dSMatthew G. Knepley 
19020c2f2876SMatthew G. Knepley   PetscFunctionBegin;
19036528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19040c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
190563a3b9bcSJacob 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);
19069566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
19076528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
19080c2f2876SMatthew G. Knepley   PetscFunctionReturn(0);
19090c2f2876SMatthew G. Knepley }
19100c2f2876SMatthew G. Knepley 
19110c2f2876SMatthew G. Knepley /*@C
19120c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
19130c2f2876SMatthew G. Knepley 
19140c2f2876SMatthew G. Knepley   Not collective
19150c2f2876SMatthew G. Knepley 
19164165533cSJose E. Roman   Input Parameters:
1917dce8aebaSBarry Smith + ds - The `PetscDS` object
19180c2f2876SMatthew G. Knepley . f  - The field number
19190c2f2876SMatthew G. Knepley - r  - Riemann solver
19200c2f2876SMatthew G. Knepley 
19210c2f2876SMatthew G. Knepley   Calling sequence for r:
1922dce8aebaSBarry Smith .vb
1923dce8aebaSBarry Smith    r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1924dce8aebaSBarry Smith .ve
19255db36cf9SMatthew G. Knepley + dim  - The spatial dimension
19265db36cf9SMatthew G. Knepley . Nf   - The number of fields
19275db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
19280c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
19290c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
19300c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
19310c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
193297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
193397b6e6e8SMatthew G. Knepley . constants - constant parameters
19340c2f2876SMatthew G. Knepley - ctx  - optional user context
19350c2f2876SMatthew G. Knepley 
19360c2f2876SMatthew G. Knepley   Level: intermediate
19370c2f2876SMatthew G. Knepley 
1938dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
19390c2f2876SMatthew G. Knepley @*/
1940d71ae5a4SJacob 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))
1941d71ae5a4SJacob Faibussowitsch {
19420c2f2876SMatthew G. Knepley   PetscFunctionBegin;
19436528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1944de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
194563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
19469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
19470c2f2876SMatthew G. Knepley   PetscFunctionReturn(0);
19480c2f2876SMatthew G. Knepley }
19490c2f2876SMatthew G. Knepley 
195032d2bbc9SMatthew G. Knepley /*@C
195132d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
195232d2bbc9SMatthew G. Knepley 
195332d2bbc9SMatthew G. Knepley   Not collective
195432d2bbc9SMatthew G. Knepley 
195532d2bbc9SMatthew G. Knepley   Input Parameters:
1956dce8aebaSBarry Smith + ds - The `PetscDS`
195732d2bbc9SMatthew G. Knepley - f  - The field number
195832d2bbc9SMatthew G. Knepley 
1959f899ff85SJose E. Roman   Output Parameter:
1960a2b725a8SWilliam Gropp . update - update function
196132d2bbc9SMatthew G. Knepley 
1962dce8aebaSBarry Smith   Calling sequence for the callback update:
1963dce8aebaSBarry Smith .vb
1964dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1965dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1966dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1967dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
1968dce8aebaSBarry Smith .ve
196932d2bbc9SMatthew G. Knepley + dim - the spatial dimension
197032d2bbc9SMatthew G. Knepley . Nf - the number of fields
197132d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
197232d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
197332d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
197432d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
197532d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
197632d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
197732d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
197832d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
197932d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
198032d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
198132d2bbc9SMatthew G. Knepley . t - current time
198232d2bbc9SMatthew G. Knepley . x - coordinates of the current point
198332d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
198432d2bbc9SMatthew G. Knepley 
198532d2bbc9SMatthew G. Knepley   Level: intermediate
198632d2bbc9SMatthew G. Knepley 
1987dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
198832d2bbc9SMatthew G. Knepley @*/
1989d71ae5a4SJacob 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[]))
1990d71ae5a4SJacob Faibussowitsch {
199132d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
19926528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
199363a3b9bcSJacob 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);
19949371c9d4SSatish Balay   if (update) {
19959371c9d4SSatish Balay     PetscValidPointer(update, 3);
19969371c9d4SSatish Balay     *update = ds->update[f];
19979371c9d4SSatish Balay   }
199832d2bbc9SMatthew G. Knepley   PetscFunctionReturn(0);
199932d2bbc9SMatthew G. Knepley }
200032d2bbc9SMatthew G. Knepley 
200132d2bbc9SMatthew G. Knepley /*@C
20023fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
200332d2bbc9SMatthew G. Knepley 
200432d2bbc9SMatthew G. Knepley   Not collective
200532d2bbc9SMatthew G. Knepley 
200632d2bbc9SMatthew G. Knepley   Input Parameters:
2007dce8aebaSBarry Smith + ds     - The `PetscDS`
200832d2bbc9SMatthew G. Knepley . f      - The field number
200932d2bbc9SMatthew G. Knepley - update - update function
201032d2bbc9SMatthew G. Knepley 
2011dce8aebaSBarry Smith   Calling sequence for the callback update:
2012dce8aebaSBarry Smith .vb
2013dce8aebaSBarry Smith   update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2014dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2015dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2016dce8aebaSBarry Smith          PetscReal t, const PetscReal x[], PetscScalar uNew[])
2017dce8aebaSBarry Smith .ve
201832d2bbc9SMatthew G. Knepley + dim - the spatial dimension
201932d2bbc9SMatthew G. Knepley . Nf - the number of fields
202032d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
202132d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
202232d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
202332d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
202432d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
202532d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
202632d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
202732d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
202832d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
202932d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
203032d2bbc9SMatthew G. Knepley . t - current time
203132d2bbc9SMatthew G. Knepley . x - coordinates of the current point
203232d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
203332d2bbc9SMatthew G. Knepley 
203432d2bbc9SMatthew G. Knepley   Level: intermediate
203532d2bbc9SMatthew G. Knepley 
2036dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
203732d2bbc9SMatthew G. Knepley @*/
2038d71ae5a4SJacob 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[]))
2039d71ae5a4SJacob Faibussowitsch {
204032d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
20416528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
204232d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
204363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20449566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
20456528b96dSMatthew G. Knepley   ds->update[f] = update;
204632d2bbc9SMatthew G. Knepley   PetscFunctionReturn(0);
204732d2bbc9SMatthew G. Knepley }
204832d2bbc9SMatthew G. Knepley 
2049d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2050d71ae5a4SJacob Faibussowitsch {
20510c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20526528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
205363a3b9bcSJacob 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);
20540c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
20553ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
20560c2f2876SMatthew G. Knepley   PetscFunctionReturn(0);
20570c2f2876SMatthew G. Knepley }
20580c2f2876SMatthew G. Knepley 
2059d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2060d71ae5a4SJacob Faibussowitsch {
20610c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20626528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
206363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20649566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
20656528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
20660c2f2876SMatthew G. Knepley   PetscFunctionReturn(0);
20670c2f2876SMatthew G. Knepley }
20680c2f2876SMatthew G. Knepley 
2069194d53e6SMatthew G. Knepley /*@C
2070194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2071194d53e6SMatthew G. Knepley 
2072194d53e6SMatthew G. Knepley   Not collective
2073194d53e6SMatthew G. Knepley 
2074194d53e6SMatthew G. Knepley   Input Parameters:
20756528b96dSMatthew G. Knepley + ds - The PetscDS
2076194d53e6SMatthew G. Knepley - f  - The test field number
2077194d53e6SMatthew G. Knepley 
2078194d53e6SMatthew G. Knepley   Output Parameters:
2079194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2080194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2081194d53e6SMatthew G. Knepley 
2082dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2083dce8aebaSBarry Smith .vb
2084dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2085dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2086dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2087dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2088dce8aebaSBarry Smith .ve
2089194d53e6SMatthew G. Knepley + dim - the spatial dimension
2090194d53e6SMatthew G. Knepley . Nf - the number of fields
2091194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2092194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2093194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2094194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2095194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2096194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2097194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2098194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2099194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2100194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2101194d53e6SMatthew G. Knepley . t - current time
2102194d53e6SMatthew G. Knepley . x - coordinates of the current point
2103194d53e6SMatthew G. Knepley . n - unit normal at the current point
210497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
210597b6e6e8SMatthew G. Knepley . constants - constant parameters
2106194d53e6SMatthew G. Knepley - f0 - output values at the current point
2107194d53e6SMatthew G. Knepley 
2108194d53e6SMatthew G. Knepley   Level: intermediate
2109194d53e6SMatthew G. Knepley 
2110dce8aebaSBarry Smith   Note:
2111dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2112dce8aebaSBarry 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
2113dce8aebaSBarry Smith 
2114dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2115194d53e6SMatthew G. Knepley @*/
2116d71ae5a4SJacob 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[]))
2117d71ae5a4SJacob Faibussowitsch {
21186528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
21196528b96dSMatthew G. Knepley   PetscInt          n0, n1;
21206528b96dSMatthew G. Knepley 
21212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
21226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
212363a3b9bcSJacob 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);
21249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
21256528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
21266528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
21272764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
21282764a2aaSMatthew G. Knepley }
21292764a2aaSMatthew G. Knepley 
2130194d53e6SMatthew G. Knepley /*@C
2131194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2132194d53e6SMatthew G. Knepley 
2133194d53e6SMatthew G. Knepley   Not collective
2134194d53e6SMatthew G. Knepley 
2135194d53e6SMatthew G. Knepley   Input Parameters:
2136dce8aebaSBarry Smith + ds - The `PetscDS`
2137194d53e6SMatthew G. Knepley . f  - The test field number
2138194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2139194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2140194d53e6SMatthew G. Knepley 
2141dce8aebaSBarry Smith   Calling sequence for the callbacks f0 and f1:
2142dce8aebaSBarry Smith .vb
2143dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2144dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2145dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2146dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2147dce8aebaSBarry Smith .ve
2148194d53e6SMatthew G. Knepley + dim - the spatial dimension
2149194d53e6SMatthew G. Knepley . Nf - the number of fields
2150194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2151194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2152194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2153194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2154194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2155194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2156194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2157194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2158194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2159194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2160194d53e6SMatthew G. Knepley . t - current time
2161194d53e6SMatthew G. Knepley . x - coordinates of the current point
2162194d53e6SMatthew G. Knepley . n - unit normal at the current point
216397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
216497b6e6e8SMatthew G. Knepley . constants - constant parameters
2165194d53e6SMatthew G. Knepley - f0 - output values at the current point
2166194d53e6SMatthew G. Knepley 
2167194d53e6SMatthew G. Knepley   Level: intermediate
2168194d53e6SMatthew G. Knepley 
2169dce8aebaSBarry Smith   Note:
2170dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2171dce8aebaSBarry 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
2172dce8aebaSBarry Smith 
2173dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2174194d53e6SMatthew G. Knepley @*/
2175d71ae5a4SJacob 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[]))
2176d71ae5a4SJacob Faibussowitsch {
21772764a2aaSMatthew G. Knepley   PetscFunctionBegin;
21786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
21812764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
21822764a2aaSMatthew G. Knepley }
21832764a2aaSMatthew G. Knepley 
218427f02ce8SMatthew G. Knepley /*@
2185dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
218627f02ce8SMatthew G. Knepley 
218727f02ce8SMatthew G. Knepley   Not collective
218827f02ce8SMatthew G. Knepley 
218927f02ce8SMatthew G. Knepley   Input Parameter:
2190dce8aebaSBarry Smith . ds - The `PetscDS`
219127f02ce8SMatthew G. Knepley 
219227f02ce8SMatthew G. Knepley   Output Parameter:
219327f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
219427f02ce8SMatthew G. Knepley 
219527f02ce8SMatthew G. Knepley   Level: intermediate
219627f02ce8SMatthew G. Knepley 
2197dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
219827f02ce8SMatthew G. Knepley @*/
2199d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2200d71ae5a4SJacob Faibussowitsch {
220127f02ce8SMatthew G. Knepley   PetscFunctionBegin;
22026528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
22036528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
22049566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
220527f02ce8SMatthew G. Knepley   PetscFunctionReturn(0);
220627f02ce8SMatthew G. Knepley }
220727f02ce8SMatthew G. Knepley 
2208194d53e6SMatthew G. Knepley /*@C
2209194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2210194d53e6SMatthew G. Knepley 
2211194d53e6SMatthew G. Knepley   Not collective
2212194d53e6SMatthew G. Knepley 
2213194d53e6SMatthew G. Knepley   Input Parameters:
2214dce8aebaSBarry Smith + ds - The `PetscDS`
2215194d53e6SMatthew G. Knepley . f  - The test field number
2216194d53e6SMatthew G. Knepley - g  - The field number
2217194d53e6SMatthew G. Knepley 
2218194d53e6SMatthew G. Knepley   Output Parameters:
2219194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2220194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2221194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2222194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2223194d53e6SMatthew G. Knepley 
2224dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2225dce8aebaSBarry Smith .vb
2226dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2227dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2228dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2229dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2230dce8aebaSBarry Smith .ve
2231194d53e6SMatthew G. Knepley + dim - the spatial dimension
2232194d53e6SMatthew G. Knepley . Nf - the number of fields
2233194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2234194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2235194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2236194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2237194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2238194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2239194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2240194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2241194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2242194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2243194d53e6SMatthew G. Knepley . t - current time
22442aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2245194d53e6SMatthew G. Knepley . x - coordinates of the current point
2246194d53e6SMatthew G. Knepley . n - normal at the current point
224797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
224897b6e6e8SMatthew G. Knepley . constants - constant parameters
2249194d53e6SMatthew G. Knepley - g0 - output values at the current point
2250194d53e6SMatthew G. Knepley 
2251194d53e6SMatthew G. Knepley   Level: intermediate
2252194d53e6SMatthew G. Knepley 
2253dce8aebaSBarry Smith   Note:
2254dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2255dce8aebaSBarry 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
2256dce8aebaSBarry Smith 
2257dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2258194d53e6SMatthew G. Knepley @*/
2259d71ae5a4SJacob 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[]))
2260d71ae5a4SJacob Faibussowitsch {
22616528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
22626528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
22636528b96dSMatthew G. Knepley 
22642764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22656528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
226663a3b9bcSJacob 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);
226763a3b9bcSJacob 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);
22689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
22696528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
22706528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
22716528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
22726528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
22732764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
22742764a2aaSMatthew G. Knepley }
22752764a2aaSMatthew G. Knepley 
2276194d53e6SMatthew G. Knepley /*@C
2277194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2278194d53e6SMatthew G. Knepley 
2279194d53e6SMatthew G. Knepley   Not collective
2280194d53e6SMatthew G. Knepley 
2281194d53e6SMatthew G. Knepley   Input Parameters:
22826528b96dSMatthew G. Knepley + ds - The PetscDS
2283194d53e6SMatthew G. Knepley . f  - The test field number
2284194d53e6SMatthew G. Knepley . g  - The field number
2285194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2286194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2287194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2288194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2289194d53e6SMatthew G. Knepley 
2290dce8aebaSBarry Smith   Calling sequence for the callbacks g0, g1, g2 and g3:
2291dce8aebaSBarry Smith .vb
2292dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2293dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2294dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2295dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2296dce8aebaSBarry Smith .ve
2297194d53e6SMatthew G. Knepley + dim - the spatial dimension
2298194d53e6SMatthew G. Knepley . Nf - the number of fields
2299194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2300194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2301194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2302194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2303194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2304194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2305194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2306194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2307194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2308194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2309194d53e6SMatthew G. Knepley . t - current time
23102aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2311194d53e6SMatthew G. Knepley . x - coordinates of the current point
2312194d53e6SMatthew G. Knepley . n - normal at the current point
231397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
231497b6e6e8SMatthew G. Knepley . constants - constant parameters
2315194d53e6SMatthew G. Knepley - g0 - output values at the current point
2316194d53e6SMatthew G. Knepley 
2317194d53e6SMatthew G. Knepley   Level: intermediate
2318194d53e6SMatthew G. Knepley 
2319dce8aebaSBarry Smith   Note:
2320dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2321dce8aebaSBarry 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
2322dce8aebaSBarry Smith 
2323dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2324194d53e6SMatthew G. Knepley @*/
2325d71ae5a4SJacob 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[]))
2326d71ae5a4SJacob Faibussowitsch {
23272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23292764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
23302764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
23312764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
23322764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
233363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
233463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
23359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
23362764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
23372764a2aaSMatthew G. Knepley }
23382764a2aaSMatthew G. Knepley 
233927f02ce8SMatthew G. Knepley /*@
234027f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
234127f02ce8SMatthew G. Knepley 
234227f02ce8SMatthew G. Knepley   Not collective
234327f02ce8SMatthew G. Knepley 
234427f02ce8SMatthew G. Knepley   Input Parameter:
2345dce8aebaSBarry Smith . ds - The `PetscDS`
234627f02ce8SMatthew G. Knepley 
234727f02ce8SMatthew G. Knepley   Output Parameter:
234827f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
234927f02ce8SMatthew G. Knepley 
235027f02ce8SMatthew G. Knepley   Level: intermediate
235127f02ce8SMatthew G. Knepley 
2352dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
235327f02ce8SMatthew G. Knepley @*/
2354d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2355d71ae5a4SJacob Faibussowitsch {
235627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23586528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
23599566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
236027f02ce8SMatthew G. Knepley   PetscFunctionReturn(0);
236127f02ce8SMatthew G. Knepley }
236227f02ce8SMatthew G. Knepley 
236327f02ce8SMatthew G. Knepley /*@C
236427f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
236527f02ce8SMatthew G. Knepley 
236627f02ce8SMatthew G. Knepley   Not collective
236727f02ce8SMatthew G. Knepley 
236827f02ce8SMatthew G. Knepley   Input Parameters:
2369dce8aebaSBarry Smith + ds - The `PetscDS`
237027f02ce8SMatthew G. Knepley . f  - The test field number
237127f02ce8SMatthew G. Knepley - g  - The field number
237227f02ce8SMatthew G. Knepley 
237327f02ce8SMatthew G. Knepley   Output Parameters:
237427f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
237527f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
237627f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
237727f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
237827f02ce8SMatthew G. Knepley 
2379dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2380dce8aebaSBarry Smith .vb
2381dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2382dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2383dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2384dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2385dce8aebaSBarry Smith .ve
238627f02ce8SMatthew G. Knepley + dim - the spatial dimension
238727f02ce8SMatthew G. Knepley . Nf - the number of fields
238827f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
238927f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
239027f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
239127f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
239227f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
239327f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
239427f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
239527f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
239627f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
239727f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
239827f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
239927f02ce8SMatthew G. Knepley . t - current time
240027f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
240127f02ce8SMatthew G. Knepley . x - coordinates of the current point
240227f02ce8SMatthew G. Knepley . n - normal at the current point
240327f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
240427f02ce8SMatthew G. Knepley . constants - constant parameters
240527f02ce8SMatthew G. Knepley - g0 - output values at the current point
240627f02ce8SMatthew G. Knepley 
240727f02ce8SMatthew G. Knepley   Level: intermediate
240827f02ce8SMatthew G. Knepley 
2409dce8aebaSBarry Smith   Note:
2410dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2411dce8aebaSBarry 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
2412dce8aebaSBarry Smith 
2413dce8aebaSBarry Smith   Fortran Note:
2414dce8aebaSBarry Smith   This is not yet available in Fortran.
2415dce8aebaSBarry Smith 
2416dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
241727f02ce8SMatthew G. Knepley @*/
2418d71ae5a4SJacob 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[]))
2419d71ae5a4SJacob Faibussowitsch {
24206528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24216528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24226528b96dSMatthew G. Knepley 
242327f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
242563a3b9bcSJacob 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);
242663a3b9bcSJacob 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);
24279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24286528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24296528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24306528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24316528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
243227f02ce8SMatthew G. Knepley   PetscFunctionReturn(0);
243327f02ce8SMatthew G. Knepley }
243427f02ce8SMatthew G. Knepley 
243527f02ce8SMatthew G. Knepley /*@C
243627f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
243727f02ce8SMatthew G. Knepley 
243827f02ce8SMatthew G. Knepley   Not collective
243927f02ce8SMatthew G. Knepley 
244027f02ce8SMatthew G. Knepley   Input Parameters:
2441dce8aebaSBarry Smith + ds - The `PetscDS`
244227f02ce8SMatthew G. Knepley . f  - The test field number
244327f02ce8SMatthew G. Knepley . g  - The field number
244427f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
244527f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
244627f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
244727f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
244827f02ce8SMatthew G. Knepley 
2449dce8aebaSBarry Smith    Calling sequence for the callbacks g0, g1, g2 and g3:
2450dce8aebaSBarry Smith .vb
2451dce8aebaSBarry Smith   g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2452dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2453dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2454dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2455dce8aebaSBarry Smith .ve
245627f02ce8SMatthew G. Knepley + dim - the spatial dimension
245727f02ce8SMatthew G. Knepley . Nf - the number of fields
245827f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
245927f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
246027f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
246127f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
246227f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
246327f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
246427f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
246527f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
246627f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
246727f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
246827f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
246927f02ce8SMatthew G. Knepley . t - current time
247027f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
247127f02ce8SMatthew G. Knepley . x - coordinates of the current point
247227f02ce8SMatthew G. Knepley . n - normal at the current point
247327f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
247427f02ce8SMatthew G. Knepley . constants - constant parameters
247527f02ce8SMatthew G. Knepley - g0 - output values at the current point
247627f02ce8SMatthew G. Knepley 
247727f02ce8SMatthew G. Knepley   Level: intermediate
247827f02ce8SMatthew G. Knepley 
2479dce8aebaSBarry Smith   Note:
2480dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2481dce8aebaSBarry Smith   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
2482dce8aebaSBarry Smith 
2483dce8aebaSBarry Smith   Fortran Note:
2484dce8aebaSBarry Smith   This is not yet available in Fortran.
2485dce8aebaSBarry Smith 
2486dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
248727f02ce8SMatthew G. Knepley @*/
2488d71ae5a4SJacob 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[]))
2489d71ae5a4SJacob Faibussowitsch {
249027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
249227f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
249327f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
249427f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
249527f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
249663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
249763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
249927f02ce8SMatthew G. Knepley   PetscFunctionReturn(0);
250027f02ce8SMatthew G. Knepley }
250127f02ce8SMatthew G. Knepley 
25020d3e9b51SMatthew G. Knepley /*@C
2503c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2504c371a6d1SMatthew G. Knepley 
2505c371a6d1SMatthew G. Knepley   Not collective
2506c371a6d1SMatthew G. Knepley 
2507c371a6d1SMatthew G. Knepley   Input Parameters:
2508c371a6d1SMatthew G. Knepley + prob - The PetscDS
2509c371a6d1SMatthew G. Knepley - f    - The test field number
2510c371a6d1SMatthew G. Knepley 
2511d8d19677SJose E. Roman   Output Parameters:
251295cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
251395cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2514c371a6d1SMatthew G. Knepley 
2515dce8aebaSBarry Smith   Calling sequence for the solution functions:
2516dce8aebaSBarry Smith .vb
2517dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2518dce8aebaSBarry Smith .ve
2519c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2520c371a6d1SMatthew G. Knepley . t - current time
2521c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2522c371a6d1SMatthew G. Knepley . Nc - the number of field components
2523c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2524c371a6d1SMatthew G. Knepley - ctx - a user context
2525c371a6d1SMatthew G. Knepley 
2526c371a6d1SMatthew G. Knepley   Level: intermediate
2527c371a6d1SMatthew G. Knepley 
2528dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2529c371a6d1SMatthew G. Knepley @*/
2530d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2531d71ae5a4SJacob Faibussowitsch {
2532c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2533c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
253463a3b9bcSJacob 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);
25359371c9d4SSatish Balay   if (sol) {
25369371c9d4SSatish Balay     PetscValidPointer(sol, 3);
25379371c9d4SSatish Balay     *sol = prob->exactSol[f];
25389371c9d4SSatish Balay   }
25399371c9d4SSatish Balay   if (ctx) {
25409371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
25419371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
25429371c9d4SSatish Balay   }
2543c371a6d1SMatthew G. Knepley   PetscFunctionReturn(0);
2544c371a6d1SMatthew G. Knepley }
2545c371a6d1SMatthew G. Knepley 
2546c371a6d1SMatthew G. Knepley /*@C
2547578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2548c371a6d1SMatthew G. Knepley 
2549c371a6d1SMatthew G. Knepley   Not collective
2550c371a6d1SMatthew G. Knepley 
2551c371a6d1SMatthew G. Knepley   Input Parameters:
2552dce8aebaSBarry Smith + prob - The `PetscDS`
2553c371a6d1SMatthew G. Knepley . f    - The test field number
255495cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
255595cbbfd3SMatthew G. Knepley - ctx  - solution context or NULL
2556c371a6d1SMatthew G. Knepley 
2557dce8aebaSBarry Smith   Calling sequence for solution functions:
2558dce8aebaSBarry Smith .vb
2559dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2560dce8aebaSBarry Smith .ve
2561c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2562c371a6d1SMatthew G. Knepley . t - current time
2563c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2564c371a6d1SMatthew G. Knepley . Nc - the number of field components
2565c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2566c371a6d1SMatthew G. Knepley - ctx - a user context
2567c371a6d1SMatthew G. Knepley 
2568c371a6d1SMatthew G. Knepley   Level: intermediate
2569c371a6d1SMatthew G. Knepley 
2570dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2571c371a6d1SMatthew G. Knepley @*/
2572d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2573d71ae5a4SJacob Faibussowitsch {
2574c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2575c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
257663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
25779566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
25789371c9d4SSatish Balay   if (sol) {
25799371c9d4SSatish Balay     PetscValidFunction(sol, 3);
25809371c9d4SSatish Balay     prob->exactSol[f] = sol;
25819371c9d4SSatish Balay   }
25829371c9d4SSatish Balay   if (ctx) {
25839371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
25849371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
25859371c9d4SSatish Balay   }
2586c371a6d1SMatthew G. Knepley   PetscFunctionReturn(0);
2587c371a6d1SMatthew G. Knepley }
2588c371a6d1SMatthew G. Knepley 
25895638fd0eSMatthew G. Knepley /*@C
2590f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2591f2cacb80SMatthew G. Knepley 
2592f2cacb80SMatthew G. Knepley   Not collective
2593f2cacb80SMatthew G. Knepley 
2594f2cacb80SMatthew G. Knepley   Input Parameters:
2595dce8aebaSBarry Smith + prob - The `PetscDS`
2596f2cacb80SMatthew G. Knepley - f    - The test field number
2597f2cacb80SMatthew G. Knepley 
2598d8d19677SJose E. Roman   Output Parameters:
2599f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2600f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2601f2cacb80SMatthew G. Knepley 
2602dce8aebaSBarry Smith   Calling sequence for the solution functions:
2603dce8aebaSBarry Smith .vb
2604dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2605dce8aebaSBarry Smith .ve
2606f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2607f2cacb80SMatthew G. Knepley . t - current time
2608f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2609f2cacb80SMatthew G. Knepley . Nc - the number of field components
2610f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2611f2cacb80SMatthew G. Knepley - ctx - a user context
2612f2cacb80SMatthew G. Knepley 
2613f2cacb80SMatthew G. Knepley   Level: intermediate
2614f2cacb80SMatthew G. Knepley 
2615dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2616f2cacb80SMatthew G. Knepley @*/
2617d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2618d71ae5a4SJacob Faibussowitsch {
2619f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2620f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
262163a3b9bcSJacob 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);
26229371c9d4SSatish Balay   if (sol) {
26239371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26249371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
26259371c9d4SSatish Balay   }
26269371c9d4SSatish Balay   if (ctx) {
26279371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26289371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
26299371c9d4SSatish Balay   }
2630f2cacb80SMatthew G. Knepley   PetscFunctionReturn(0);
2631f2cacb80SMatthew G. Knepley }
2632f2cacb80SMatthew G. Knepley 
2633f2cacb80SMatthew G. Knepley /*@C
2634f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2635f2cacb80SMatthew G. Knepley 
2636f2cacb80SMatthew G. Knepley   Not collective
2637f2cacb80SMatthew G. Knepley 
2638f2cacb80SMatthew G. Knepley   Input Parameters:
2639dce8aebaSBarry Smith + prob - The `PetscDS`
2640f2cacb80SMatthew G. Knepley . f    - The test field number
2641f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
2642f2cacb80SMatthew G. Knepley - ctx  - time derivative of the solution context or NULL
2643f2cacb80SMatthew G. Knepley 
2644dce8aebaSBarry Smith   Calling sequence for solution functions:
2645dce8aebaSBarry Smith .vb
2646dce8aebaSBarry Smith   sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2647dce8aebaSBarry Smith .ve
2648f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2649f2cacb80SMatthew G. Knepley . t - current time
2650f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2651f2cacb80SMatthew G. Knepley . Nc - the number of field components
2652f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2653f2cacb80SMatthew G. Knepley - ctx - a user context
2654f2cacb80SMatthew G. Knepley 
2655f2cacb80SMatthew G. Knepley   Level: intermediate
2656f2cacb80SMatthew G. Knepley 
2657dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2658f2cacb80SMatthew G. Knepley @*/
2659d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2660d71ae5a4SJacob Faibussowitsch {
2661f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2662f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
266363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
26649566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
26659371c9d4SSatish Balay   if (sol) {
26669371c9d4SSatish Balay     PetscValidFunction(sol, 3);
26679371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
26689371c9d4SSatish Balay   }
26699371c9d4SSatish Balay   if (ctx) {
26709371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
26719371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
26729371c9d4SSatish Balay   }
2673f2cacb80SMatthew G. Knepley   PetscFunctionReturn(0);
2674f2cacb80SMatthew G. Knepley }
2675f2cacb80SMatthew G. Knepley 
2676f2cacb80SMatthew G. Knepley /*@C
267797b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
267897b6e6e8SMatthew G. Knepley 
267997b6e6e8SMatthew G. Knepley   Not collective
268097b6e6e8SMatthew G. Knepley 
268197b6e6e8SMatthew G. Knepley   Input Parameter:
2682dce8aebaSBarry Smith . prob - The `PetscDS` object
268397b6e6e8SMatthew G. Knepley 
268497b6e6e8SMatthew G. Knepley   Output Parameters:
268597b6e6e8SMatthew G. Knepley + numConstants - The number of constants
268697b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
268797b6e6e8SMatthew G. Knepley 
268897b6e6e8SMatthew G. Knepley   Level: intermediate
268997b6e6e8SMatthew G. Knepley 
2690dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
269197b6e6e8SMatthew G. Knepley @*/
2692d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2693d71ae5a4SJacob Faibussowitsch {
269497b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
269597b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
26969371c9d4SSatish Balay   if (numConstants) {
26979371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
26989371c9d4SSatish Balay     *numConstants = prob->numConstants;
26999371c9d4SSatish Balay   }
27009371c9d4SSatish Balay   if (constants) {
27019371c9d4SSatish Balay     PetscValidPointer(constants, 3);
27029371c9d4SSatish Balay     *constants = prob->constants;
27039371c9d4SSatish Balay   }
270497b6e6e8SMatthew G. Knepley   PetscFunctionReturn(0);
270597b6e6e8SMatthew G. Knepley }
270697b6e6e8SMatthew G. Knepley 
27070d3e9b51SMatthew G. Knepley /*@C
270897b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
270997b6e6e8SMatthew G. Knepley 
271097b6e6e8SMatthew G. Knepley   Not collective
271197b6e6e8SMatthew G. Knepley 
271297b6e6e8SMatthew G. Knepley   Input Parameters:
2713dce8aebaSBarry Smith + prob         - The `PetscDS` object
271497b6e6e8SMatthew G. Knepley . numConstants - The number of constants
271597b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
271697b6e6e8SMatthew G. Knepley 
271797b6e6e8SMatthew G. Knepley   Level: intermediate
271897b6e6e8SMatthew G. Knepley 
2719dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
272097b6e6e8SMatthew G. Knepley @*/
2721d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2722d71ae5a4SJacob Faibussowitsch {
272397b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
272497b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
272597b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
27269566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
272797b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
272897b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
27299566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
273020be0f5bSMatthew G. Knepley     } else {
273120be0f5bSMatthew G. Knepley       prob->constants = NULL;
273220be0f5bSMatthew G. Knepley     }
273320be0f5bSMatthew G. Knepley   }
273420be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2735dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
27369566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
273797b6e6e8SMatthew G. Knepley   }
273897b6e6e8SMatthew G. Knepley   PetscFunctionReturn(0);
273997b6e6e8SMatthew G. Knepley }
274097b6e6e8SMatthew G. Knepley 
27414cd1e086SMatthew G. Knepley /*@
27424cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
27434cd1e086SMatthew G. Knepley 
27444cd1e086SMatthew G. Knepley   Not collective
27454cd1e086SMatthew G. Knepley 
27464cd1e086SMatthew G. Knepley   Input Parameters:
2747dce8aebaSBarry Smith + prob - The `PetscDS` object
27484cd1e086SMatthew G. Knepley - disc - The discretization object
27494cd1e086SMatthew G. Knepley 
27504cd1e086SMatthew G. Knepley   Output Parameter:
27514cd1e086SMatthew G. Knepley . f - The field number
27524cd1e086SMatthew G. Knepley 
27534cd1e086SMatthew G. Knepley   Level: beginner
27544cd1e086SMatthew G. Knepley 
2755dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
27564cd1e086SMatthew G. Knepley @*/
2757d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2758d71ae5a4SJacob Faibussowitsch {
27594cd1e086SMatthew G. Knepley   PetscInt g;
27604cd1e086SMatthew G. Knepley 
27614cd1e086SMatthew G. Knepley   PetscFunctionBegin;
27624cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2763dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
27644cd1e086SMatthew G. Knepley   *f = -1;
27659371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
27669371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
27679371c9d4SSatish Balay   }
276808401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
27694cd1e086SMatthew G. Knepley   *f = g;
27704cd1e086SMatthew G. Knepley   PetscFunctionReturn(0);
27714cd1e086SMatthew G. Knepley }
27724cd1e086SMatthew G. Knepley 
27734cd1e086SMatthew G. Knepley /*@
27744cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
27754cd1e086SMatthew G. Knepley 
27764cd1e086SMatthew G. Knepley   Not collective
27774cd1e086SMatthew G. Knepley 
27784cd1e086SMatthew G. Knepley   Input Parameters:
2779dce8aebaSBarry Smith + prob - The `PetscDS` object
27804cd1e086SMatthew G. Knepley - f - The field number
27814cd1e086SMatthew G. Knepley 
27824cd1e086SMatthew G. Knepley   Output Parameter:
27834cd1e086SMatthew G. Knepley . size - The size
27844cd1e086SMatthew G. Knepley 
27854cd1e086SMatthew G. Knepley   Level: beginner
27864cd1e086SMatthew G. Knepley 
2787dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
27884cd1e086SMatthew G. Knepley @*/
2789d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2790d71ae5a4SJacob Faibussowitsch {
27914cd1e086SMatthew G. Knepley   PetscFunctionBegin;
27924cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2793dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
279463a3b9bcSJacob 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);
27959566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2796d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
27974cd1e086SMatthew G. Knepley   PetscFunctionReturn(0);
27984cd1e086SMatthew G. Knepley }
27994cd1e086SMatthew G. Knepley 
2800bc4ae4beSMatthew G. Knepley /*@
2801bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2802bc4ae4beSMatthew G. Knepley 
2803bc4ae4beSMatthew G. Knepley   Not collective
2804bc4ae4beSMatthew G. Knepley 
2805bc4ae4beSMatthew G. Knepley   Input Parameters:
2806dce8aebaSBarry Smith + prob - The `PetscDS` object
2807bc4ae4beSMatthew G. Knepley - f - The field number
2808bc4ae4beSMatthew G. Knepley 
2809bc4ae4beSMatthew G. Knepley   Output Parameter:
2810bc4ae4beSMatthew G. Knepley . off - The offset
2811bc4ae4beSMatthew G. Knepley 
2812bc4ae4beSMatthew G. Knepley   Level: beginner
2813bc4ae4beSMatthew G. Knepley 
2814dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2815bc4ae4beSMatthew G. Knepley @*/
2816d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2817d71ae5a4SJacob Faibussowitsch {
28184cd1e086SMatthew G. Knepley   PetscInt size, g;
28192764a2aaSMatthew G. Knepley 
28202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
28212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2822dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
282363a3b9bcSJacob 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);
28242764a2aaSMatthew G. Knepley   *off = 0;
28252764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
28269566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
28274cd1e086SMatthew G. Knepley     *off += size;
28282764a2aaSMatthew G. Knepley   }
28292764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
28302764a2aaSMatthew G. Knepley }
28312764a2aaSMatthew G. Knepley 
2832bc4ae4beSMatthew G. Knepley /*@
28335fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
28345fedec97SMatthew G. Knepley 
28355fedec97SMatthew G. Knepley   Not collective
28365fedec97SMatthew G. Knepley 
28375fedec97SMatthew G. Knepley   Input Parameters:
2838dce8aebaSBarry Smith + prob - The `PetscDS` object
28395fedec97SMatthew G. Knepley - f - The field number
28405fedec97SMatthew G. Knepley 
28415fedec97SMatthew G. Knepley   Output Parameter:
28425fedec97SMatthew G. Knepley . off - The offset
28435fedec97SMatthew G. Knepley 
28445fedec97SMatthew G. Knepley   Level: beginner
28455fedec97SMatthew G. Knepley 
2846dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28475fedec97SMatthew G. Knepley @*/
2848d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2849d71ae5a4SJacob Faibussowitsch {
28505fedec97SMatthew G. Knepley   PetscInt size, g;
28515fedec97SMatthew G. Knepley 
28525fedec97SMatthew G. Knepley   PetscFunctionBegin;
28535fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2854dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
285563a3b9bcSJacob 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);
28565fedec97SMatthew G. Knepley   *off = 0;
28575fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
28585fedec97SMatthew G. Knepley     PetscBool cohesive;
28595fedec97SMatthew G. Knepley 
28609566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
28619566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
28625fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
28635fedec97SMatthew G. Knepley   }
28645fedec97SMatthew G. Knepley   PetscFunctionReturn(0);
28655fedec97SMatthew G. Knepley }
28665fedec97SMatthew G. Knepley 
28675fedec97SMatthew G. Knepley /*@
286847e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2869bc4ae4beSMatthew G. Knepley 
2870bc4ae4beSMatthew G. Knepley   Not collective
2871bc4ae4beSMatthew G. Knepley 
287247e57110SSander Arens   Input Parameter:
2873dce8aebaSBarry Smith . prob - The `PetscDS` object
2874bc4ae4beSMatthew G. Knepley 
2875bc4ae4beSMatthew G. Knepley   Output Parameter:
287647e57110SSander Arens . dimensions - The number of dimensions
2877bc4ae4beSMatthew G. Knepley 
2878bc4ae4beSMatthew G. Knepley   Level: beginner
2879bc4ae4beSMatthew G. Knepley 
2880dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2881bc4ae4beSMatthew G. Knepley @*/
2882d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2883d71ae5a4SJacob Faibussowitsch {
28842764a2aaSMatthew G. Knepley   PetscFunctionBegin;
28852764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28869566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
288747e57110SSander Arens   PetscValidPointer(dimensions, 2);
288847e57110SSander Arens   *dimensions = prob->Nb;
288947e57110SSander Arens   PetscFunctionReturn(0);
28906ce16762SMatthew G. Knepley }
289147e57110SSander Arens 
289247e57110SSander Arens /*@
289347e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
289447e57110SSander Arens 
289547e57110SSander Arens   Not collective
289647e57110SSander Arens 
289747e57110SSander Arens   Input Parameter:
2898dce8aebaSBarry Smith . prob - The `PetscDS` object
289947e57110SSander Arens 
290047e57110SSander Arens   Output Parameter:
290147e57110SSander Arens . components - The number of components
290247e57110SSander Arens 
290347e57110SSander Arens   Level: beginner
290447e57110SSander Arens 
2905dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
290647e57110SSander Arens @*/
2907d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
2908d71ae5a4SJacob Faibussowitsch {
290947e57110SSander Arens   PetscFunctionBegin;
291047e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29119566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
291247e57110SSander Arens   PetscValidPointer(components, 2);
291347e57110SSander Arens   *components = prob->Nc;
29146ce16762SMatthew G. Knepley   PetscFunctionReturn(0);
29156ce16762SMatthew G. Knepley }
29166ce16762SMatthew G. Knepley 
29176ce16762SMatthew G. Knepley /*@
29186ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
29196ce16762SMatthew G. Knepley 
29206ce16762SMatthew G. Knepley   Not collective
29216ce16762SMatthew G. Knepley 
29226ce16762SMatthew G. Knepley   Input Parameters:
2923dce8aebaSBarry Smith + prob - The `PetscDS` object
29246ce16762SMatthew G. Knepley - f - The field number
29256ce16762SMatthew G. Knepley 
29266ce16762SMatthew G. Knepley   Output Parameter:
29276ce16762SMatthew G. Knepley . off - The offset
29286ce16762SMatthew G. Knepley 
29296ce16762SMatthew G. Knepley   Level: beginner
29306ce16762SMatthew G. Knepley 
2931dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29326ce16762SMatthew G. Knepley @*/
2933d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
2934d71ae5a4SJacob Faibussowitsch {
29356ce16762SMatthew G. Knepley   PetscFunctionBegin;
29366ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2937dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
293863a3b9bcSJacob 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);
29399566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
294047e57110SSander Arens   *off = prob->off[f];
29412764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
29422764a2aaSMatthew G. Knepley }
29432764a2aaSMatthew G. Knepley 
2944194d53e6SMatthew G. Knepley /*@
2945194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
2946194d53e6SMatthew G. Knepley 
2947194d53e6SMatthew G. Knepley   Not collective
2948194d53e6SMatthew G. Knepley 
2949194d53e6SMatthew G. Knepley   Input Parameter:
2950dce8aebaSBarry Smith . prob - The `PetscDS` object
2951194d53e6SMatthew G. Knepley 
2952194d53e6SMatthew G. Knepley   Output Parameter:
2953194d53e6SMatthew G. Knepley . offsets - The offsets
2954194d53e6SMatthew G. Knepley 
2955194d53e6SMatthew G. Knepley   Level: beginner
2956194d53e6SMatthew G. Knepley 
2957dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2958194d53e6SMatthew G. Knepley @*/
2959d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
2960d71ae5a4SJacob Faibussowitsch {
2961194d53e6SMatthew G. Knepley   PetscFunctionBegin;
2962194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2963194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
29649566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2965194d53e6SMatthew G. Knepley   *offsets = prob->off;
2966194d53e6SMatthew G. Knepley   PetscFunctionReturn(0);
2967194d53e6SMatthew G. Knepley }
2968194d53e6SMatthew G. Knepley 
2969194d53e6SMatthew G. Knepley /*@
2970194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
2971194d53e6SMatthew G. Knepley 
2972194d53e6SMatthew G. Knepley   Not collective
2973194d53e6SMatthew G. Knepley 
2974194d53e6SMatthew G. Knepley   Input Parameter:
2975dce8aebaSBarry Smith . prob - The `PetscDS` object
2976194d53e6SMatthew G. Knepley 
2977194d53e6SMatthew G. Knepley   Output Parameter:
2978194d53e6SMatthew G. Knepley . offsets - The offsets
2979194d53e6SMatthew G. Knepley 
2980194d53e6SMatthew G. Knepley   Level: beginner
2981194d53e6SMatthew G. Knepley 
2982dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2983194d53e6SMatthew G. Knepley @*/
2984d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
2985d71ae5a4SJacob Faibussowitsch {
2986194d53e6SMatthew G. Knepley   PetscFunctionBegin;
2987194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2988194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
29899566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2990194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
2991194d53e6SMatthew G. Knepley   PetscFunctionReturn(0);
2992194d53e6SMatthew G. Knepley }
2993194d53e6SMatthew G. Knepley 
29949ee2af8cSMatthew G. Knepley /*@
29959ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
29969ee2af8cSMatthew G. Knepley 
29979ee2af8cSMatthew G. Knepley   Not collective
29989ee2af8cSMatthew G. Knepley 
29999ee2af8cSMatthew G. Knepley   Input Parameters:
3000dce8aebaSBarry Smith + ds - The `PetscDS` object
30019ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
30029ee2af8cSMatthew G. Knepley 
30039ee2af8cSMatthew G. Knepley   Output Parameter:
30049ee2af8cSMatthew G. Knepley . offsets - The offsets
30059ee2af8cSMatthew G. Knepley 
30069ee2af8cSMatthew G. Knepley   Level: beginner
30079ee2af8cSMatthew G. Knepley 
3008dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30099ee2af8cSMatthew G. Knepley @*/
3010d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3011d71ae5a4SJacob Faibussowitsch {
30129ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
30139ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
30149ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
301528b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
301663a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
30179566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
30189ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
30199ee2af8cSMatthew G. Knepley   PetscFunctionReturn(0);
30209ee2af8cSMatthew G. Knepley }
30219ee2af8cSMatthew G. Knepley 
30229ee2af8cSMatthew G. Knepley /*@
30239ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
30249ee2af8cSMatthew G. Knepley 
30259ee2af8cSMatthew G. Knepley   Not collective
30269ee2af8cSMatthew G. Knepley 
30279ee2af8cSMatthew G. Knepley   Input Parameters:
3028dce8aebaSBarry Smith + ds - The `PetscDS` object
30299ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
30309ee2af8cSMatthew G. Knepley 
30319ee2af8cSMatthew G. Knepley   Output Parameter:
30329ee2af8cSMatthew G. Knepley . offsets - The offsets
30339ee2af8cSMatthew G. Knepley 
30349ee2af8cSMatthew G. Knepley   Level: beginner
30359ee2af8cSMatthew G. Knepley 
3036dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30379ee2af8cSMatthew G. Knepley @*/
3038d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3039d71ae5a4SJacob Faibussowitsch {
30409ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
30419ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
30429ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
304328b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
304463a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
30459566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
30469ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
30479ee2af8cSMatthew G. Knepley   PetscFunctionReturn(0);
30489ee2af8cSMatthew G. Knepley }
30499ee2af8cSMatthew G. Knepley 
305068c9edb9SMatthew G. Knepley /*@C
305168c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
305268c9edb9SMatthew G. Knepley 
305368c9edb9SMatthew G. Knepley   Not collective
305468c9edb9SMatthew G. Knepley 
305568c9edb9SMatthew G. Knepley   Input Parameter:
3056dce8aebaSBarry Smith . prob - The `PetscDS` object
305768c9edb9SMatthew G. Knepley 
3058ef0bb6c7SMatthew G. Knepley   Output Parameter:
3059ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
306068c9edb9SMatthew G. Knepley 
306168c9edb9SMatthew G. Knepley   Level: intermediate
306268c9edb9SMatthew G. Knepley 
3063dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
306468c9edb9SMatthew G. Knepley @*/
3065d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3066d71ae5a4SJacob Faibussowitsch {
30672764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30682764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3069ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
30709566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3071ef0bb6c7SMatthew G. Knepley   *T = prob->T;
30722764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
30732764a2aaSMatthew G. Knepley }
30742764a2aaSMatthew G. Knepley 
307568c9edb9SMatthew G. Knepley /*@C
30764d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
307768c9edb9SMatthew G. Knepley 
307868c9edb9SMatthew G. Knepley   Not collective
307968c9edb9SMatthew G. Knepley 
308068c9edb9SMatthew G. Knepley   Input Parameter:
3081dce8aebaSBarry Smith . prob - The `PetscDS` object
308268c9edb9SMatthew G. Knepley 
3083ef0bb6c7SMatthew G. Knepley   Output Parameter:
3084a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
308568c9edb9SMatthew G. Knepley 
308668c9edb9SMatthew G. Knepley   Level: intermediate
308768c9edb9SMatthew G. Knepley 
3088dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
308968c9edb9SMatthew G. Knepley @*/
3090d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3091d71ae5a4SJacob Faibussowitsch {
30922764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30932764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3094ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
30959566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3096ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
30972764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
30982764a2aaSMatthew G. Knepley }
30992764a2aaSMatthew G. Knepley 
3100d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3101d71ae5a4SJacob Faibussowitsch {
31022764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31032764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31049566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
31059371c9d4SSatish Balay   if (u) {
31069371c9d4SSatish Balay     PetscValidPointer(u, 2);
31079371c9d4SSatish Balay     *u = prob->u;
31089371c9d4SSatish Balay   }
31099371c9d4SSatish Balay   if (u_t) {
31109371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
31119371c9d4SSatish Balay     *u_t = prob->u_t;
31129371c9d4SSatish Balay   }
31139371c9d4SSatish Balay   if (u_x) {
31149371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
31159371c9d4SSatish Balay     *u_x = prob->u_x;
31169371c9d4SSatish Balay   }
31172764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
31182764a2aaSMatthew G. Knepley }
31192764a2aaSMatthew G. Knepley 
3120d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3121d71ae5a4SJacob Faibussowitsch {
31222764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31232764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31249566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
31259371c9d4SSatish Balay   if (f0) {
31269371c9d4SSatish Balay     PetscValidPointer(f0, 2);
31279371c9d4SSatish Balay     *f0 = prob->f0;
31289371c9d4SSatish Balay   }
31299371c9d4SSatish Balay   if (f1) {
31309371c9d4SSatish Balay     PetscValidPointer(f1, 3);
31319371c9d4SSatish Balay     *f1 = prob->f1;
31329371c9d4SSatish Balay   }
31339371c9d4SSatish Balay   if (g0) {
31349371c9d4SSatish Balay     PetscValidPointer(g0, 4);
31359371c9d4SSatish Balay     *g0 = prob->g0;
31369371c9d4SSatish Balay   }
31379371c9d4SSatish Balay   if (g1) {
31389371c9d4SSatish Balay     PetscValidPointer(g1, 5);
31399371c9d4SSatish Balay     *g1 = prob->g1;
31409371c9d4SSatish Balay   }
31419371c9d4SSatish Balay   if (g2) {
31429371c9d4SSatish Balay     PetscValidPointer(g2, 6);
31439371c9d4SSatish Balay     *g2 = prob->g2;
31449371c9d4SSatish Balay   }
31459371c9d4SSatish Balay   if (g3) {
31469371c9d4SSatish Balay     PetscValidPointer(g3, 7);
31479371c9d4SSatish Balay     *g3 = prob->g3;
31489371c9d4SSatish Balay   }
31492764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
31502764a2aaSMatthew G. Knepley }
31512764a2aaSMatthew G. Knepley 
3152d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3153d71ae5a4SJacob Faibussowitsch {
31542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31552764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31569566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
31579371c9d4SSatish Balay   if (x) {
31589371c9d4SSatish Balay     PetscValidPointer(x, 2);
31599371c9d4SSatish Balay     *x = prob->x;
31609371c9d4SSatish Balay   }
31619371c9d4SSatish Balay   if (basisReal) {
31629371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
31639371c9d4SSatish Balay     *basisReal = prob->basisReal;
31649371c9d4SSatish Balay   }
31659371c9d4SSatish Balay   if (basisDerReal) {
31669371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
31679371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
31689371c9d4SSatish Balay   }
31699371c9d4SSatish Balay   if (testReal) {
31709371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
31719371c9d4SSatish Balay     *testReal = prob->testReal;
31729371c9d4SSatish Balay   }
31739371c9d4SSatish Balay   if (testDerReal) {
31749371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
31759371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
31769371c9d4SSatish Balay   }
31772764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
31782764a2aaSMatthew G. Knepley }
31792764a2aaSMatthew G. Knepley 
318058ebd649SToby Isaac /*@C
3181dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3182dce8aebaSBarry 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
3183dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
318458ebd649SToby Isaac 
3185783e2ec8SMatthew G. Knepley   Collective on ds
3186783e2ec8SMatthew G. Knepley 
318758ebd649SToby Isaac   Input Parameters:
318858ebd649SToby Isaac + ds       - The PetscDS object
3189dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
319058ebd649SToby Isaac . name     - The BC name
319145480ffeSMatthew G. Knepley . label    - The label defining constrained points
3192dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
319345480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
319458ebd649SToby Isaac . field    - The field to constrain
319545480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
319658ebd649SToby Isaac . comps    - An array of constrained component numbers
319758ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3198a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
319958ebd649SToby Isaac - ctx      - An optional user context for bcFunc
320058ebd649SToby Isaac 
320145480ffeSMatthew G. Knepley   Output Parameters:
320245480ffeSMatthew G. Knepley - bd       - The boundary number
320345480ffeSMatthew G. Knepley 
320458ebd649SToby Isaac   Options Database Keys:
320558ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
320658ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
320758ebd649SToby Isaac 
3208dce8aebaSBarry Smith   Level: developer
3209dce8aebaSBarry Smith 
321056cf3b9cSMatthew G. Knepley   Note:
3211dce8aebaSBarry 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:
321256cf3b9cSMatthew G. Knepley 
321356cf3b9cSMatthew G. Knepley $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
321456cf3b9cSMatthew G. Knepley 
3215dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3216dce8aebaSBarry Smith .vb
3217dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3218dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3219dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3220dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3221dce8aebaSBarry Smith .ve
322256cf3b9cSMatthew G. Knepley + dim - the spatial dimension
322356cf3b9cSMatthew G. Knepley . Nf - the number of fields
322456cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
322556cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
322656cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
322756cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
322856cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
322956cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
323056cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
323156cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
323256cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
323356cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
323456cf3b9cSMatthew G. Knepley . t - current time
323556cf3b9cSMatthew G. Knepley . x - coordinates of the current point
323656cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
323756cf3b9cSMatthew G. Knepley . constants - constant parameters
323856cf3b9cSMatthew G. Knepley - bcval - output values at the current point
323956cf3b9cSMatthew G. Knepley 
3240dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
324158ebd649SToby Isaac @*/
3242d71ae5a4SJacob 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)
3243d71ae5a4SJacob Faibussowitsch {
324445480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
324545480ffeSMatthew G. Knepley   PetscInt    n    = 0;
324645480ffeSMatthew G. Knepley   const char *lname;
324758ebd649SToby Isaac 
324858ebd649SToby Isaac   PetscFunctionBegin;
324958ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3250783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
325145480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
325245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
325345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
325445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
325545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3256*dce9da9cSMatthew 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);
3257d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3258d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3259d57bb9dbSMatthew G. Knepley     PetscInt  c;
3260d57bb9dbSMatthew G. Knepley 
32619566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
326263a3b9bcSJacob 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);
3263d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
32641dca8a05SBarry 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);
3265d57bb9dbSMatthew G. Knepley     }
3266d57bb9dbSMatthew G. Knepley   }
32679566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
32689566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
32699566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
32709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
32719566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
32729566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
32739566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
32749566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
32759566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
32769566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3277f971fd6bSMatthew G. Knepley   b->type   = type;
327845480ffeSMatthew G. Knepley   b->label  = label;
327945480ffeSMatthew G. Knepley   b->Nv     = Nv;
328058ebd649SToby Isaac   b->field  = field;
328145480ffeSMatthew G. Knepley   b->Nc     = Nc;
328258ebd649SToby Isaac   b->func   = bcFunc;
328356cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
328458ebd649SToby Isaac   b->ctx    = ctx;
328545480ffeSMatthew G. Knepley   b->next   = NULL;
328645480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
328745480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
328845480ffeSMatthew G. Knepley   while (head) {
328945480ffeSMatthew G. Knepley     if (!head->next) {
329045480ffeSMatthew G. Knepley       head->next = b;
329145480ffeSMatthew G. Knepley       head       = b;
329245480ffeSMatthew G. Knepley     }
329345480ffeSMatthew G. Knepley     head = head->next;
329445480ffeSMatthew G. Knepley     ++n;
329545480ffeSMatthew G. Knepley   }
32969371c9d4SSatish Balay   if (bd) {
32979371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
32989371c9d4SSatish Balay     *bd = n;
32999371c9d4SSatish Balay   }
330045480ffeSMatthew G. Knepley   PetscFunctionReturn(0);
330145480ffeSMatthew G. Knepley }
330245480ffeSMatthew G. Knepley 
330345480ffeSMatthew G. Knepley /*@C
3304dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3305dce8aebaSBarry 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
3306dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
330745480ffeSMatthew G. Knepley 
330845480ffeSMatthew G. Knepley   Collective on ds
330945480ffeSMatthew G. Knepley 
331045480ffeSMatthew G. Knepley   Input Parameters:
3311dce8aebaSBarry Smith + ds       - The `PetscDS` object
3312dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
331345480ffeSMatthew G. Knepley . name     - The BC name
331445480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3315dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
331645480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
331745480ffeSMatthew G. Knepley . field    - The field to constrain
331845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
331945480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
332045480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3321a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
332245480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
332345480ffeSMatthew G. Knepley 
332445480ffeSMatthew G. Knepley   Output Parameters:
332545480ffeSMatthew G. Knepley - bd       - The boundary number
332645480ffeSMatthew G. Knepley 
332745480ffeSMatthew G. Knepley   Options Database Keys:
332845480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
332945480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
333045480ffeSMatthew G. Knepley 
3331dce8aebaSBarry Smith   Calling Sequence of bcFunc() and bcFunc_t():
3332dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3333dce8aebaSBarry Smith .vb
3334dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3335dce8aebaSBarry Smith .ve
3336dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3337dce8aebaSBarry Smith .vb
3338dce8aebaSBarry Smith   bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3339dce8aebaSBarry Smith          const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3340dce8aebaSBarry Smith          const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3341dce8aebaSBarry Smith          PetscReal time, const PetscReal x[], PetscScalar bcval[])
3342dce8aebaSBarry Smith .ve
334345480ffeSMatthew G. Knepley + dim - the spatial dimension
334445480ffeSMatthew G. Knepley . Nf - the number of fields
334545480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
334645480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
334745480ffeSMatthew G. Knepley . u - each field evaluated at the current point
334845480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
334945480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
335045480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
335145480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
335245480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
335345480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
335445480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
335545480ffeSMatthew G. Knepley . t - current time
335645480ffeSMatthew G. Knepley . x - coordinates of the current point
335745480ffeSMatthew G. Knepley . numConstants - number of constant parameters
335845480ffeSMatthew G. Knepley . constants - constant parameters
335945480ffeSMatthew G. Knepley - bcval - output values at the current point
336045480ffeSMatthew G. Knepley 
336145480ffeSMatthew G. Knepley   Level: developer
336245480ffeSMatthew G. Knepley 
3363dce8aebaSBarry Smith   Note:
3364dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3365dce8aebaSBarry Smith 
3366dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
336745480ffeSMatthew G. Knepley @*/
3368d71ae5a4SJacob 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)
3369d71ae5a4SJacob Faibussowitsch {
337045480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
337145480ffeSMatthew G. Knepley   PetscInt   n    = 0;
337245480ffeSMatthew G. Knepley 
337345480ffeSMatthew G. Knepley   PetscFunctionBegin;
337445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
337545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
337645480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
337745480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
337845480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
337945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
338045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
33819566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33829566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33839566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33849566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33859566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33869566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
33879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
33889566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
33899566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
339045480ffeSMatthew G. Knepley   b->type   = type;
339145480ffeSMatthew G. Knepley   b->label  = NULL;
339245480ffeSMatthew G. Knepley   b->Nv     = Nv;
339345480ffeSMatthew G. Knepley   b->field  = field;
339445480ffeSMatthew G. Knepley   b->Nc     = Nc;
339545480ffeSMatthew G. Knepley   b->func   = bcFunc;
339645480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
339745480ffeSMatthew G. Knepley   b->ctx    = ctx;
339845480ffeSMatthew G. Knepley   b->next   = NULL;
339945480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
340045480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
340145480ffeSMatthew G. Knepley   while (head) {
340245480ffeSMatthew G. Knepley     if (!head->next) {
340345480ffeSMatthew G. Knepley       head->next = b;
340445480ffeSMatthew G. Knepley       head       = b;
340545480ffeSMatthew G. Knepley     }
340645480ffeSMatthew G. Knepley     head = head->next;
340745480ffeSMatthew G. Knepley     ++n;
340845480ffeSMatthew G. Knepley   }
34099371c9d4SSatish Balay   if (bd) {
34109371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34119371c9d4SSatish Balay     *bd = n;
34129371c9d4SSatish Balay   }
341358ebd649SToby Isaac   PetscFunctionReturn(0);
341458ebd649SToby Isaac }
341558ebd649SToby Isaac 
3416b67eacb3SMatthew G. Knepley /*@C
3417dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3418dce8aebaSBarry 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
3419dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3420b67eacb3SMatthew G. Knepley 
3421b67eacb3SMatthew G. Knepley   Input Parameters:
3422dce8aebaSBarry Smith + ds       - The `PetscDS` object
3423b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3424dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3425b67eacb3SMatthew G. Knepley . name     - The BC name
342645480ffeSMatthew G. Knepley . label    - The label defining constrained points
3427dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
342845480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3429b67eacb3SMatthew G. Knepley . field    - The field to constrain
343045480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3431b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3432b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3433a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3434b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3435b67eacb3SMatthew G. Knepley 
3436b67eacb3SMatthew G. Knepley   Level: developer
3437b67eacb3SMatthew G. Knepley 
3438dce8aebaSBarry Smith   Note:
3439dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3440dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3441dce8aebaSBarry Smith 
3442dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3443b67eacb3SMatthew G. Knepley @*/
3444d71ae5a4SJacob 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)
3445d71ae5a4SJacob Faibussowitsch {
3446b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3447b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3448b67eacb3SMatthew G. Knepley 
3449b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3450b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3451b67eacb3SMatthew G. Knepley   while (b) {
3452b67eacb3SMatthew G. Knepley     if (n == bd) break;
3453b67eacb3SMatthew G. Knepley     b = b->next;
3454b67eacb3SMatthew G. Knepley     ++n;
3455b67eacb3SMatthew G. Knepley   }
345663a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3457b67eacb3SMatthew G. Knepley   if (name) {
34589566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
34599566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3460b67eacb3SMatthew G. Knepley   }
3461b67eacb3SMatthew G. Knepley   b->type = type;
346245480ffeSMatthew G. Knepley   if (label) {
346345480ffeSMatthew G. Knepley     const char *name;
346445480ffeSMatthew G. Knepley 
346545480ffeSMatthew G. Knepley     b->label = label;
34669566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
34679566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
34689566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
346945480ffeSMatthew G. Knepley   }
347045480ffeSMatthew G. Knepley   if (Nv >= 0) {
347145480ffeSMatthew G. Knepley     b->Nv = Nv;
34729566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
34739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
34749566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
347545480ffeSMatthew G. Knepley   }
347645480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
347745480ffeSMatthew G. Knepley   if (Nc >= 0) {
347845480ffeSMatthew G. Knepley     b->Nc = Nc;
34799566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
34809566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
34819566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
348245480ffeSMatthew G. Knepley   }
348345480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
348445480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
348545480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
3486b67eacb3SMatthew G. Knepley   PetscFunctionReturn(0);
3487b67eacb3SMatthew G. Knepley }
3488b67eacb3SMatthew G. Knepley 
348958ebd649SToby Isaac /*@
349058ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
349158ebd649SToby Isaac 
349258ebd649SToby Isaac   Input Parameters:
3493dce8aebaSBarry Smith . ds - The `PetscDS` object
349458ebd649SToby Isaac 
349558ebd649SToby Isaac   Output Parameters:
349658ebd649SToby Isaac . numBd - The number of BC
349758ebd649SToby Isaac 
349858ebd649SToby Isaac   Level: intermediate
349958ebd649SToby Isaac 
3500dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
350158ebd649SToby Isaac @*/
3502d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3503d71ae5a4SJacob Faibussowitsch {
350458ebd649SToby Isaac   DSBoundary b = ds->boundary;
350558ebd649SToby Isaac 
350658ebd649SToby Isaac   PetscFunctionBegin;
350758ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3508dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
350958ebd649SToby Isaac   *numBd = 0;
35109371c9d4SSatish Balay   while (b) {
35119371c9d4SSatish Balay     ++(*numBd);
35129371c9d4SSatish Balay     b = b->next;
35139371c9d4SSatish Balay   }
351458ebd649SToby Isaac   PetscFunctionReturn(0);
351558ebd649SToby Isaac }
351658ebd649SToby Isaac 
351758ebd649SToby Isaac /*@C
35189a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
351958ebd649SToby Isaac 
352058ebd649SToby Isaac   Input Parameters:
3521dce8aebaSBarry Smith + ds          - The `PetscDS` object
352258ebd649SToby Isaac - bd          - The BC number
352358ebd649SToby Isaac 
352458ebd649SToby Isaac   Output Parameters:
3525dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3526dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
352758ebd649SToby Isaac . name     - The BC name
352845480ffeSMatthew G. Knepley . label    - The label defining constrained points
3529dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
353045480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
353158ebd649SToby Isaac . field    - The field to constrain
353245480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
353358ebd649SToby Isaac . comps    - An array of constrained component numbers
353458ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3535a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
353658ebd649SToby Isaac - ctx      - An optional user context for bcFunc
353758ebd649SToby Isaac 
353858ebd649SToby Isaac   Options Database Keys:
353958ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
354058ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
354158ebd649SToby Isaac 
354258ebd649SToby Isaac   Level: developer
354358ebd649SToby Isaac 
3544dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
354558ebd649SToby Isaac @*/
3546d71ae5a4SJacob 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)
3547d71ae5a4SJacob Faibussowitsch {
354858ebd649SToby Isaac   DSBoundary b = ds->boundary;
354958ebd649SToby Isaac   PetscInt   n = 0;
355058ebd649SToby Isaac 
355158ebd649SToby Isaac   PetscFunctionBegin;
355258ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
355358ebd649SToby Isaac   while (b) {
355458ebd649SToby Isaac     if (n == bd) break;
355558ebd649SToby Isaac     b = b->next;
355658ebd649SToby Isaac     ++n;
355758ebd649SToby Isaac   }
355863a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
355945480ffeSMatthew G. Knepley   if (wf) {
356045480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
356145480ffeSMatthew G. Knepley     *wf = b->wf;
356245480ffeSMatthew G. Knepley   }
3563f971fd6bSMatthew G. Knepley   if (type) {
356445480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3565f971fd6bSMatthew G. Knepley     *type = b->type;
356658ebd649SToby Isaac   }
356758ebd649SToby Isaac   if (name) {
356845480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
356958ebd649SToby Isaac     *name = b->name;
357058ebd649SToby Isaac   }
357145480ffeSMatthew G. Knepley   if (label) {
357245480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
357345480ffeSMatthew G. Knepley     *label = b->label;
357445480ffeSMatthew G. Knepley   }
357545480ffeSMatthew G. Knepley   if (Nv) {
357645480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
357745480ffeSMatthew G. Knepley     *Nv = b->Nv;
357845480ffeSMatthew G. Knepley   }
357945480ffeSMatthew G. Knepley   if (values) {
358045480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
358145480ffeSMatthew G. Knepley     *values = b->values;
358258ebd649SToby Isaac   }
358358ebd649SToby Isaac   if (field) {
358445480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
358558ebd649SToby Isaac     *field = b->field;
358658ebd649SToby Isaac   }
358745480ffeSMatthew G. Knepley   if (Nc) {
358845480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
358945480ffeSMatthew G. Knepley     *Nc = b->Nc;
359058ebd649SToby Isaac   }
359158ebd649SToby Isaac   if (comps) {
359245480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
359358ebd649SToby Isaac     *comps = b->comps;
359458ebd649SToby Isaac   }
359558ebd649SToby Isaac   if (func) {
359645480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
359758ebd649SToby Isaac     *func = b->func;
359858ebd649SToby Isaac   }
359956cf3b9cSMatthew G. Knepley   if (func_t) {
360045480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
360156cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
360256cf3b9cSMatthew G. Knepley   }
360358ebd649SToby Isaac   if (ctx) {
360445480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
360558ebd649SToby Isaac     *ctx = b->ctx;
360658ebd649SToby Isaac   }
360758ebd649SToby Isaac   PetscFunctionReturn(0);
360858ebd649SToby Isaac }
360958ebd649SToby Isaac 
3610d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3611d71ae5a4SJacob Faibussowitsch {
361245480ffeSMatthew G. Knepley   PetscFunctionBegin;
36139566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
36149566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
36159566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
36169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
36179566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
361845480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
361945480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
362045480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
36219566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
36229566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
362345480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
362445480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
36259566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
36269566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
362745480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
362845480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
362945480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
363045480ffeSMatthew G. Knepley   PetscFunctionReturn(0);
363145480ffeSMatthew G. Knepley }
363245480ffeSMatthew G. Knepley 
36339252d075SMatthew G. Knepley /*@
36349252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
36359252d075SMatthew G. Knepley 
36369252d075SMatthew G. Knepley   Not collective
36379252d075SMatthew G. Knepley 
363836951cb5SMatthew G. Knepley   Input Parameters:
3639dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3640dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
364136951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
36429252d075SMatthew G. Knepley 
36439252d075SMatthew G. Knepley   Output Parameter:
3644dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
36459252d075SMatthew G. Knepley 
36469252d075SMatthew G. Knepley   Level: intermediate
36479252d075SMatthew G. Knepley 
3648dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
36499252d075SMatthew G. Knepley @*/
3650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3651d71ae5a4SJacob Faibussowitsch {
365245480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3653dff059c6SToby Isaac 
3654dff059c6SToby Isaac   PetscFunctionBegin;
365536951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
365636951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
365736951cb5SMatthew G. Knepley   if (ds == newds) PetscFunctionReturn(0);
36589566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
365936951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
366036951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3661dff059c6SToby Isaac     DSBoundary bNew;
366236951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3663dff059c6SToby Isaac 
366436951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
366536951cb5SMatthew G. Knepley       PetscInt f;
366636951cb5SMatthew G. Knepley 
36679371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
36689371c9d4SSatish Balay         if (b->field == fields[f]) break;
366936951cb5SMatthew G. Knepley       if (f == numFields) continue;
367036951cb5SMatthew G. Knepley       fieldNew = f;
367136951cb5SMatthew G. Knepley     }
36729566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
367336951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3674dff059c6SToby Isaac     *lastnext   = bNew;
3675dff059c6SToby Isaac     lastnext    = &(bNew->next);
3676dff059c6SToby Isaac   }
3677dff059c6SToby Isaac   PetscFunctionReturn(0);
3678dff059c6SToby Isaac }
3679dff059c6SToby Isaac 
36806c1eb96dSMatthew G. Knepley /*@
3681dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
368245480ffeSMatthew G. Knepley 
368345480ffeSMatthew G. Knepley   Not collective
368445480ffeSMatthew G. Knepley 
368545480ffeSMatthew G. Knepley   Input Parameter:
3686dce8aebaSBarry Smith . ds - The `PetscDS` object
368745480ffeSMatthew G. Knepley 
368845480ffeSMatthew G. Knepley   Level: intermediate
368945480ffeSMatthew G. Knepley 
3690dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
369145480ffeSMatthew G. Knepley @*/
3692d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3693d71ae5a4SJacob Faibussowitsch {
369445480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
369545480ffeSMatthew G. Knepley 
369645480ffeSMatthew G. Knepley   PetscFunctionBegin;
369745480ffeSMatthew G. Knepley   while (next) {
369845480ffeSMatthew G. Knepley     DSBoundary b = next;
369945480ffeSMatthew G. Knepley 
370045480ffeSMatthew G. Knepley     next = b->next;
37019566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
37029566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
37039566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
37049566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
37059566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
37069566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
370745480ffeSMatthew G. Knepley   }
370845480ffeSMatthew G. Knepley   PetscFunctionReturn(0);
370945480ffeSMatthew G. Knepley }
371045480ffeSMatthew G. Knepley 
371145480ffeSMatthew G. Knepley /*@
37126c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
37136c1eb96dSMatthew G. Knepley 
37146c1eb96dSMatthew G. Knepley   Not collective
37156c1eb96dSMatthew G. Knepley 
3716d8d19677SJose E. Roman   Input Parameters:
3717dce8aebaSBarry Smith + prob - The `PetscDS` object
37186c1eb96dSMatthew G. Knepley . numFields - Number of new fields
37196c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
37206c1eb96dSMatthew G. Knepley 
37216c1eb96dSMatthew G. Knepley   Output Parameter:
3722dce8aebaSBarry Smith . newprob - The `PetscDS` copy
37236c1eb96dSMatthew G. Knepley 
37246c1eb96dSMatthew G. Knepley   Level: intermediate
37256c1eb96dSMatthew G. Knepley 
3726dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37276c1eb96dSMatthew G. Knepley @*/
3728d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3729d71ae5a4SJacob Faibussowitsch {
37306c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
37316c1eb96dSMatthew G. Knepley 
37326c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
37336c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3734dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
37356c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
37369566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
37379566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
373845480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
37396c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
37406c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
37416c1eb96dSMatthew G. Knepley     PetscObject    disc;
37426c1eb96dSMatthew G. Knepley 
37436c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
37449566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
37459566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
37466c1eb96dSMatthew G. Knepley   }
37476c1eb96dSMatthew G. Knepley   PetscFunctionReturn(0);
37486c1eb96dSMatthew G. Knepley }
37496c1eb96dSMatthew G. Knepley 
37506c1eb96dSMatthew G. Knepley /*@
37519252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
37529252d075SMatthew G. Knepley 
37539252d075SMatthew G. Knepley   Not collective
37549252d075SMatthew G. Knepley 
3755d8d19677SJose E. Roman   Input Parameters:
3756dce8aebaSBarry Smith + prob - The `PetscDS` object
37579252d075SMatthew G. Knepley . numFields - Number of new fields
37589252d075SMatthew G. Knepley - fields - Old field number for each new field
37599252d075SMatthew G. Knepley 
37609252d075SMatthew G. Knepley   Output Parameter:
3761dce8aebaSBarry Smith . newprob - The `PetscDS` copy
37629252d075SMatthew G. Knepley 
37639252d075SMatthew G. Knepley   Level: intermediate
37649252d075SMatthew G. Knepley 
3765dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37669252d075SMatthew G. Knepley @*/
3767d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3768d71ae5a4SJacob Faibussowitsch {
37699252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
37709252d075SMatthew G. Knepley 
37719252d075SMatthew G. Knepley   PetscFunctionBegin;
37729252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3773dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
37749252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
37759566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
37769566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
377763a3b9bcSJacob 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);
37789252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
37799252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
37809252d075SMatthew G. Knepley     PetscPointFunc   obj;
37819252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
37829252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
37839252d075SMatthew G. Knepley     PetscRiemannFunc r;
37849252d075SMatthew G. Knepley 
3785c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
37869566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
37879566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
37889566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
37899566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
37909566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
37919566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
37929566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
37939566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
37949252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
37959252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
37969252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
37979252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
37989252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
37999252d075SMatthew G. Knepley 
3800c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
38019566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
38029566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
38039566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
38049566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
38059566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
38069566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
38079252d075SMatthew G. Knepley     }
38089252d075SMatthew G. Knepley   }
38099252d075SMatthew G. Knepley   PetscFunctionReturn(0);
38109252d075SMatthew G. Knepley }
38119252d075SMatthew G. Knepley 
3812da51fcedSMatthew G. Knepley /*@
3813dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3814da51fcedSMatthew G. Knepley 
3815da51fcedSMatthew G. Knepley   Not collective
3816da51fcedSMatthew G. Knepley 
3817da51fcedSMatthew G. Knepley   Input Parameter:
3818dce8aebaSBarry Smith . prob - The `PetscDS` object
3819da51fcedSMatthew G. Knepley 
3820da51fcedSMatthew G. Knepley   Output Parameter:
3821dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3822da51fcedSMatthew G. Knepley 
3823da51fcedSMatthew G. Knepley   Level: intermediate
3824da51fcedSMatthew G. Knepley 
3825dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3826da51fcedSMatthew G. Knepley @*/
3827d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3828d71ae5a4SJacob Faibussowitsch {
3829b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
38309252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3831da51fcedSMatthew G. Knepley 
3832da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3833da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3834da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
38359566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38369566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
383763a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
38389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
38399566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
38409566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
38419252d075SMatthew G. Knepley   PetscFunctionReturn(0);
38429252d075SMatthew G. Knepley }
384345480ffeSMatthew G. Knepley 
38449252d075SMatthew G. Knepley /*@
3845dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3846da51fcedSMatthew G. Knepley 
38479252d075SMatthew G. Knepley   Not collective
38489252d075SMatthew G. Knepley 
38499252d075SMatthew G. Knepley   Input Parameter:
3850dce8aebaSBarry Smith . prob - The `PetscDS` object
38519252d075SMatthew G. Knepley 
38529252d075SMatthew G. Knepley   Output Parameter:
3853dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38549252d075SMatthew G. Knepley 
38559252d075SMatthew G. Knepley   Level: intermediate
38569252d075SMatthew G. Knepley 
3857dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38589252d075SMatthew G. Knepley @*/
3859d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3860d71ae5a4SJacob Faibussowitsch {
38619252d075SMatthew G. Knepley   PetscInt           Nc;
38629252d075SMatthew G. Knepley   const PetscScalar *constants;
38639252d075SMatthew G. Knepley 
38649252d075SMatthew G. Knepley   PetscFunctionBegin;
38659252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
38669252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
38679566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
38689566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
3869da51fcedSMatthew G. Knepley   PetscFunctionReturn(0);
3870da51fcedSMatthew G. Knepley }
3871da51fcedSMatthew G. Knepley 
387245480ffeSMatthew G. Knepley /*@
3873dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
387445480ffeSMatthew G. Knepley 
387545480ffeSMatthew G. Knepley   Not collective
387645480ffeSMatthew G. Knepley 
387745480ffeSMatthew G. Knepley   Input Parameter:
3878dce8aebaSBarry Smith . ds - The `PetscDS` object
387945480ffeSMatthew G. Knepley 
388045480ffeSMatthew G. Knepley   Output Parameter:
3881dce8aebaSBarry Smith . newds - The `PetscDS` copy
388245480ffeSMatthew G. Knepley 
388345480ffeSMatthew G. Knepley   Level: intermediate
388445480ffeSMatthew G. Knepley 
3885dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
388645480ffeSMatthew G. Knepley @*/
3887d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
3888d71ae5a4SJacob Faibussowitsch {
388945480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
389045480ffeSMatthew G. Knepley   void                *ctx;
389145480ffeSMatthew G. Knepley   PetscInt             Nf, f;
389245480ffeSMatthew G. Knepley 
389345480ffeSMatthew G. Knepley   PetscFunctionBegin;
389445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
389545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
38969566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
389745480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
38989566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
38999566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
39009566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
39019566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
390245480ffeSMatthew G. Knepley   }
390345480ffeSMatthew G. Knepley   PetscFunctionReturn(0);
390445480ffeSMatthew G. Knepley }
390545480ffeSMatthew G. Knepley 
3906d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
3907d71ae5a4SJacob Faibussowitsch {
3908df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
3909b1353e8eSMatthew G. Knepley 
3910b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
3911b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3912b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
39139371c9d4SSatish Balay   if (height == 0) {
39149371c9d4SSatish Balay     *subprob = prob;
39159371c9d4SSatish Balay     PetscFunctionReturn(0);
39169371c9d4SSatish Balay   }
39179566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39189566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
391963a3b9bcSJacob 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);
39209566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
3921df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
3922b1353e8eSMatthew G. Knepley     PetscInt cdim;
3923b1353e8eSMatthew G. Knepley 
39249566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
39259566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
39269566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
3927b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
3928b1353e8eSMatthew G. Knepley       PetscFE      subfe;
3929b1353e8eSMatthew G. Knepley       PetscObject  obj;
3930b1353e8eSMatthew G. Knepley       PetscClassId id;
3931b1353e8eSMatthew G. Knepley 
39329566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
39339566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
39349566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
393563a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
39369566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
3937b1353e8eSMatthew G. Knepley     }
3938b1353e8eSMatthew G. Knepley   }
3939df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
3940b1353e8eSMatthew G. Knepley   PetscFunctionReturn(0);
3941b1353e8eSMatthew G. Knepley }
3942b1353e8eSMatthew G. Knepley 
3943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
3944d71ae5a4SJacob Faibussowitsch {
3945c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
3946c7bd5f0bSMatthew G. Knepley   PetscClassId id;
3947c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
3948c7bd5f0bSMatthew G. Knepley 
3949c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
3950c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3951665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
3952665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
39539566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
395463a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
39559566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
3956665f567fSMatthew G. Knepley   if (obj) {
39579566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
3958665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
3959665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
3960665f567fSMatthew G. Knepley   }
3961c7bd5f0bSMatthew G. Knepley   PetscFunctionReturn(0);
3962c7bd5f0bSMatthew G. Knepley }
3963c7bd5f0bSMatthew G. Knepley 
3964d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
3965d71ae5a4SJacob Faibussowitsch {
39662764a2aaSMatthew G. Knepley   PetscFunctionBegin;
39679566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
39682764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
39692764a2aaSMatthew G. Knepley }
39702764a2aaSMatthew G. Knepley 
3971d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
3972d71ae5a4SJacob Faibussowitsch {
39732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
39746528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
39756528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
39766528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
39776528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
39782764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
39792764a2aaSMatthew G. Knepley }
39802764a2aaSMatthew G. Knepley 
39812764a2aaSMatthew G. Knepley /*MC
39822764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
39832764a2aaSMatthew G. Knepley 
39842764a2aaSMatthew G. Knepley   Level: intermediate
39852764a2aaSMatthew G. Knepley 
3986db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
39872764a2aaSMatthew G. Knepley M*/
39882764a2aaSMatthew G. Knepley 
3989d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
3990d71ae5a4SJacob Faibussowitsch {
39912764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
39922764a2aaSMatthew G. Knepley 
39932764a2aaSMatthew G. Knepley   PetscFunctionBegin;
39946528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
39954dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
39966528b96dSMatthew G. Knepley   ds->data = b;
39972764a2aaSMatthew G. Knepley 
39989566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
39992764a2aaSMatthew G. Knepley   PetscFunctionReturn(0);
40002764a2aaSMatthew G. Knepley }
4001