xref: /petsc/src/dm/dt/interface/dtds.c (revision 2192575e8c1428e47f7eac7b348fe8e57717183e)
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 
82764a2aaSMatthew G. Knepley /*@C
9dce8aebaSBarry Smith   PetscDSRegister - Adds a new `PetscDS` implementation
102764a2aaSMatthew G. Knepley 
1120f4b53cSBarry Smith   Not Collective; No Fortran Support
122764a2aaSMatthew G. Knepley 
132764a2aaSMatthew G. Knepley   Input Parameters:
1420f4b53cSBarry Smith + sname    - The name of a new user-defined creation routine
1520f4b53cSBarry Smith - function - The creation routine itself
162764a2aaSMatthew G. Knepley 
1760225df5SJacob Faibussowitsch   Example Usage:
182764a2aaSMatthew G. Knepley .vb
192764a2aaSMatthew G. Knepley     PetscDSRegister("my_ds", MyPetscDSCreate);
202764a2aaSMatthew G. Knepley .ve
212764a2aaSMatthew G. Knepley 
222764a2aaSMatthew G. Knepley   Then, your PetscDS type can be chosen with the procedural interface via
232764a2aaSMatthew G. Knepley .vb
242764a2aaSMatthew G. Knepley     PetscDSCreate(MPI_Comm, PetscDS *);
252764a2aaSMatthew G. Knepley     PetscDSSetType(PetscDS, "my_ds");
262764a2aaSMatthew G. Knepley .ve
272764a2aaSMatthew G. Knepley   or at runtime via the option
282764a2aaSMatthew G. Knepley .vb
292764a2aaSMatthew G. Knepley     -petscds_type my_ds
302764a2aaSMatthew G. Knepley .ve
312764a2aaSMatthew G. Knepley 
322764a2aaSMatthew G. Knepley   Level: advanced
332764a2aaSMatthew G. Knepley 
34dce8aebaSBarry Smith   Note:
35dce8aebaSBarry Smith   `PetscDSRegister()` may be called multiple times to add several user-defined `PetscDSs`
36dce8aebaSBarry Smith 
37dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
382764a2aaSMatthew G. Knepley @*/
39d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
40d71ae5a4SJacob Faibussowitsch {
412764a2aaSMatthew G. Knepley   PetscFunctionBegin;
429566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
442764a2aaSMatthew G. Knepley }
452764a2aaSMatthew G. Knepley 
46cc4c1da9SBarry Smith /*@
47dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
482764a2aaSMatthew G. Knepley 
4920f4b53cSBarry Smith   Collective; No Fortran Support
502764a2aaSMatthew G. Knepley 
512764a2aaSMatthew G. Knepley   Input Parameters:
52dce8aebaSBarry Smith + prob - The `PetscDS` object
53dce8aebaSBarry Smith - name - The `PetscDSType`
542764a2aaSMatthew G. Knepley 
552764a2aaSMatthew G. Knepley   Options Database Key:
562764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
572764a2aaSMatthew G. Knepley 
582764a2aaSMatthew G. Knepley   Level: intermediate
592764a2aaSMatthew G. Knepley 
60dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
612764a2aaSMatthew G. Knepley @*/
62d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
63d71ae5a4SJacob Faibussowitsch {
642764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
652764a2aaSMatthew G. Knepley   PetscBool match;
662764a2aaSMatthew G. Knepley 
672764a2aaSMatthew G. Knepley   PetscFunctionBegin;
682764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
703ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
712764a2aaSMatthew G. Knepley 
729566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
739566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
7428b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
752764a2aaSMatthew G. Knepley 
76dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
772764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
78dbbe0bcdSBarry Smith 
799566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
809566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
822764a2aaSMatthew G. Knepley }
832764a2aaSMatthew G. Knepley 
84cc4c1da9SBarry Smith /*@
85dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
862764a2aaSMatthew G. Knepley 
8720f4b53cSBarry Smith   Not Collective; No Fortran Support
882764a2aaSMatthew G. Knepley 
892764a2aaSMatthew G. Knepley   Input Parameter:
90dce8aebaSBarry Smith . prob - The `PetscDS`
912764a2aaSMatthew G. Knepley 
922764a2aaSMatthew G. Knepley   Output Parameter:
93dce8aebaSBarry Smith . name - The `PetscDSType` name
942764a2aaSMatthew G. Knepley 
952764a2aaSMatthew G. Knepley   Level: intermediate
962764a2aaSMatthew G. Knepley 
97dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
982764a2aaSMatthew G. Knepley @*/
99d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
100d71ae5a4SJacob Faibussowitsch {
1012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1022764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1034f572ea9SToby Isaac   PetscAssertPointer(name, 2);
1049566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1052764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1072764a2aaSMatthew G. Knepley }
1082764a2aaSMatthew G. Knepley 
109d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
110d71ae5a4SJacob Faibussowitsch {
1117d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
11297b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1135fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1147d8a60eaSMatthew G. Knepley 
1157d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1169566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1179566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
11863a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1199566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
12063a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1219566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1225fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
12340967b3bSMatthew G. Knepley     DSBoundary      b;
1247d8a60eaSMatthew G. Knepley     PetscObject     obj;
1257d8a60eaSMatthew G. Knepley     PetscClassId    id;
126f35450b9SMatthew G. Knepley     PetscQuadrature q;
1277d8a60eaSMatthew G. Knepley     const char     *name;
128f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1297d8a60eaSMatthew G. Knepley 
1309566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1319566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1329566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1339566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1357d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1369566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1379566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1389566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1397d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1409566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1419566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1429566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1439371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
14463a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
14563a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1469566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1479566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1483e60c2a6SMatthew G. Knepley     if (q) {
1499566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
15063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1513e60c2a6SMatthew G. Knepley     }
15263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1549566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1559566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1569566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1579566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
15940967b3bSMatthew G. Knepley 
1605fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
16106ad1575SMatthew G. Knepley       char    *name;
16240967b3bSMatthew G. Knepley       PetscInt c, i;
16340967b3bSMatthew G. Knepley 
16440967b3bSMatthew G. Knepley       if (b->field != f) continue;
1659566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
16745480ffeSMatthew G. Knepley       if (!b->Nc) {
1689566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
16940967b3bSMatthew G. Knepley       } else {
1709566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1719566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
17245480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1739566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
17463a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
17540967b3bSMatthew G. Knepley         }
1769566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1779566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
17840967b3bSMatthew G. Knepley       }
1799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
1809566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
18145480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
1829566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
18363a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
18440967b3bSMatthew G. Knepley       }
1859566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1869566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
18715943bb8SPierre Jolivet #if defined(__clang__)
188a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic")
18915943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
190a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat")
19115943bb8SPierre Jolivet #endif
1928e0d8d9cSMatthew G. Knepley       if (b->func) {
1939566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
1949566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
1959566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
1969566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
1978e0d8d9cSMatthew G. Knepley       }
1988e0d8d9cSMatthew G. Knepley       if (b->func_t) {
1999566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2009566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2019566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2029566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2038e0d8d9cSMatthew G. Knepley       }
204a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END()
2059566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2069566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
20740967b3bSMatthew G. Knepley     }
2087d8a60eaSMatthew G. Knepley   }
2099566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
21097b6e6e8SMatthew G. Knepley   if (numConstants) {
21163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2129566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2139566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2149566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
21597b6e6e8SMatthew G. Knepley   }
2169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2179566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2197d8a60eaSMatthew G. Knepley }
2207d8a60eaSMatthew G. Knepley 
221ffeef943SBarry Smith /*@
222dce8aebaSBarry Smith   PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
223fe2efc57SMark 
22420f4b53cSBarry Smith   Collective
225fe2efc57SMark 
226fe2efc57SMark   Input Parameters:
227dce8aebaSBarry Smith + A    - the `PetscDS` object
228*2192575eSBarry Smith . obj  - Optional object that provides the options prefix used in the search of the options database
229736c3998SJose E. Roman - name - command line option
230fe2efc57SMark 
231fe2efc57SMark   Level: intermediate
232dce8aebaSBarry Smith 
233dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
234fe2efc57SMark @*/
235d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
236d71ae5a4SJacob Faibussowitsch {
237fe2efc57SMark   PetscFunctionBegin;
238fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2399566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
241fe2efc57SMark }
242fe2efc57SMark 
243ffeef943SBarry Smith /*@
244dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2452764a2aaSMatthew G. Knepley 
24620f4b53cSBarry Smith   Collective
2472764a2aaSMatthew G. Knepley 
248d8d19677SJose E. Roman   Input Parameters:
249dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2502764a2aaSMatthew G. Knepley - v    - the viewer
2512764a2aaSMatthew G. Knepley 
2522764a2aaSMatthew G. Knepley   Level: developer
2532764a2aaSMatthew G. Knepley 
25420f4b53cSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`, `PetscDSViewFromOptions()`
2552764a2aaSMatthew G. Knepley @*/
256d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
257d71ae5a4SJacob Faibussowitsch {
2587d8a60eaSMatthew G. Knepley   PetscBool iascii;
2592764a2aaSMatthew G. Knepley 
2602764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2612764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2629566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
263ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2649566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2659566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
266dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2682764a2aaSMatthew G. Knepley }
2692764a2aaSMatthew G. Knepley 
2702764a2aaSMatthew G. Knepley /*@
271dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2722764a2aaSMatthew G. Knepley 
27320f4b53cSBarry Smith   Collective
2742764a2aaSMatthew G. Knepley 
2752764a2aaSMatthew G. Knepley   Input Parameter:
276dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2772764a2aaSMatthew G. Knepley 
278dce8aebaSBarry Smith   Options Database Keys:
279dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
280dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
281147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
282147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
283147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
2842764a2aaSMatthew G. Knepley 
285dce8aebaSBarry Smith   Level: intermediate
2862764a2aaSMatthew G. Knepley 
287dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
2882764a2aaSMatthew G. Knepley @*/
289d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
290d71ae5a4SJacob Faibussowitsch {
291f1fd5e65SToby Isaac   DSBoundary  b;
2922764a2aaSMatthew G. Knepley   const char *defaultType;
2932764a2aaSMatthew G. Knepley   char        name[256];
2942764a2aaSMatthew G. Knepley   PetscBool   flg;
2952764a2aaSMatthew G. Knepley 
2962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2972764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2982764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
2992764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3002764a2aaSMatthew G. Knepley   } else {
3012764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3022764a2aaSMatthew G. Knepley   }
3039566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3042764a2aaSMatthew G. Knepley 
305d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
306f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
307f1fd5e65SToby Isaac     char      optname[1024];
308f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
309f1fd5e65SToby Isaac     PetscBool flg;
310f1fd5e65SToby Isaac 
3119566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3129566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3139566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
314f1fd5e65SToby Isaac     if (flg) {
31545480ffeSMatthew G. Knepley       b->Nv = len;
3169566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3179566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3189566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3199566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
320f1fd5e65SToby Isaac     }
321e7b0402cSSander Arens     len = 1024;
3229566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3239566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3249566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
325f1fd5e65SToby Isaac     if (flg) {
32645480ffeSMatthew G. Knepley       b->Nc = len;
3279566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3289566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3299566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
330f1fd5e65SToby Isaac     }
331f1fd5e65SToby Isaac   }
3329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3332764a2aaSMatthew G. Knepley   if (flg) {
3349566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3352764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3369566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3372764a2aaSMatthew G. Knepley   }
3389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
33912fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
340b2deab97SMatthew G. Knepley   PetscCall(PetscOptionsInt("-petscds_print_integrate", "Discrete System", "", prob->printIntegrate, &prob->printIntegrate, NULL));
341dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3422764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
343dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
344d0609cedSBarry Smith   PetscOptionsEnd();
3459566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3472764a2aaSMatthew G. Knepley }
3482764a2aaSMatthew G. Knepley 
349cc4c1da9SBarry Smith /*@
350dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3512764a2aaSMatthew G. Knepley 
35220f4b53cSBarry Smith   Collective
3532764a2aaSMatthew G. Knepley 
3542764a2aaSMatthew G. Knepley   Input Parameter:
355dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3562764a2aaSMatthew G. Knepley 
3572764a2aaSMatthew G. Knepley   Level: developer
3582764a2aaSMatthew G. Knepley 
359dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3602764a2aaSMatthew G. Knepley @*/
361d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
362d71ae5a4SJacob Faibussowitsch {
3632764a2aaSMatthew G. Knepley   const PetscInt Nf          = prob->Nf;
364f9244615SMatthew G. Knepley   PetscBool      hasH        = PETSC_FALSE;
365e59ddd55SMatthew G. Knepley   PetscInt       maxOrder[4] = {-2, -2, -2, -2};
3664bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3672764a2aaSMatthew G. Knepley 
3682764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3692764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3703ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3712764a2aaSMatthew G. Knepley   /* Calculate sizes */
3729566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3739566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
374f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3759566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3769566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3779566063dSJacob 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]));
3789566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
37912fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
38007218a29SMatthew G. Knepley     // Note: This assumes we have one kind of cell at each dimension.
38107218a29SMatthew G. Knepley     //       We can fix this by having quadrature hold the celltype
38207218a29SMatthew G. Knepley     PetscQuadrature maxQuad[4] = {NULL, NULL, NULL, NULL};
38312fc5b22SMatthew G. Knepley 
38412fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
38512fc5b22SMatthew G. Knepley       PetscObject     obj;
38612fc5b22SMatthew G. Knepley       PetscClassId    id;
38712fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
38807218a29SMatthew G. Knepley       PetscInt        dim = -1, order = -1, forder = -1;
38912fc5b22SMatthew G. Knepley 
39012fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
39112fc5b22SMatthew G. Knepley       if (!obj) continue;
39212fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
39312fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
39412fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
39512fc5b22SMatthew G. Knepley 
39612fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
39712fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
39812fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
39912fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
40012fc5b22SMatthew G. Knepley 
40112fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
40212fc5b22SMatthew G. Knepley       }
40307218a29SMatthew G. Knepley       if (q) {
40407218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
40507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(q, &order));
40607218a29SMatthew G. Knepley         if (order > maxOrder[dim]) {
40707218a29SMatthew G. Knepley           maxOrder[dim] = order;
40807218a29SMatthew G. Knepley           maxQuad[dim]  = q;
40912fc5b22SMatthew G. Knepley         }
41007218a29SMatthew G. Knepley       }
41107218a29SMatthew G. Knepley       if (fq) {
41207218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
41307218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(fq, &forder));
41407218a29SMatthew G. Knepley         if (forder > maxOrder[dim]) {
41507218a29SMatthew G. Knepley           maxOrder[dim] = forder;
41607218a29SMatthew G. Knepley           maxQuad[dim]  = fq;
41707218a29SMatthew G. Knepley         }
41812fc5b22SMatthew G. Knepley       }
41912fc5b22SMatthew G. Knepley     }
42012fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
42112fc5b22SMatthew G. Knepley       PetscObject     obj;
42212fc5b22SMatthew G. Knepley       PetscClassId    id;
42307218a29SMatthew G. Knepley       PetscQuadrature q;
42407218a29SMatthew G. Knepley       PetscInt        dim;
42512fc5b22SMatthew G. Knepley 
42612fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
42712fc5b22SMatthew G. Knepley       if (!obj) continue;
42812fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
42912fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
43012fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
43112fc5b22SMatthew G. Knepley 
43207218a29SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
43307218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
43407218a29SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, maxQuad[dim]));
435aa9788aaSMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, dim ? maxQuad[dim - 1] : NULL));
43612fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
43712fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
43812fc5b22SMatthew G. Knepley 
43907218a29SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
44007218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
44107218a29SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, maxQuad[dim]));
44212fc5b22SMatthew G. Knepley       }
44312fc5b22SMatthew G. Knepley     }
44412fc5b22SMatthew G. Knepley   }
4452764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4469de99aefSMatthew G. Knepley     PetscObject     obj;
4479de99aefSMatthew G. Knepley     PetscClassId    id;
448665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4499de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4502764a2aaSMatthew G. Knepley 
4519566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
452f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
453665f567fSMatthew G. Knepley     if (!obj) {
454665f567fSMatthew G. Knepley       /* Empty mesh */
455665f567fSMatthew G. Knepley       Nb = Nc    = 0;
456665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
457665f567fSMatthew G. Knepley     } else {
4589566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4599de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4609de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4619de99aefSMatthew G. Knepley 
4629566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
46349ae0b56SMatthew G. Knepley         {
46449ae0b56SMatthew G. Knepley           PetscQuadrature fq;
46507218a29SMatthew G. Knepley           PetscInt        dim, order;
46649ae0b56SMatthew G. Knepley 
46707218a29SMatthew G. Knepley           PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
46849ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
46907218a29SMatthew G. Knepley           if (maxOrder[dim] < 0) maxOrder[dim] = order;
47007218a29SMatthew G. Knepley           PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, maxOrder[dim]);
47149ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
47249ae0b56SMatthew G. Knepley           if (fq) {
47307218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
47407218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &order));
47507218a29SMatthew G. Knepley             if (maxOrder[dim] < 0) maxOrder[dim] = order;
47607218a29SMatthew G. Knepley             PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, order, maxOrder[dim]);
47749ae0b56SMatthew G. Knepley           }
47849ae0b56SMatthew G. Knepley         }
4799566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4809566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4819566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4829566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4839de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4849de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4859de99aefSMatthew G. Knepley 
4869566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4879566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
4889c3cf19fSMatthew G. Knepley         Nb = Nc;
4899566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
4904d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
49163a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
492665f567fSMatthew G. Knepley     }
49347e57110SSander Arens     prob->Nc[f]                    = Nc;
49447e57110SSander Arens     prob->Nb[f]                    = Nb;
495194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
496194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
4979ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
4989ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
4999ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5009ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5019ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5029ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5039566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5042764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5054bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5062764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5079c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5082764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5095fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5105fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5112764a2aaSMatthew G. Knepley   }
5129ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5139ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5142764a2aaSMatthew G. Knepley   /* Allocate works space */
5155fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5169566063dSJacob 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));
5179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5189371c9d4SSatish 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,
5199371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
520dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5212764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5232764a2aaSMatthew G. Knepley }
5242764a2aaSMatthew G. Knepley 
525d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
526d71ae5a4SJacob Faibussowitsch {
5272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5289566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5299566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5309566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5319566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5329566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5339566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5349566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5362764a2aaSMatthew G. Knepley }
5372764a2aaSMatthew G. Knepley 
538d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
539d71ae5a4SJacob Faibussowitsch {
540f744cafaSSander Arens   PetscObject         *tmpd;
54134aa8a36SMatthew G. Knepley   PetscBool           *tmpi;
542f9244615SMatthew G. Knepley   PetscInt            *tmpk;
5435fedec97SMatthew G. Knepley   PetscBool           *tmpc;
544*2192575eSBarry Smith   PetscPointFn       **tmpup;
545342bd5aaSMatthew G. Knepley   PetscSimplePointFn **tmpexactSol, **tmpexactSol_t, **tmplowerBound, **tmpupperBound;
546342bd5aaSMatthew G. Knepley   void               **tmpexactCtx, **tmpexactCtx_t, **tmplowerCtx, **tmpupperCtx;
5470c2f2876SMatthew G. Knepley   void               **tmpctx;
54834aa8a36SMatthew G. Knepley   PetscInt             Nf = prob->Nf, f;
5492764a2aaSMatthew G. Knepley 
5502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5513ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5522764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5539566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5559371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5569371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5579371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5589371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5599371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5609371c9d4SSatish Balay   }
5619371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5629371c9d4SSatish Balay     tmpd[f] = NULL;
5639371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5649371c9d4SSatish Balay     tmpk[f] = 1;
5659371c9d4SSatish Balay   }
5669566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5682764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5692764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
570249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5715fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
572f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5739566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
57432d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5750c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
57632d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5770c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5789566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
57932d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5800c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5819566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
582342bd5aaSMatthew G. Knepley   PetscCall(PetscCalloc4(NfNew, &tmplowerBound, NfNew, &tmplowerCtx, NfNew, &tmpupperBound, NfNew, &tmpupperCtx));
583c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
58495cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
585f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
586f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
587342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerBound[f] = prob->lowerBound[f];
588342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmplowerCtx[f] = prob->lowerCtx[f];
589342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperBound[f] = prob->upperBound[f];
590342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpupperCtx[f] = prob->upperCtx[f];
591c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
59295cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
593f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
594f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
595342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerBound[f] = NULL;
596342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmplowerCtx[f] = NULL;
597342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperBound[f] = NULL;
598342bd5aaSMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpupperCtx[f] = NULL;
5999566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
600342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4(prob->lowerBound, prob->lowerCtx, prob->upperBound, prob->upperCtx));
601c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60295cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
603f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
604f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
605342bd5aaSMatthew G. Knepley   prob->lowerBound = tmplowerBound;
606342bd5aaSMatthew G. Knepley   prob->lowerCtx   = tmplowerCtx;
607342bd5aaSMatthew G. Knepley   prob->upperBound = tmpupperBound;
608342bd5aaSMatthew G. Knepley   prob->upperCtx   = tmpupperCtx;
6093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6102764a2aaSMatthew G. Knepley }
6112764a2aaSMatthew G. Knepley 
6122764a2aaSMatthew G. Knepley /*@
61320f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6142764a2aaSMatthew G. Knepley 
61520f4b53cSBarry Smith   Collective
6162764a2aaSMatthew G. Knepley 
6172764a2aaSMatthew G. Knepley   Input Parameter:
61860225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6192764a2aaSMatthew G. Knepley 
6202764a2aaSMatthew G. Knepley   Level: developer
6212764a2aaSMatthew G. Knepley 
622dce8aebaSBarry Smith .seealso: `PetscDSView()`
6232764a2aaSMatthew G. Knepley @*/
624d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
625d71ae5a4SJacob Faibussowitsch {
6262764a2aaSMatthew G. Knepley   PetscInt f;
6272764a2aaSMatthew G. Knepley 
6282764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6293ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
630f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6312764a2aaSMatthew G. Knepley 
632f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6339371c9d4SSatish Balay     *ds = NULL;
6343ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6359371c9d4SSatish Balay   }
636f4f49eeaSPierre Jolivet   ((PetscObject)*ds)->refct = 0;
6376528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
638df3a45bdSMatthew G. Knepley     PetscInt dim, d;
639df3a45bdSMatthew G. Knepley 
6409566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6419566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
642df3a45bdSMatthew G. Knepley   }
6439566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6449566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64548a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6469566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6489566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6499566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
650342bd5aaSMatthew G. Knepley   PetscCall(PetscFree4((*ds)->lowerBound, (*ds)->lowerCtx, (*ds)->upperBound, (*ds)->upperCtx));
651f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ds, destroy);
6529566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6539566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6544366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
65585036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((DMPolytopeType)c);
6564366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6574366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6584366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6594366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6604366bac7SMatthew G. Knepley   }
6619566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6632764a2aaSMatthew G. Knepley }
6642764a2aaSMatthew G. Knepley 
6652764a2aaSMatthew G. Knepley /*@
666dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6672764a2aaSMatthew G. Knepley 
668d083f849SBarry Smith   Collective
6692764a2aaSMatthew G. Knepley 
6702764a2aaSMatthew G. Knepley   Input Parameter:
671dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6722764a2aaSMatthew G. Knepley 
6732764a2aaSMatthew G. Knepley   Output Parameter:
674dce8aebaSBarry Smith . ds - The `PetscDS` object
6752764a2aaSMatthew G. Knepley 
6762764a2aaSMatthew G. Knepley   Level: beginner
6772764a2aaSMatthew G. Knepley 
678*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`, `PetscDSDestroy()`
6792764a2aaSMatthew G. Knepley @*/
680d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
681d71ae5a4SJacob Faibussowitsch {
6822764a2aaSMatthew G. Knepley   PetscDS p;
6832764a2aaSMatthew G. Knepley 
6842764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6854f572ea9SToby Isaac   PetscAssertPointer(ds, 2);
6869566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6872764a2aaSMatthew G. Knepley 
6889566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6892764a2aaSMatthew G. Knepley   p->Nf               = 0;
6902764a2aaSMatthew G. Knepley   p->setup            = PETSC_FALSE;
69197b6e6e8SMatthew G. Knepley   p->numConstants     = 0;
69287510d7dSMatthew G. Knepley   p->numFuncConstants = 3; // Row and col fields, cell size
693a859676bSMatthew G. Knepley   p->dimEmbed         = -1;
69455c1f793SMatthew G. Knepley   p->useJacPre        = PETSC_TRUE;
69512fc5b22SMatthew G. Knepley   p->forceQuad        = PETSC_TRUE;
696a102dd69SStefano Zampini   PetscCall(PetscMalloc1(p->numConstants + p->numFuncConstants, &p->constants));
6979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6984366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
6996528b96dSMatthew G. Knepley   *ds = p;
7003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7012764a2aaSMatthew G. Knepley }
7022764a2aaSMatthew G. Knepley 
703bc4ae4beSMatthew G. Knepley /*@
704dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
705bc4ae4beSMatthew G. Knepley 
70620f4b53cSBarry Smith   Not Collective
707bc4ae4beSMatthew G. Knepley 
708bc4ae4beSMatthew G. Knepley   Input Parameter:
70920f4b53cSBarry Smith . prob - The `PetscDS` object
710bc4ae4beSMatthew G. Knepley 
711bc4ae4beSMatthew G. Knepley   Output Parameter:
712bc4ae4beSMatthew G. Knepley . Nf - The number of fields
713bc4ae4beSMatthew G. Knepley 
714bc4ae4beSMatthew G. Knepley   Level: beginner
715bc4ae4beSMatthew G. Knepley 
716dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
717bc4ae4beSMatthew G. Knepley @*/
718d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
719d71ae5a4SJacob Faibussowitsch {
7202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7224f572ea9SToby Isaac   PetscAssertPointer(Nf, 2);
7232764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7252764a2aaSMatthew G. Knepley }
7262764a2aaSMatthew G. Knepley 
727bc4ae4beSMatthew G. Knepley /*@
728dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
729bc4ae4beSMatthew G. Knepley 
73020f4b53cSBarry Smith   Not Collective
731bc4ae4beSMatthew G. Knepley 
732bc4ae4beSMatthew G. Knepley   Input Parameter:
733dce8aebaSBarry Smith . prob - The `PetscDS` object
734bc4ae4beSMatthew G. Knepley 
735bc4ae4beSMatthew G. Knepley   Output Parameter:
736bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
737bc4ae4beSMatthew G. Knepley 
738bc4ae4beSMatthew G. Knepley   Level: beginner
739bc4ae4beSMatthew G. Knepley 
740dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
741bc4ae4beSMatthew G. Knepley @*/
742d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
743d71ae5a4SJacob Faibussowitsch {
7442764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7452764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7464f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
7472764a2aaSMatthew G. Knepley   *dim = 0;
7489de99aefSMatthew G. Knepley   if (prob->Nf) {
7499de99aefSMatthew G. Knepley     PetscObject  obj;
7509de99aefSMatthew G. Knepley     PetscClassId id;
7519de99aefSMatthew G. Knepley 
7529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
753665f567fSMatthew G. Knepley     if (obj) {
7549566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7559566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7569566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
75798921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7589de99aefSMatthew G. Knepley     }
759665f567fSMatthew G. Knepley   }
7603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7612764a2aaSMatthew G. Knepley }
7622764a2aaSMatthew G. Knepley 
763bc4ae4beSMatthew G. Knepley /*@
764dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
765a859676bSMatthew G. Knepley 
76620f4b53cSBarry Smith   Not Collective
767a859676bSMatthew G. Knepley 
768a859676bSMatthew G. Knepley   Input Parameter:
769dce8aebaSBarry Smith . prob - The `PetscDS` object
770a859676bSMatthew G. Knepley 
771a859676bSMatthew G. Knepley   Output Parameter:
772a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
773a859676bSMatthew G. Knepley 
774a859676bSMatthew G. Knepley   Level: beginner
775a859676bSMatthew G. Knepley 
776dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
777a859676bSMatthew G. Knepley @*/
778d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
779d71ae5a4SJacob Faibussowitsch {
780a859676bSMatthew G. Knepley   PetscFunctionBegin;
781a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
7824f572ea9SToby Isaac   PetscAssertPointer(dimEmbed, 2);
78308401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
784a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
786a859676bSMatthew G. Knepley }
787a859676bSMatthew G. Knepley 
788a859676bSMatthew G. Knepley /*@
789dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
790a859676bSMatthew G. Knepley 
79120f4b53cSBarry Smith   Logically Collective
792a859676bSMatthew G. Knepley 
793a859676bSMatthew G. Knepley   Input Parameters:
794dce8aebaSBarry Smith + prob     - The `PetscDS` object
795a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
796a859676bSMatthew G. Knepley 
797a859676bSMatthew G. Knepley   Level: beginner
798a859676bSMatthew G. Knepley 
799dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
800a859676bSMatthew G. Knepley @*/
801d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
802d71ae5a4SJacob Faibussowitsch {
803a859676bSMatthew G. Knepley   PetscFunctionBegin;
804a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
80563a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
806a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
808a859676bSMatthew G. Knepley }
809a859676bSMatthew G. Knepley 
810a859676bSMatthew G. Knepley /*@
81112fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
81212fc5b22SMatthew G. Knepley 
81312fc5b22SMatthew G. Knepley   Not collective
81412fc5b22SMatthew G. Knepley 
81512fc5b22SMatthew G. Knepley   Input Parameter:
81660225df5SJacob Faibussowitsch . ds - The `PetscDS` object
81712fc5b22SMatthew G. Knepley 
81812fc5b22SMatthew G. Knepley   Output Parameter:
81912fc5b22SMatthew G. Knepley . forceQuad - The flag
82012fc5b22SMatthew G. Knepley 
82112fc5b22SMatthew G. Knepley   Level: intermediate
82212fc5b22SMatthew G. Knepley 
82312fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82412fc5b22SMatthew G. Knepley @*/
82512fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
82612fc5b22SMatthew G. Knepley {
82712fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82812fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8294f572ea9SToby Isaac   PetscAssertPointer(forceQuad, 2);
83012fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
83112fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83212fc5b22SMatthew G. Knepley }
83312fc5b22SMatthew G. Knepley 
83412fc5b22SMatthew G. Knepley /*@
83512fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
83612fc5b22SMatthew G. Knepley 
83712fc5b22SMatthew G. Knepley   Logically collective on ds
83812fc5b22SMatthew G. Knepley 
83912fc5b22SMatthew G. Knepley   Input Parameters:
84012fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
84112fc5b22SMatthew G. Knepley - forceQuad - The flag
84212fc5b22SMatthew G. Knepley 
84312fc5b22SMatthew G. Knepley   Level: intermediate
84412fc5b22SMatthew G. Knepley 
84512fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
84612fc5b22SMatthew G. Knepley @*/
84712fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
84812fc5b22SMatthew G. Knepley {
84912fc5b22SMatthew G. Knepley   PetscFunctionBegin;
85012fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
85112fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
85212fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
85312fc5b22SMatthew G. Knepley }
85412fc5b22SMatthew G. Knepley 
85512fc5b22SMatthew G. Knepley /*@
856dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8578edf6225SMatthew G. Knepley 
85820f4b53cSBarry Smith   Not Collective
8598edf6225SMatthew G. Knepley 
8608edf6225SMatthew G. Knepley   Input Parameter:
861dce8aebaSBarry Smith . ds - The `PetscDS` object
8628edf6225SMatthew G. Knepley 
8638edf6225SMatthew G. Knepley   Output Parameter:
8645fedec97SMatthew G. Knepley . isCohesive - The flag
8658edf6225SMatthew G. Knepley 
8668edf6225SMatthew G. Knepley   Level: developer
8678edf6225SMatthew G. Knepley 
868dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8698edf6225SMatthew G. Knepley @*/
870d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
871d71ae5a4SJacob Faibussowitsch {
8728edf6225SMatthew G. Knepley   PetscFunctionBegin;
8735fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
8744f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 2);
8755fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8778edf6225SMatthew G. Knepley }
8788edf6225SMatthew G. Knepley 
8798edf6225SMatthew G. Knepley /*@
880be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8815fedec97SMatthew G. Knepley 
88220f4b53cSBarry Smith   Not Collective
8835fedec97SMatthew G. Knepley 
8845fedec97SMatthew G. Knepley   Input Parameter:
885dce8aebaSBarry Smith . ds - The `PetscDS` object
8865fedec97SMatthew G. Knepley 
8875fedec97SMatthew G. Knepley   Output Parameter:
8885fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8895fedec97SMatthew G. Knepley 
8905fedec97SMatthew G. Knepley   Level: developer
8915fedec97SMatthew G. Knepley 
892dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8935fedec97SMatthew G. Knepley @*/
894d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
895d71ae5a4SJacob Faibussowitsch {
8965fedec97SMatthew G. Knepley   PetscInt f;
8975fedec97SMatthew G. Knepley 
8985fedec97SMatthew G. Knepley   PetscFunctionBegin;
8995fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9004f572ea9SToby Isaac   PetscAssertPointer(numCohesive, 2);
9015fedec97SMatthew G. Knepley   *numCohesive = 0;
9025fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9045fedec97SMatthew G. Knepley }
9055fedec97SMatthew G. Knepley 
9065fedec97SMatthew G. Knepley /*@
9075fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9085fedec97SMatthew G. Knepley 
90920f4b53cSBarry Smith   Not Collective
9105fedec97SMatthew G. Knepley 
911f1a722f8SMatthew G. Knepley   Input Parameters:
912dce8aebaSBarry Smith + ds - The `PetscDS` object
9135fedec97SMatthew G. Knepley - f  - The field index
9145fedec97SMatthew G. Knepley 
9155fedec97SMatthew G. Knepley   Output Parameter:
9165fedec97SMatthew G. Knepley . isCohesive - The flag
9175fedec97SMatthew G. Knepley 
9185fedec97SMatthew G. Knepley   Level: developer
9195fedec97SMatthew G. Knepley 
920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9215fedec97SMatthew G. Knepley @*/
922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
923d71ae5a4SJacob Faibussowitsch {
9245fedec97SMatthew G. Knepley   PetscFunctionBegin;
9255fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
9264f572ea9SToby Isaac   PetscAssertPointer(isCohesive, 3);
92763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9285fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9305fedec97SMatthew G. Knepley }
9315fedec97SMatthew G. Knepley 
9325fedec97SMatthew G. Knepley /*@
9335fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9348edf6225SMatthew G. Knepley 
93520f4b53cSBarry Smith   Not Collective
9368edf6225SMatthew G. Knepley 
9378edf6225SMatthew G. Knepley   Input Parameters:
938dce8aebaSBarry Smith + ds         - The `PetscDS` object
9395fedec97SMatthew G. Knepley . f          - The field index
9405fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9418edf6225SMatthew G. Knepley 
9428edf6225SMatthew G. Knepley   Level: developer
9438edf6225SMatthew G. Knepley 
944dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9458edf6225SMatthew G. Knepley @*/
946d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
947d71ae5a4SJacob Faibussowitsch {
9485fedec97SMatthew G. Knepley   PetscInt i;
9495fedec97SMatthew G. Knepley 
9508edf6225SMatthew G. Knepley   PetscFunctionBegin;
9515fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
95263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9535fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9545fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9555fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9578edf6225SMatthew G. Knepley }
9588edf6225SMatthew G. Knepley 
9598edf6225SMatthew G. Knepley /*@
960bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
961bc4ae4beSMatthew G. Knepley 
96220f4b53cSBarry Smith   Not Collective
963bc4ae4beSMatthew G. Knepley 
964bc4ae4beSMatthew G. Knepley   Input Parameter:
965dce8aebaSBarry Smith . prob - The `PetscDS` object
966bc4ae4beSMatthew G. Knepley 
967bc4ae4beSMatthew G. Knepley   Output Parameter:
968bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
969bc4ae4beSMatthew G. Knepley 
970bc4ae4beSMatthew G. Knepley   Level: beginner
971bc4ae4beSMatthew G. Knepley 
972dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
973bc4ae4beSMatthew G. Knepley @*/
974d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
975d71ae5a4SJacob Faibussowitsch {
9762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9772764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9789566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
9794f572ea9SToby Isaac   PetscAssertPointer(dim, 2);
9802764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9822764a2aaSMatthew G. Knepley }
9832764a2aaSMatthew G. Knepley 
984bc4ae4beSMatthew G. Knepley /*@
985bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
986bc4ae4beSMatthew G. Knepley 
98720f4b53cSBarry Smith   Not Collective
988bc4ae4beSMatthew G. Knepley 
989bc4ae4beSMatthew G. Knepley   Input Parameter:
990dce8aebaSBarry Smith . prob - The `PetscDS` object
991bc4ae4beSMatthew G. Knepley 
992bc4ae4beSMatthew G. Knepley   Output Parameter:
99360225df5SJacob Faibussowitsch . Nc - The total number of components
994bc4ae4beSMatthew G. Knepley 
995bc4ae4beSMatthew G. Knepley   Level: beginner
996bc4ae4beSMatthew G. Knepley 
997dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
998bc4ae4beSMatthew G. Knepley @*/
999d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
1000d71ae5a4SJacob Faibussowitsch {
10012764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10022764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10039566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
10044f572ea9SToby Isaac   PetscAssertPointer(Nc, 2);
10052764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10072764a2aaSMatthew G. Knepley }
10082764a2aaSMatthew G. Knepley 
1009bc4ae4beSMatthew G. Knepley /*@
1010bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1011bc4ae4beSMatthew G. Knepley 
101220f4b53cSBarry Smith   Not Collective
1013bc4ae4beSMatthew G. Knepley 
1014bc4ae4beSMatthew G. Knepley   Input Parameters:
1015dce8aebaSBarry Smith + prob - The `PetscDS` object
1016bc4ae4beSMatthew G. Knepley - f    - The field number
1017bc4ae4beSMatthew G. Knepley 
1018bc4ae4beSMatthew G. Knepley   Output Parameter:
1019*2192575eSBarry Smith . disc - The discretization object, this can be a `PetscFE` or a `PetscFV`
1020bc4ae4beSMatthew G. Knepley 
1021bc4ae4beSMatthew G. Knepley   Level: beginner
1022bc4ae4beSMatthew G. Knepley 
1023dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1024bc4ae4beSMatthew G. Knepley @*/
1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1026d71ae5a4SJacob Faibussowitsch {
10276528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10282764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10294f572ea9SToby Isaac   PetscAssertPointer(disc, 3);
103063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
10312764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10332764a2aaSMatthew G. Knepley }
10342764a2aaSMatthew G. Knepley 
1035bc4ae4beSMatthew G. Knepley /*@
1036bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1037bc4ae4beSMatthew G. Knepley 
103820f4b53cSBarry Smith   Not Collective
1039bc4ae4beSMatthew G. Knepley 
1040bc4ae4beSMatthew G. Knepley   Input Parameters:
1041dce8aebaSBarry Smith + prob - The `PetscDS` object
1042bc4ae4beSMatthew G. Knepley . f    - The field number
1043*2192575eSBarry Smith - disc - The discretization object, this can be a `PetscFE` or a `PetscFV`
1044bc4ae4beSMatthew G. Knepley 
1045bc4ae4beSMatthew G. Knepley   Level: beginner
1046bc4ae4beSMatthew G. Knepley 
1047dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1048bc4ae4beSMatthew G. Knepley @*/
1049d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1050d71ae5a4SJacob Faibussowitsch {
10512764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10522764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10534f572ea9SToby Isaac   if (disc) PetscAssertPointer(disc, 3);
105463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10559566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10569566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10572764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1059665f567fSMatthew G. Knepley   if (disc) {
1060249df284SMatthew G. Knepley     PetscClassId id;
1061249df284SMatthew G. Knepley 
10629566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10631cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10649566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10651cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10669566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1067a6cbbb48SMatthew G. Knepley     }
10689566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1069249df284SMatthew G. Knepley   }
10703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10712764a2aaSMatthew G. Knepley }
10722764a2aaSMatthew G. Knepley 
1073bc4ae4beSMatthew G. Knepley /*@
1074*2192575eSBarry Smith   PetscDSGetWeakForm - Returns the weak form object from within the `PetscDS`
10756528b96dSMatthew G. Knepley 
107620f4b53cSBarry Smith   Not Collective
10776528b96dSMatthew G. Knepley 
10786528b96dSMatthew G. Knepley   Input Parameter:
1079dce8aebaSBarry Smith . ds - The `PetscDS` object
10806528b96dSMatthew G. Knepley 
10816528b96dSMatthew G. Knepley   Output Parameter:
10826528b96dSMatthew G. Knepley . wf - The weak form object
10836528b96dSMatthew G. Knepley 
10846528b96dSMatthew G. Knepley   Level: beginner
10856528b96dSMatthew G. Knepley 
1086dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10876528b96dSMatthew G. Knepley @*/
1088d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1089d71ae5a4SJacob Faibussowitsch {
10906528b96dSMatthew G. Knepley   PetscFunctionBegin;
10916528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10924f572ea9SToby Isaac   PetscAssertPointer(wf, 2);
10936528b96dSMatthew G. Knepley   *wf = ds->wf;
10943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10956528b96dSMatthew G. Knepley }
10966528b96dSMatthew G. Knepley 
10976528b96dSMatthew G. Knepley /*@
1098*2192575eSBarry Smith   PetscDSSetWeakForm - Sets the weak form object to be used by the `PetscDS`
10996528b96dSMatthew G. Knepley 
110020f4b53cSBarry Smith   Not Collective
11016528b96dSMatthew G. Knepley 
11026528b96dSMatthew G. Knepley   Input Parameters:
1103dce8aebaSBarry Smith + ds - The `PetscDS` object
11046528b96dSMatthew G. Knepley - wf - The weak form object
11056528b96dSMatthew G. Knepley 
11066528b96dSMatthew G. Knepley   Level: beginner
11076528b96dSMatthew G. Knepley 
1108dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11096528b96dSMatthew G. Knepley @*/
1110d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1111d71ae5a4SJacob Faibussowitsch {
11126528b96dSMatthew G. Knepley   PetscFunctionBegin;
11136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11159566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11166528b96dSMatthew G. Knepley   ds->wf = wf;
11179566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11206528b96dSMatthew G. Knepley }
11216528b96dSMatthew G. Knepley 
11226528b96dSMatthew G. Knepley /*@
1123bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1124bc4ae4beSMatthew G. Knepley 
112520f4b53cSBarry Smith   Not Collective
1126bc4ae4beSMatthew G. Knepley 
1127bc4ae4beSMatthew G. Knepley   Input Parameters:
1128dce8aebaSBarry Smith + prob - The `PetscDS` object
1129*2192575eSBarry Smith - disc - The discretization object, this can be a `PetscFE` or `PetscFV`
1130bc4ae4beSMatthew G. Knepley 
1131bc4ae4beSMatthew G. Knepley   Level: beginner
1132bc4ae4beSMatthew G. Knepley 
1133*2192575eSBarry Smith .seealso: `PetscWeakForm`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1134bc4ae4beSMatthew G. Knepley @*/
1135d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1136d71ae5a4SJacob Faibussowitsch {
11372764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11402764a2aaSMatthew G. Knepley }
11412764a2aaSMatthew G. Knepley 
1142249df284SMatthew G. Knepley /*@
1143dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1144083401c6SMatthew G. Knepley 
114520f4b53cSBarry Smith   Not Collective
1146083401c6SMatthew G. Knepley 
1147083401c6SMatthew G. Knepley   Input Parameter:
1148dce8aebaSBarry Smith . prob - The `PetscDS` object
1149083401c6SMatthew G. Knepley 
1150083401c6SMatthew G. Knepley   Output Parameter:
1151083401c6SMatthew G. Knepley . q - The quadrature object
1152083401c6SMatthew G. Knepley 
1153083401c6SMatthew G. Knepley   Level: intermediate
1154083401c6SMatthew G. Knepley 
1155dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1156083401c6SMatthew G. Knepley @*/
1157d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1158d71ae5a4SJacob Faibussowitsch {
1159083401c6SMatthew G. Knepley   PetscObject  obj;
1160083401c6SMatthew G. Knepley   PetscClassId id;
1161083401c6SMatthew G. Knepley 
1162083401c6SMatthew G. Knepley   PetscFunctionBegin;
1163083401c6SMatthew G. Knepley   *q = NULL;
11643ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11669566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11679566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11689566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116998921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1171083401c6SMatthew G. Knepley }
1172083401c6SMatthew G. Knepley 
1173083401c6SMatthew G. Knepley /*@
11743dddbd81SStefano Zampini   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1175249df284SMatthew G. Knepley 
117620f4b53cSBarry Smith   Not Collective
1177249df284SMatthew G. Knepley 
1178249df284SMatthew G. Knepley   Input Parameters:
1179dce8aebaSBarry Smith + prob - The `PetscDS` object
1180249df284SMatthew G. Knepley - f    - The field number
1181249df284SMatthew G. Knepley 
1182249df284SMatthew G. Knepley   Output Parameter:
1183249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1184249df284SMatthew G. Knepley 
1185249df284SMatthew G. Knepley   Level: developer
1186249df284SMatthew G. Knepley 
11873dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1188249df284SMatthew G. Knepley @*/
1189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1190d71ae5a4SJacob Faibussowitsch {
1191249df284SMatthew G. Knepley   PetscFunctionBegin;
1192249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
11934f572ea9SToby Isaac   PetscAssertPointer(implicit, 3);
119463a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1195249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1197249df284SMatthew G. Knepley }
1198249df284SMatthew G. Knepley 
1199249df284SMatthew G. Knepley /*@
12003dddbd81SStefano Zampini   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSARKIMEX`
1201249df284SMatthew G. Knepley 
120220f4b53cSBarry Smith   Not Collective
1203249df284SMatthew G. Knepley 
1204249df284SMatthew G. Knepley   Input Parameters:
1205dce8aebaSBarry Smith + prob     - The `PetscDS` object
1206249df284SMatthew G. Knepley . f        - The field number
1207249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1208249df284SMatthew G. Knepley 
1209249df284SMatthew G. Knepley   Level: developer
1210249df284SMatthew G. Knepley 
12113dddbd81SStefano Zampini .seealso: `TSARKIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1212249df284SMatthew G. Knepley @*/
1213d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1214d71ae5a4SJacob Faibussowitsch {
1215249df284SMatthew G. Knepley   PetscFunctionBegin;
1216249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
121763a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1218249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1220249df284SMatthew G. Knepley }
1221249df284SMatthew G. Knepley 
1222f9244615SMatthew G. Knepley /*@
1223f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1224f9244615SMatthew G. Knepley 
122520f4b53cSBarry Smith   Not Collective
1226f9244615SMatthew G. Knepley 
1227f9244615SMatthew G. Knepley   Input Parameters:
1228dce8aebaSBarry Smith + ds - The `PetscDS` object
1229f9244615SMatthew G. Knepley - f  - The field number
1230f9244615SMatthew G. Knepley 
1231f9244615SMatthew G. Knepley   Output Parameter:
1232f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1233f9244615SMatthew G. Knepley 
1234f9244615SMatthew G. Knepley   Level: developer
1235f9244615SMatthew G. Knepley 
1236dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1237f9244615SMatthew G. Knepley @*/
1238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1239d71ae5a4SJacob Faibussowitsch {
1240f9244615SMatthew G. Knepley   PetscFunctionBegin;
1241f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12424f572ea9SToby Isaac   PetscAssertPointer(k, 3);
124363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1244f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1246f9244615SMatthew G. Knepley }
1247f9244615SMatthew G. Knepley 
1248f9244615SMatthew G. Knepley /*@
1249f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1250f9244615SMatthew G. Knepley 
125120f4b53cSBarry Smith   Not Collective
1252f9244615SMatthew G. Knepley 
1253f9244615SMatthew G. Knepley   Input Parameters:
1254dce8aebaSBarry Smith + ds - The `PetscDS` object
1255f9244615SMatthew G. Knepley . f  - The field number
1256f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1257f9244615SMatthew G. Knepley 
1258f9244615SMatthew G. Knepley   Level: developer
1259f9244615SMatthew G. Knepley 
1260a94f484eSPierre Jolivet .seealso: `PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1261f9244615SMatthew G. Knepley @*/
1262d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1263d71ae5a4SJacob Faibussowitsch {
1264f9244615SMatthew G. Knepley   PetscFunctionBegin;
1265f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
126663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1267f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1269f9244615SMatthew G. Knepley }
1270f9244615SMatthew G. Knepley 
1271c8943706SMatthew G. Knepley /*@C
1272*2192575eSBarry Smith   PetscDSGetObjective - Get the pointwise objective function for a given test field that was provided with `PetscDSSetObjective()`
1273c8943706SMatthew G. Knepley 
1274c8943706SMatthew G. Knepley   Not Collective
1275c8943706SMatthew G. Knepley 
1276c8943706SMatthew G. Knepley   Input Parameters:
1277c8943706SMatthew G. Knepley + ds - The `PetscDS`
1278c8943706SMatthew G. Knepley - f  - The test field number
1279c8943706SMatthew G. Knepley 
1280a4e35b19SJacob Faibussowitsch   Output Parameter:
1281*2192575eSBarry Smith . obj - integrand for the test function term, see `PetscPointFn`
1282c8943706SMatthew G. Knepley 
1283c8943706SMatthew G. Knepley   Level: intermediate
1284c8943706SMatthew G. Knepley 
1285c8943706SMatthew G. Knepley   Note:
12861702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1287c8943706SMatthew G. Knepley 
1288*2192575eSBarry Smith .seealso: `PetscPointFn`, `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1289c8943706SMatthew G. Knepley @*/
1290*2192575eSBarry Smith PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f, PetscPointFn **obj)
1291d71ae5a4SJacob Faibussowitsch {
1292*2192575eSBarry Smith   PetscPointFn **tmp;
12936528b96dSMatthew G. Knepley   PetscInt       n;
12946528b96dSMatthew G. Knepley 
12952764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12974f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
129863a3b9bcSJacob 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);
12999566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13006528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13022764a2aaSMatthew G. Knepley }
13032764a2aaSMatthew G. Knepley 
1304c8943706SMatthew G. Knepley /*@C
1305c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1306c8943706SMatthew G. Knepley 
1307c8943706SMatthew G. Knepley   Not Collective
1308c8943706SMatthew G. Knepley 
1309c8943706SMatthew G. Knepley   Input Parameters:
1310c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1311c8943706SMatthew G. Knepley . f   - The test field number
1312*2192575eSBarry Smith - obj - integrand for the test function term, see `PetscPointFn`
1313c8943706SMatthew G. Knepley 
1314c8943706SMatthew G. Knepley   Level: intermediate
1315c8943706SMatthew G. Knepley 
1316c8943706SMatthew G. Knepley   Note:
13171702e181SMatthew Knepley   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi\,\mathrm{obj}(u, u_t, \nabla u, x, t)$
1318c8943706SMatthew G. Knepley 
1319*2192575eSBarry Smith .seealso: `PetscPointFn`, `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1320c8943706SMatthew G. Knepley @*/
1321*2192575eSBarry Smith PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f, PetscPointFn *obj)
1322d71ae5a4SJacob Faibussowitsch {
13232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13256528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
132663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13292764a2aaSMatthew G. Knepley }
13302764a2aaSMatthew G. Knepley 
1331194d53e6SMatthew G. Knepley /*@C
1332194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1333194d53e6SMatthew G. Knepley 
133420f4b53cSBarry Smith   Not Collective
1335194d53e6SMatthew G. Knepley 
1336194d53e6SMatthew G. Knepley   Input Parameters:
1337dce8aebaSBarry Smith + ds - The `PetscDS`
1338194d53e6SMatthew G. Knepley - f  - The test field number
1339194d53e6SMatthew G. Knepley 
1340194d53e6SMatthew G. Knepley   Output Parameters:
1341*2192575eSBarry Smith + f0 - integrand for the test function term, see `PetscPointFn`
1342*2192575eSBarry Smith - f1 - integrand for the test function gradient term, see `PetscPointFn`
1343194d53e6SMatthew G. Knepley 
1344194d53e6SMatthew G. Knepley   Level: intermediate
1345194d53e6SMatthew G. Knepley 
1346dce8aebaSBarry Smith   Note:
13471d27aa22SBarry 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)$
1348dce8aebaSBarry Smith 
1349*2192575eSBarry Smith .seealso: `PetscPointFn`, `PetscDS`, `PetscDSSetResidual()`
1350194d53e6SMatthew G. Knepley @*/
1351*2192575eSBarry Smith PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, PetscPointFn **f0, PetscPointFn **f1)
1352d71ae5a4SJacob Faibussowitsch {
1353*2192575eSBarry Smith   PetscPointFn **tmp0, **tmp1;
13546528b96dSMatthew G. Knepley   PetscInt       n0, n1;
13556528b96dSMatthew G. Knepley 
13562764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
135863a3b9bcSJacob 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);
13599566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13606528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13616528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13632764a2aaSMatthew G. Knepley }
13642764a2aaSMatthew G. Knepley 
1365194d53e6SMatthew G. Knepley /*@C
1366194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1367194d53e6SMatthew G. Knepley 
136820f4b53cSBarry Smith   Not Collective
1369194d53e6SMatthew G. Knepley 
1370194d53e6SMatthew G. Knepley   Input Parameters:
1371dce8aebaSBarry Smith + ds - The `PetscDS`
1372194d53e6SMatthew G. Knepley . f  - The test field number
1373*2192575eSBarry Smith . f0 - integrand for the test function term, see `PetscPointFn`
1374*2192575eSBarry Smith - f1 - integrand for the test function gradient term, see `PetscPointFn`
1375194d53e6SMatthew G. Knepley 
1376194d53e6SMatthew G. Knepley   Level: intermediate
1377194d53e6SMatthew G. Knepley 
1378dce8aebaSBarry Smith   Note:
13791d27aa22SBarry 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)$
1380dce8aebaSBarry Smith 
1381*2192575eSBarry Smith .seealso: `PetscPointFn`, `PetscDS`, `PetscDSGetResidual()`
1382194d53e6SMatthew G. Knepley @*/
1383*2192575eSBarry Smith PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, PetscPointFn *f0, PetscPointFn *f1)
1384d71ae5a4SJacob Faibussowitsch {
13852764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13866528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1387f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1388f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
138963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
13913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13922764a2aaSMatthew G. Knepley }
13932764a2aaSMatthew G. Knepley 
13943e75805dSMatthew G. Knepley /*@C
1395cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1396cb36c0f9SMatthew G. Knepley 
139720f4b53cSBarry Smith   Not Collective
1398cb36c0f9SMatthew G. Knepley 
1399cb36c0f9SMatthew G. Knepley   Input Parameters:
1400dce8aebaSBarry Smith + ds - The `PetscDS`
1401cb36c0f9SMatthew G. Knepley - f  - The test field number
1402cb36c0f9SMatthew G. Knepley 
1403cb36c0f9SMatthew G. Knepley   Output Parameters:
1404*2192575eSBarry Smith + f0 - integrand for the test function term, see `PetscPointFn`
1405*2192575eSBarry Smith - f1 - integrand for the test function gradient term, see `PetscPointFn`
1406cb36c0f9SMatthew G. Knepley 
1407cb36c0f9SMatthew G. Knepley   Level: intermediate
1408cb36c0f9SMatthew G. Knepley 
1409dce8aebaSBarry Smith   Note:
14101d27aa22SBarry 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)$
1411dce8aebaSBarry Smith 
1412*2192575eSBarry Smith .seealso: `PetscPointFn`, `PetscDS`, `PetscDSSetRHSResidual()`
1413cb36c0f9SMatthew G. Knepley @*/
1414*2192575eSBarry Smith PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f, PetscPointFn **f0, PetscPointFn **f1)
1415d71ae5a4SJacob Faibussowitsch {
1416*2192575eSBarry Smith   PetscPointFn **tmp0, **tmp1;
1417cb36c0f9SMatthew G. Knepley   PetscInt       n0, n1;
1418cb36c0f9SMatthew G. Knepley 
1419cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1420cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
142163a3b9bcSJacob 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);
14229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1423cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1424cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1426cb36c0f9SMatthew G. Knepley }
1427cb36c0f9SMatthew G. Knepley 
1428cb36c0f9SMatthew G. Knepley /*@C
1429cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1430cb36c0f9SMatthew G. Knepley 
143120f4b53cSBarry Smith   Not Collective
1432cb36c0f9SMatthew G. Knepley 
1433cb36c0f9SMatthew G. Knepley   Input Parameters:
1434dce8aebaSBarry Smith + ds - The `PetscDS`
1435cb36c0f9SMatthew G. Knepley . f  - The test field number
1436*2192575eSBarry Smith . f0 - integrand for the test function term, see `PetscPointFn`
1437*2192575eSBarry Smith - f1 - integrand for the test function gradient term, see `PetscPointFn`
1438cb36c0f9SMatthew G. Knepley 
1439cb36c0f9SMatthew G. Knepley   Level: intermediate
1440cb36c0f9SMatthew G. Knepley 
1441dce8aebaSBarry Smith   Note:
14421d27aa22SBarry 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)$
1443dce8aebaSBarry Smith 
1444dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1445cb36c0f9SMatthew G. Knepley @*/
1446*2192575eSBarry Smith PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f, PetscPointFn *f0, PetscPointFn *f1)
1447d71ae5a4SJacob Faibussowitsch {
1448cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1449cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1450cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1451cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
145263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14539566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
14543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1455cb36c0f9SMatthew G. Knepley }
1456cb36c0f9SMatthew G. Knepley 
1457cc4c1da9SBarry Smith /*@
1458dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
14593e75805dSMatthew G. Knepley 
146020f4b53cSBarry Smith   Not Collective
14613e75805dSMatthew G. Knepley 
14623e75805dSMatthew G. Knepley   Input Parameter:
146360225df5SJacob Faibussowitsch . ds - The `PetscDS`
14643e75805dSMatthew G. Knepley 
14653e75805dSMatthew G. Knepley   Output Parameter:
1466*2192575eSBarry Smith . hasJac - flag that indicates the pointwise function for the Jacobian has been set
14673e75805dSMatthew G. Knepley 
14683e75805dSMatthew G. Knepley   Level: intermediate
14693e75805dSMatthew G. Knepley 
1470dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
14713e75805dSMatthew G. Knepley @*/
1472d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1473d71ae5a4SJacob Faibussowitsch {
14743e75805dSMatthew G. Knepley   PetscFunctionBegin;
14756528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
14769566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
14773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14783e75805dSMatthew G. Knepley }
14793e75805dSMatthew G. Knepley 
1480194d53e6SMatthew G. Knepley /*@C
1481194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1482194d53e6SMatthew G. Knepley 
148320f4b53cSBarry Smith   Not Collective
1484194d53e6SMatthew G. Knepley 
1485194d53e6SMatthew G. Knepley   Input Parameters:
1486dce8aebaSBarry Smith + ds - The `PetscDS`
1487194d53e6SMatthew G. Knepley . f  - The test field number
1488194d53e6SMatthew G. Knepley - g  - The field number
1489194d53e6SMatthew G. Knepley 
1490194d53e6SMatthew G. Knepley   Output Parameters:
1491*2192575eSBarry Smith + g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1492*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1493*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1494*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1495194d53e6SMatthew G. Knepley 
1496194d53e6SMatthew G. Knepley   Level: intermediate
1497194d53e6SMatthew G. Knepley 
1498dce8aebaSBarry Smith   Note:
1499a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
15001d27aa22SBarry Smith 
15011d27aa22SBarry Smith   $$
15021702e181SMatthew Knepley   \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
15031702e181SMatthew Knepley   + \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
15041d27aa22SBarry Smith   $$
1505dce8aebaSBarry Smith 
1506*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`, `PetscPointJacFn`
1507194d53e6SMatthew G. Knepley @*/
1508*2192575eSBarry Smith PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn **g0, PetscPointJacFn **g1, PetscPointJacFn **g2, PetscPointJacFn **g3)
1509d71ae5a4SJacob Faibussowitsch {
1510*2192575eSBarry Smith   PetscPointJacFn **tmp0, **tmp1, **tmp2, **tmp3;
15116528b96dSMatthew G. Knepley   PetscInt          n0, n1, n2, n3;
15126528b96dSMatthew G. Knepley 
15132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
151563a3b9bcSJacob 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);
151663a3b9bcSJacob 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);
15179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
15186528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
15196528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
15206528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
15216528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
15223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15232764a2aaSMatthew G. Knepley }
15242764a2aaSMatthew G. Knepley 
1525194d53e6SMatthew G. Knepley /*@C
1526194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1527194d53e6SMatthew G. Knepley 
152820f4b53cSBarry Smith   Not Collective
1529194d53e6SMatthew G. Knepley 
1530194d53e6SMatthew G. Knepley   Input Parameters:
1531dce8aebaSBarry Smith + ds - The `PetscDS`
1532194d53e6SMatthew G. Knepley . f  - The test field number
1533194d53e6SMatthew G. Knepley . g  - The field number
1534*2192575eSBarry Smith . g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1535*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1536*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1537*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1538194d53e6SMatthew G. Knepley 
1539194d53e6SMatthew G. Knepley   Level: intermediate
1540194d53e6SMatthew G. Knepley 
1541dce8aebaSBarry Smith   Note:
1542a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
15431702e181SMatthew Knepley 
15441702e181SMatthew Knepley   $$
15451702e181SMatthew Knepley   \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
15461702e181SMatthew Knepley   + \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
15471702e181SMatthew Knepley   $$
1548dce8aebaSBarry Smith 
1549*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`, `PetscPointJacFn`
1550194d53e6SMatthew G. Knepley @*/
1551*2192575eSBarry Smith PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn *g0, PetscPointJacFn *g1, PetscPointJacFn *g2, PetscPointJacFn *g3)
1552d71ae5a4SJacob Faibussowitsch {
15532764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15546528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15552764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
15562764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
15572764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
15582764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
155963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
156063a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
15619566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
15623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15632764a2aaSMatthew G. Knepley }
15642764a2aaSMatthew G. Knepley 
1565cc4c1da9SBarry Smith /*@
1566dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
156755c1f793SMatthew G. Knepley 
156820f4b53cSBarry Smith   Not Collective
156955c1f793SMatthew G. Knepley 
157055c1f793SMatthew G. Knepley   Input Parameters:
1571dce8aebaSBarry Smith + prob      - The `PetscDS`
157255c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
157355c1f793SMatthew G. Knepley 
157455c1f793SMatthew G. Knepley   Level: intermediate
157555c1f793SMatthew G. Knepley 
1576cc4c1da9SBarry Smith   Developer Note:
1577cc4c1da9SBarry Smith   Should be called `PetscDSSetUseJacobianPreconditioner()`
1578cc4c1da9SBarry Smith 
1579dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
158055c1f793SMatthew G. Knepley @*/
1581d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1582d71ae5a4SJacob Faibussowitsch {
158355c1f793SMatthew G. Knepley   PetscFunctionBegin;
158455c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
158555c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
15863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
158755c1f793SMatthew G. Knepley }
158855c1f793SMatthew G. Knepley 
1589cc4c1da9SBarry Smith /*@
1590dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1591475e0ac9SMatthew G. Knepley 
159220f4b53cSBarry Smith   Not Collective
1593475e0ac9SMatthew G. Knepley 
1594475e0ac9SMatthew G. Knepley   Input Parameter:
159560225df5SJacob Faibussowitsch . ds - The `PetscDS`
1596475e0ac9SMatthew G. Knepley 
1597475e0ac9SMatthew G. Knepley   Output Parameter:
1598475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1599475e0ac9SMatthew G. Knepley 
1600475e0ac9SMatthew G. Knepley   Level: intermediate
1601475e0ac9SMatthew G. Knepley 
1602dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1603475e0ac9SMatthew G. Knepley @*/
1604d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1605d71ae5a4SJacob Faibussowitsch {
1606475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16076528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1608475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
16093ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
16109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
16113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1612475e0ac9SMatthew G. Knepley }
1613475e0ac9SMatthew G. Knepley 
1614475e0ac9SMatthew G. Knepley /*@C
1615*2192575eSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian function for given test and basis field that constructs the matrix used
1616*2192575eSBarry Smith   to compute the preconditioner. If this is missing, the system matrix is used to build the preconditioner.
1617475e0ac9SMatthew G. Knepley 
161820f4b53cSBarry Smith   Not Collective
1619475e0ac9SMatthew G. Knepley 
1620475e0ac9SMatthew G. Knepley   Input Parameters:
1621dce8aebaSBarry Smith + ds - The `PetscDS`
1622475e0ac9SMatthew G. Knepley . f  - The test field number
1623475e0ac9SMatthew G. Knepley - g  - The field number
1624475e0ac9SMatthew G. Knepley 
1625475e0ac9SMatthew G. Knepley   Output Parameters:
1626*2192575eSBarry Smith + g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1627*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1628*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1629*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1630475e0ac9SMatthew G. Knepley 
1631475e0ac9SMatthew G. Knepley   Level: intermediate
1632475e0ac9SMatthew G. Knepley 
1633dce8aebaSBarry Smith   Note:
1634a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16351702e181SMatthew Knepley 
16361702e181SMatthew Knepley   $$
16371702e181SMatthew Knepley   \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
16381702e181SMatthew Knepley   + \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
16391702e181SMatthew Knepley   $$
1640dce8aebaSBarry Smith 
1641*2192575eSBarry Smith   Developer Note:
1642*2192575eSBarry Smith   The name is confusing since the function computes a matrix used to construct the preconditioner, not a preconditioner.
1643*2192575eSBarry Smith 
1644*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`, `PetscPointJacFn`
1645475e0ac9SMatthew G. Knepley @*/
1646*2192575eSBarry Smith PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn **g0, PetscPointJacFn **g1, PetscPointJacFn **g2, PetscPointJacFn **g3)
1647d71ae5a4SJacob Faibussowitsch {
1648*2192575eSBarry Smith   PetscPointJacFn **tmp0, **tmp1, **tmp2, **tmp3;
16496528b96dSMatthew G. Knepley   PetscInt          n0, n1, n2, n3;
16506528b96dSMatthew G. Knepley 
1651475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16526528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
165363a3b9bcSJacob 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);
165463a3b9bcSJacob 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);
16559566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16566528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16576528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16586528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16596528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1661475e0ac9SMatthew G. Knepley }
1662475e0ac9SMatthew G. Knepley 
1663475e0ac9SMatthew G. Knepley /*@C
1664*2192575eSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian function for given test and basis fields that constructs the matrix used
1665*2192575eSBarry Smith   to compute the preconditioner. If this is missing, the system matrix is used to build the preconditioner.
1666475e0ac9SMatthew G. Knepley 
166720f4b53cSBarry Smith   Not Collective
1668475e0ac9SMatthew G. Knepley 
1669475e0ac9SMatthew G. Knepley   Input Parameters:
1670dce8aebaSBarry Smith + ds - The `PetscDS`
1671475e0ac9SMatthew G. Knepley . f  - The test field number
1672475e0ac9SMatthew G. Knepley . g  - The field number
1673*2192575eSBarry Smith . g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1674*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1675*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1676*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1677475e0ac9SMatthew G. Knepley 
1678475e0ac9SMatthew G. Knepley   Level: intermediate
1679475e0ac9SMatthew G. Knepley 
1680dce8aebaSBarry Smith   Note:
1681a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16821702e181SMatthew Knepley 
16831702e181SMatthew Knepley   $$
16841702e181SMatthew Knepley   \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
16851702e181SMatthew Knepley   + \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
16861702e181SMatthew Knepley   $$
1687dce8aebaSBarry Smith 
1688*2192575eSBarry Smith   Developer Note:
1689*2192575eSBarry Smith   The name is confusing since the function computes a matrix used to construct the preconditioner, not a preconditioner.
1690*2192575eSBarry Smith 
1691*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`, `PetscPointJacFn`
1692475e0ac9SMatthew G. Knepley @*/
1693*2192575eSBarry Smith PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn *g0, PetscPointJacFn *g1, PetscPointJacFn *g2, PetscPointJacFn *g3)
1694d71ae5a4SJacob Faibussowitsch {
1695475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16966528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1697475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1698475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1699475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1700475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
170163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
170263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1705475e0ac9SMatthew G. Knepley }
1706475e0ac9SMatthew G. Knepley 
1707cc4c1da9SBarry Smith /*@
1708*2192575eSBarry Smith   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, $dF/du_t$, has been set
1709b7e05686SMatthew G. Knepley 
171020f4b53cSBarry Smith   Not Collective
1711b7e05686SMatthew G. Knepley 
1712b7e05686SMatthew G. Knepley   Input Parameter:
1713dce8aebaSBarry Smith . ds - The `PetscDS`
1714b7e05686SMatthew G. Knepley 
1715b7e05686SMatthew G. Knepley   Output Parameter:
1716b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1717b7e05686SMatthew G. Knepley 
1718b7e05686SMatthew G. Knepley   Level: intermediate
1719b7e05686SMatthew G. Knepley 
1720dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1721b7e05686SMatthew G. Knepley @*/
1722d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1723d71ae5a4SJacob Faibussowitsch {
1724b7e05686SMatthew G. Knepley   PetscFunctionBegin;
17256528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
17273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1728b7e05686SMatthew G. Knepley }
1729b7e05686SMatthew G. Knepley 
1730b7e05686SMatthew G. Knepley /*@C
1731*2192575eSBarry Smith   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, $dF/du_t$, function for given test and basis field
1732b7e05686SMatthew G. Knepley 
173320f4b53cSBarry Smith   Not Collective
1734b7e05686SMatthew G. Knepley 
1735b7e05686SMatthew G. Knepley   Input Parameters:
1736dce8aebaSBarry Smith + ds - The `PetscDS`
1737b7e05686SMatthew G. Knepley . f  - The test field number
1738b7e05686SMatthew G. Knepley - g  - The field number
1739b7e05686SMatthew G. Knepley 
1740b7e05686SMatthew G. Knepley   Output Parameters:
1741*2192575eSBarry Smith + g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1742*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1743*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1744*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1745b7e05686SMatthew G. Knepley 
1746b7e05686SMatthew G. Knepley   Level: intermediate
1747b7e05686SMatthew G. Knepley 
1748dce8aebaSBarry Smith   Note:
1749a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
17501702e181SMatthew Knepley 
17511702e181SMatthew Knepley   $$
17521702e181SMatthew Knepley   \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
17531702e181SMatthew Knepley   + \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
17541702e181SMatthew Knepley   $$
1755dce8aebaSBarry Smith 
1756*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscPointJacFn`
1757b7e05686SMatthew G. Knepley @*/
1758*2192575eSBarry Smith PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn **g0, PetscPointJacFn **g1, PetscPointJacFn **g2, PetscPointJacFn **g3)
1759d71ae5a4SJacob Faibussowitsch {
1760*2192575eSBarry Smith   PetscPointJacFn **tmp0, **tmp1, **tmp2, **tmp3;
17616528b96dSMatthew G. Knepley   PetscInt          n0, n1, n2, n3;
17626528b96dSMatthew G. Knepley 
1763b7e05686SMatthew G. Knepley   PetscFunctionBegin;
17646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
176563a3b9bcSJacob 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);
176663a3b9bcSJacob 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);
17679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17686528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17696528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17706528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17716528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1773b7e05686SMatthew G. Knepley }
1774b7e05686SMatthew G. Knepley 
1775b7e05686SMatthew G. Knepley /*@C
1776*2192575eSBarry Smith   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, $dF/du_t$, function for given test and basis fields
1777b7e05686SMatthew G. Knepley 
177820f4b53cSBarry Smith   Not Collective
1779b7e05686SMatthew G. Knepley 
1780b7e05686SMatthew G. Knepley   Input Parameters:
1781dce8aebaSBarry Smith + ds - The `PetscDS`
1782b7e05686SMatthew G. Knepley . f  - The test field number
1783b7e05686SMatthew G. Knepley . g  - The field number
1784*2192575eSBarry Smith . g0 - integrand for the test and basis function term, see `PetscPointJacFn`
1785*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscPointJacFn`
1786*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscPointJacFn`
1787*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscPointJacFn`
1788b7e05686SMatthew G. Knepley 
1789b7e05686SMatthew G. Knepley   Level: intermediate
1790b7e05686SMatthew G. Knepley 
1791dce8aebaSBarry Smith   Note:
1792a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
17931702e181SMatthew Knepley 
17941702e181SMatthew Knepley   $$
17951702e181SMatthew Knepley   \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
17961702e181SMatthew Knepley   + \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
17971702e181SMatthew Knepley   $$
1798dce8aebaSBarry Smith 
1799*2192575eSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSGetJacobian()`, `PetscPointJacFn`
1800b7e05686SMatthew G. Knepley @*/
1801*2192575eSBarry Smith PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscPointJacFn *g0, PetscPointJacFn *g1, PetscPointJacFn *g2, PetscPointJacFn *g3)
1802d71ae5a4SJacob Faibussowitsch {
1803b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1805b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1806b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1807b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1808b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
180963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
181063a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1813b7e05686SMatthew G. Knepley }
1814b7e05686SMatthew G. Knepley 
18150c2f2876SMatthew G. Knepley /*@C
18160c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
18170c2f2876SMatthew G. Knepley 
181820f4b53cSBarry Smith   Not Collective
18190c2f2876SMatthew G. Knepley 
18204165533cSJose E. Roman   Input Parameters:
1821dce8aebaSBarry Smith + ds - The `PetscDS` object
18220c2f2876SMatthew G. Knepley - f  - The field number
18230c2f2876SMatthew G. Knepley 
18244165533cSJose E. Roman   Output Parameter:
1825*2192575eSBarry Smith . r - Riemann solver, see `PetscRiemannFn`
18260c2f2876SMatthew G. Knepley 
18270c2f2876SMatthew G. Knepley   Level: intermediate
18280c2f2876SMatthew G. Knepley 
1829*2192575eSBarry Smith .seealso: `PetscDS`, `PetscRiemannFn`, `PetscDSSetRiemannSolver()`
18300c2f2876SMatthew G. Knepley @*/
1831*2192575eSBarry Smith PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f, PetscRiemannFn **r)
1832d71ae5a4SJacob Faibussowitsch {
1833*2192575eSBarry Smith   PetscRiemannFn **tmp;
18346528b96dSMatthew G. Knepley   PetscInt         n;
18356528b96dSMatthew G. Knepley 
18360c2f2876SMatthew G. Knepley   PetscFunctionBegin;
18376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18384f572ea9SToby Isaac   PetscAssertPointer(r, 3);
183963a3b9bcSJacob 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);
18409566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
18416528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
18423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18430c2f2876SMatthew G. Knepley }
18440c2f2876SMatthew G. Knepley 
18450c2f2876SMatthew G. Knepley /*@C
18460c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
18470c2f2876SMatthew G. Knepley 
184820f4b53cSBarry Smith   Not Collective
18490c2f2876SMatthew G. Knepley 
18504165533cSJose E. Roman   Input Parameters:
1851dce8aebaSBarry Smith + ds - The `PetscDS` object
18520c2f2876SMatthew G. Knepley . f  - The field number
1853*2192575eSBarry Smith - r  - Riemann solver, see `PetscRiemannFn`
18540c2f2876SMatthew G. Knepley 
18550c2f2876SMatthew G. Knepley   Level: intermediate
18560c2f2876SMatthew G. Knepley 
1857*2192575eSBarry Smith .seealso: `PetscDS`, `PetscRiemannFn`, `PetscDSGetRiemannSolver()`
18580c2f2876SMatthew G. Knepley @*/
1859*2192575eSBarry Smith PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f, PetscRiemannFn *r)
1860d71ae5a4SJacob Faibussowitsch {
18610c2f2876SMatthew G. Knepley   PetscFunctionBegin;
18626528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1863de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
186463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
18659566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
18663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18670c2f2876SMatthew G. Knepley }
18680c2f2876SMatthew G. Knepley 
186932d2bbc9SMatthew G. Knepley /*@C
187032d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
187132d2bbc9SMatthew G. Knepley 
187220f4b53cSBarry Smith   Not Collective
187332d2bbc9SMatthew G. Knepley 
187432d2bbc9SMatthew G. Knepley   Input Parameters:
1875dce8aebaSBarry Smith + ds - The `PetscDS`
187632d2bbc9SMatthew G. Knepley - f  - The field number
187732d2bbc9SMatthew G. Knepley 
1878f899ff85SJose E. Roman   Output Parameter:
1879*2192575eSBarry Smith . update - update function, see `PetscPointFn`
188032d2bbc9SMatthew G. Knepley 
188132d2bbc9SMatthew G. Knepley   Level: intermediate
188232d2bbc9SMatthew G. Knepley 
1883*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointFn`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
188432d2bbc9SMatthew G. Knepley @*/
1885*2192575eSBarry Smith PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f, PetscPointFn **update)
1886d71ae5a4SJacob Faibussowitsch {
188732d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
18886528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
188963a3b9bcSJacob 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);
18909371c9d4SSatish Balay   if (update) {
18914f572ea9SToby Isaac     PetscAssertPointer(update, 3);
18929371c9d4SSatish Balay     *update = ds->update[f];
18939371c9d4SSatish Balay   }
18943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
189532d2bbc9SMatthew G. Knepley }
189632d2bbc9SMatthew G. Knepley 
189732d2bbc9SMatthew G. Knepley /*@C
18983fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
189932d2bbc9SMatthew G. Knepley 
190020f4b53cSBarry Smith   Not Collective
190132d2bbc9SMatthew G. Knepley 
190232d2bbc9SMatthew G. Knepley   Input Parameters:
1903dce8aebaSBarry Smith + ds     - The `PetscDS`
190432d2bbc9SMatthew G. Knepley . f      - The field number
1905*2192575eSBarry Smith - update - update function, see `PetscPointFn`
190632d2bbc9SMatthew G. Knepley 
190732d2bbc9SMatthew G. Knepley   Level: intermediate
190832d2bbc9SMatthew G. Knepley 
1909*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointFn`, `PetscDSGetResidual()`
191032d2bbc9SMatthew G. Knepley @*/
1911*2192575eSBarry Smith PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f, PetscPointFn *update)
1912d71ae5a4SJacob Faibussowitsch {
191332d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
19146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
191532d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
191663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
19179566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
19186528b96dSMatthew G. Knepley   ds->update[f] = update;
19193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
192032d2bbc9SMatthew G. Knepley }
192132d2bbc9SMatthew G. Knepley 
1922*2192575eSBarry Smith /*@C
1923*2192575eSBarry Smith   PetscDSGetContext - Returns the context that was passed by `PetscDSSetContext()`
1924*2192575eSBarry Smith 
1925*2192575eSBarry Smith   Not Collective
1926*2192575eSBarry Smith 
1927*2192575eSBarry Smith   Input Parameters:
1928*2192575eSBarry Smith + ds  - The `PetscDS`
1929*2192575eSBarry Smith . f   - The field number
1930*2192575eSBarry Smith - ctx - the context
1931*2192575eSBarry Smith 
1932*2192575eSBarry Smith   Level: intermediate
1933*2192575eSBarry Smith 
1934*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointFn`, `PetscDSSetContext()`
1935*2192575eSBarry Smith @*/
1936d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
1937d71ae5a4SJacob Faibussowitsch {
19380c2f2876SMatthew G. Knepley   PetscFunctionBegin;
19396528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
194063a3b9bcSJacob 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);
19414f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
19423ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
19433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19440c2f2876SMatthew G. Knepley }
19450c2f2876SMatthew G. Knepley 
1946*2192575eSBarry Smith /*@C
1947*2192575eSBarry Smith   PetscDSSetContext - Sets the context that is passed back to some of the pointwise function callbacks used by this `PetscDS`
1948*2192575eSBarry Smith 
1949*2192575eSBarry Smith   Not Collective
1950*2192575eSBarry Smith 
1951*2192575eSBarry Smith   Input Parameters:
1952*2192575eSBarry Smith + ds  - The `PetscDS`
1953*2192575eSBarry Smith . f   - The field number
1954*2192575eSBarry Smith - ctx - the context
1955*2192575eSBarry Smith 
1956*2192575eSBarry Smith   Level: intermediate
1957*2192575eSBarry Smith 
1958*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointFn`, `PetscDSGetContext()`
1959*2192575eSBarry Smith @*/
1960d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
1961d71ae5a4SJacob Faibussowitsch {
19620c2f2876SMatthew G. Knepley   PetscFunctionBegin;
19636528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
196463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
19659566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
19666528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
19673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
19680c2f2876SMatthew G. Knepley }
19690c2f2876SMatthew G. Knepley 
1970194d53e6SMatthew G. Knepley /*@C
1971194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
1972194d53e6SMatthew G. Knepley 
197320f4b53cSBarry Smith   Not Collective
1974194d53e6SMatthew G. Knepley 
1975194d53e6SMatthew G. Knepley   Input Parameters:
19766528b96dSMatthew G. Knepley + ds - The PetscDS
1977194d53e6SMatthew G. Knepley - f  - The test field number
1978194d53e6SMatthew G. Knepley 
1979194d53e6SMatthew G. Knepley   Output Parameters:
1980*2192575eSBarry Smith + f0 - boundary integrand for the test function term, see `PetscBdPointFn`
1981*2192575eSBarry Smith - f1 - boundary integrand for the test function gradient term, see `PetscBdPointFn`
1982194d53e6SMatthew G. Knepley 
1983194d53e6SMatthew G. Knepley   Level: intermediate
1984194d53e6SMatthew G. Knepley 
1985dce8aebaSBarry Smith   Note:
1986a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
19871702e181SMatthew Knepley 
19881702e181SMatthew Knepley   $$
1989dce8aebaSBarry 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
19901702e181SMatthew Knepley   $$
1991dce8aebaSBarry Smith 
1992*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointFn`, `PetscDSSetBdResidual()`
1993194d53e6SMatthew G. Knepley @*/
1994*2192575eSBarry Smith PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, PetscBdPointFn **f0, PetscBdPointFn **f1)
1995d71ae5a4SJacob Faibussowitsch {
1996*2192575eSBarry Smith   PetscBdPointFn **tmp0, **tmp1;
19976528b96dSMatthew G. Knepley   PetscInt         n0, n1;
19986528b96dSMatthew G. Knepley 
19992764a2aaSMatthew G. Knepley   PetscFunctionBegin;
20006528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
200163a3b9bcSJacob 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);
20029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
20036528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
20046528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
20053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20062764a2aaSMatthew G. Knepley }
20072764a2aaSMatthew G. Knepley 
2008194d53e6SMatthew G. Knepley /*@C
2009194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2010194d53e6SMatthew G. Knepley 
201120f4b53cSBarry Smith   Not Collective
2012194d53e6SMatthew G. Knepley 
2013194d53e6SMatthew G. Knepley   Input Parameters:
2014dce8aebaSBarry Smith + ds - The `PetscDS`
2015194d53e6SMatthew G. Knepley . f  - The test field number
2016*2192575eSBarry Smith . f0 - boundary integrand for the test function term, see `PetscBdPointFn`
2017*2192575eSBarry Smith - f1 - boundary integrand for the test function gradient term, see `PetscBdPointFn`
2018194d53e6SMatthew G. Knepley 
2019194d53e6SMatthew G. Knepley   Level: intermediate
2020194d53e6SMatthew G. Knepley 
2021dce8aebaSBarry Smith   Note:
2022a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
20231702e181SMatthew Knepley 
20241702e181SMatthew Knepley   $$
2025dce8aebaSBarry 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
20261702e181SMatthew Knepley   $$
2027dce8aebaSBarry Smith 
2028*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointFn`, `PetscDSGetBdResidual()`
2029194d53e6SMatthew G. Knepley @*/
2030*2192575eSBarry Smith PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, PetscBdPointFn *f0, PetscBdPointFn *f1)
2031d71ae5a4SJacob Faibussowitsch {
20322764a2aaSMatthew G. Knepley   PetscFunctionBegin;
20336528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
203463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
20363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20372764a2aaSMatthew G. Knepley }
20382764a2aaSMatthew G. Knepley 
203927f02ce8SMatthew G. Knepley /*@
2040dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
204127f02ce8SMatthew G. Knepley 
204220f4b53cSBarry Smith   Not Collective
204327f02ce8SMatthew G. Knepley 
204427f02ce8SMatthew G. Knepley   Input Parameter:
2045dce8aebaSBarry Smith . ds - The `PetscDS`
204627f02ce8SMatthew G. Knepley 
204727f02ce8SMatthew G. Knepley   Output Parameter:
204827f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
204927f02ce8SMatthew G. Knepley 
205027f02ce8SMatthew G. Knepley   Level: intermediate
205127f02ce8SMatthew G. Knepley 
2052dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
205327f02ce8SMatthew G. Knepley @*/
2054d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2055d71ae5a4SJacob Faibussowitsch {
205627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
20576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20584f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
20599566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
20603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
206127f02ce8SMatthew G. Knepley }
206227f02ce8SMatthew G. Knepley 
2063194d53e6SMatthew G. Knepley /*@C
2064194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2065194d53e6SMatthew G. Knepley 
206620f4b53cSBarry Smith   Not Collective
2067194d53e6SMatthew G. Knepley 
2068194d53e6SMatthew G. Knepley   Input Parameters:
2069dce8aebaSBarry Smith + ds - The `PetscDS`
2070194d53e6SMatthew G. Knepley . f  - The test field number
2071194d53e6SMatthew G. Knepley - g  - The field number
2072194d53e6SMatthew G. Knepley 
2073194d53e6SMatthew G. Knepley   Output Parameters:
2074*2192575eSBarry Smith + g0 - integrand for the test and basis function term, see `PetscBdPointJacFn`
2075*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscBdPointJacFn`
2076*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscBdPointJacFn`
2077*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscBdPointJacFn`
2078194d53e6SMatthew G. Knepley 
2079194d53e6SMatthew G. Knepley   Level: intermediate
2080194d53e6SMatthew G. Knepley 
2081dce8aebaSBarry Smith   Note:
2082a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
20831702e181SMatthew Knepley 
20841702e181SMatthew Knepley   $$
20851702e181SMatthew Knepley   \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
20861702e181SMatthew Knepley   + \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
20871702e181SMatthew Knepley   $$
2088dce8aebaSBarry Smith 
2089*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointJacFn`, `PetscDSSetBdJacobian()`
2090194d53e6SMatthew G. Knepley @*/
2091*2192575eSBarry Smith PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscBdPointJacFn **g0, PetscBdPointJacFn **g1, PetscBdPointJacFn **g2, PetscBdPointJacFn **g3)
2092d71ae5a4SJacob Faibussowitsch {
2093*2192575eSBarry Smith   PetscBdPointJacFn **tmp0, **tmp1, **tmp2, **tmp3;
20946528b96dSMatthew G. Knepley   PetscInt            n0, n1, n2, n3;
20956528b96dSMatthew G. Knepley 
20962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
20976528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
209863a3b9bcSJacob 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);
209963a3b9bcSJacob 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);
21009566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
21016528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
21026528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
21036528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
21046528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
21053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21062764a2aaSMatthew G. Knepley }
21072764a2aaSMatthew G. Knepley 
2108194d53e6SMatthew G. Knepley /*@C
2109194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2110194d53e6SMatthew G. Knepley 
211120f4b53cSBarry Smith   Not Collective
2112194d53e6SMatthew G. Knepley 
2113194d53e6SMatthew G. Knepley   Input Parameters:
21146528b96dSMatthew G. Knepley + ds - The PetscDS
2115194d53e6SMatthew G. Knepley . f  - The test field number
2116194d53e6SMatthew G. Knepley . g  - The field number
2117*2192575eSBarry Smith . g0 - integrand for the test and basis function term, see `PetscBdPointJacFn`
2118*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscBdPointJacFn`
2119*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscBdPointJacFn`
2120*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscBdPointJacFn`
2121194d53e6SMatthew G. Knepley 
2122194d53e6SMatthew G. Knepley   Level: intermediate
2123194d53e6SMatthew G. Knepley 
2124dce8aebaSBarry Smith   Note:
2125a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
21261702e181SMatthew Knepley 
21271702e181SMatthew Knepley   $$
21281702e181SMatthew Knepley   \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
21291702e181SMatthew Knepley   + \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
21301702e181SMatthew Knepley   $$
2131dce8aebaSBarry Smith 
2132*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointJacFn`, `PetscDSGetBdJacobian()`
2133194d53e6SMatthew G. Knepley @*/
2134*2192575eSBarry Smith PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, PetscBdPointJacFn *g0, PetscBdPointJacFn *g1, PetscBdPointJacFn *g2, PetscBdPointJacFn *g3)
2135d71ae5a4SJacob Faibussowitsch {
21362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
21376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21382764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
21392764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
21402764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
21412764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
214263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
214363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
21449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
21453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21462764a2aaSMatthew G. Knepley }
21472764a2aaSMatthew G. Knepley 
214827f02ce8SMatthew G. Knepley /*@
2149*2192575eSBarry Smith   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set with `PetscDSSetBdJacobianPreconditioner()`
215027f02ce8SMatthew G. Knepley 
215120f4b53cSBarry Smith   Not Collective
215227f02ce8SMatthew G. Knepley 
215327f02ce8SMatthew G. Knepley   Input Parameter:
2154dce8aebaSBarry Smith . ds - The `PetscDS`
215527f02ce8SMatthew G. Knepley 
215627f02ce8SMatthew G. Knepley   Output Parameter:
2157*2192575eSBarry Smith . hasBdJacPre - flag that pointwise function for the boundary Jacobian matrix to construct the preconditioner has been set
215827f02ce8SMatthew G. Knepley 
215927f02ce8SMatthew G. Knepley   Level: intermediate
216027f02ce8SMatthew G. Knepley 
2161*2192575eSBarry Smith   Developer Note:
2162*2192575eSBarry Smith   The name is confusing since the function computes a matrix used to construct the preconditioner, not a preconditioner.
2163*2192575eSBarry Smith 
2164dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
216527f02ce8SMatthew G. Knepley @*/
2166d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2167d71ae5a4SJacob Faibussowitsch {
216827f02ce8SMatthew G. Knepley   PetscFunctionBegin;
21696528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21704f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
21719566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
21723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217327f02ce8SMatthew G. Knepley }
217427f02ce8SMatthew G. Knepley 
217527f02ce8SMatthew G. Knepley /*@C
2176*2192575eSBarry Smith   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian function for given test and basis field that constructs the
2177*2192575eSBarry Smith   matrix used to construct the preconditioner
217827f02ce8SMatthew G. Knepley 
217920f4b53cSBarry Smith   Not Collective; No Fortran Support
218027f02ce8SMatthew G. Knepley 
218127f02ce8SMatthew G. Knepley   Input Parameters:
2182dce8aebaSBarry Smith + ds - The `PetscDS`
218327f02ce8SMatthew G. Knepley . f  - The test field number
218427f02ce8SMatthew G. Knepley - g  - The field number
218527f02ce8SMatthew G. Knepley 
218627f02ce8SMatthew G. Knepley   Output Parameters:
2187*2192575eSBarry Smith + g0 - integrand for the test and basis function term, see `PetscBdPointJacFn`
2188*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscBdPointJacFn`
2189*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscBdPointJacFn`
2190*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscBdPointJacFn`
219127f02ce8SMatthew G. Knepley 
219227f02ce8SMatthew G. Knepley   Level: intermediate
219327f02ce8SMatthew G. Knepley 
2194dce8aebaSBarry Smith   Note:
2195a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
21961702e181SMatthew Knepley 
21971702e181SMatthew Knepley   $$
21981702e181SMatthew Knepley   \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
21991702e181SMatthew Knepley   + \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
22001702e181SMatthew Knepley   $$
2201dce8aebaSBarry Smith 
2202*2192575eSBarry Smith   Developer Note:
2203*2192575eSBarry Smith   The name is confusing since the function computes a matrix used to construct the preconditioner, not a preconditioner.
2204*2192575eSBarry Smith 
2205*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointJacFn`, `PetscDSSetBdJacobianPreconditioner()`
220627f02ce8SMatthew G. Knepley @*/
2207*2192575eSBarry Smith PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, PetscBdPointJacFn **g0, PetscBdPointJacFn **g1, PetscBdPointJacFn **g2, PetscBdPointJacFn **g3)
2208d71ae5a4SJacob Faibussowitsch {
2209*2192575eSBarry Smith   PetscBdPointJacFn **tmp0, **tmp1, **tmp2, **tmp3;
22106528b96dSMatthew G. Knepley   PetscInt            n0, n1, n2, n3;
22116528b96dSMatthew G. Knepley 
221227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
22136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
221463a3b9bcSJacob 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);
221563a3b9bcSJacob 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);
22169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
22176528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
22186528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
22196528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
22206528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
22213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
222227f02ce8SMatthew G. Knepley }
222327f02ce8SMatthew G. Knepley 
222427f02ce8SMatthew G. Knepley /*@C
2225*2192575eSBarry Smith   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field that constructs the
2226*2192575eSBarry Smith   matrix used to construct the preconditioner
222727f02ce8SMatthew G. Knepley 
222820f4b53cSBarry Smith   Not Collective; No Fortran Support
222927f02ce8SMatthew G. Knepley 
223027f02ce8SMatthew G. Knepley   Input Parameters:
2231dce8aebaSBarry Smith + ds - The `PetscDS`
223227f02ce8SMatthew G. Knepley . f  - The test field number
223327f02ce8SMatthew G. Knepley . g  - The field number
2234*2192575eSBarry Smith . g0 - integrand for the test and basis function term, see `PetscBdPointJacFn`
2235*2192575eSBarry Smith . g1 - integrand for the test function and basis function gradient term, see `PetscBdPointJacFn`
2236*2192575eSBarry Smith . g2 - integrand for the test function gradient and basis function term, see `PetscBdPointJacFn`
2237*2192575eSBarry Smith - g3 - integrand for the test function gradient and basis function gradient term, see `PetscBdPointJacFn`
223827f02ce8SMatthew G. Knepley 
223927f02ce8SMatthew G. Knepley   Level: intermediate
224027f02ce8SMatthew G. Knepley 
2241dce8aebaSBarry Smith   Note:
2242a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
22431702e181SMatthew Knepley 
22441702e181SMatthew Knepley   $$
22451702e181SMatthew Knepley   \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
22461702e181SMatthew Knepley   + \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
22471702e181SMatthew Knepley   $$
2248dce8aebaSBarry Smith 
2249*2192575eSBarry Smith   Developer Note:
2250*2192575eSBarry Smith   The name is confusing since the function computes a matrix used to construct the preconditioner, not a preconditioner.
2251*2192575eSBarry Smith 
2252*2192575eSBarry Smith .seealso: `PetscDS`, `PetscBdPointJacFn`, `PetscDSGetBdJacobianPreconditioner()`
225327f02ce8SMatthew G. Knepley @*/
2254*2192575eSBarry Smith PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, PetscBdPointJacFn *g0, PetscBdPointJacFn *g1, PetscBdPointJacFn *g2, PetscBdPointJacFn *g3)
2255d71ae5a4SJacob Faibussowitsch {
225627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
22576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225827f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
225927f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
226027f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
226127f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
226263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
226363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
22649566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
22653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
226627f02ce8SMatthew G. Knepley }
226727f02ce8SMatthew G. Knepley 
22680d3e9b51SMatthew G. Knepley /*@C
2269c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2270c371a6d1SMatthew G. Knepley 
227120f4b53cSBarry Smith   Not Collective
2272c371a6d1SMatthew G. Knepley 
2273c371a6d1SMatthew G. Knepley   Input Parameters:
2274*2192575eSBarry Smith + prob - The `PetscDS`
2275c371a6d1SMatthew G. Knepley - f    - The test field number
2276c371a6d1SMatthew G. Knepley 
2277d8d19677SJose E. Roman   Output Parameters:
2278*2192575eSBarry Smith + sol - exact solution function for the test field, see `PetscPointExactSolutionFn`
2279a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2280c371a6d1SMatthew G. Knepley 
2281c371a6d1SMatthew G. Knepley   Level: intermediate
2282c371a6d1SMatthew G. Knepley 
2283*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointExactSolutionFn`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2284c371a6d1SMatthew G. Knepley @*/
2285*2192575eSBarry Smith PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscPointExactSolutionFn **sol, void **ctx)
2286d71ae5a4SJacob Faibussowitsch {
2287c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2288c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
228963a3b9bcSJacob 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);
22909371c9d4SSatish Balay   if (sol) {
22914f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
22929371c9d4SSatish Balay     *sol = prob->exactSol[f];
22939371c9d4SSatish Balay   }
22949371c9d4SSatish Balay   if (ctx) {
22954f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
22969371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
22979371c9d4SSatish Balay   }
22983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2299c371a6d1SMatthew G. Knepley }
2300c371a6d1SMatthew G. Knepley 
2301c371a6d1SMatthew G. Knepley /*@C
2302578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2303c371a6d1SMatthew G. Knepley 
230420f4b53cSBarry Smith   Not Collective
2305c371a6d1SMatthew G. Knepley 
2306c371a6d1SMatthew G. Knepley   Input Parameters:
2307dce8aebaSBarry Smith + prob - The `PetscDS`
2308c371a6d1SMatthew G. Knepley . f    - The test field number
2309*2192575eSBarry Smith . sol  - solution function for the test fields, see `PetscPointExactSolutionFn`
231020f4b53cSBarry Smith - ctx  - solution context or `NULL`
2311c371a6d1SMatthew G. Knepley 
2312c371a6d1SMatthew G. Knepley   Level: intermediate
2313c371a6d1SMatthew G. Knepley 
2314*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointExactSolutionFn`, `PetscDSGetExactSolution()`
2315c371a6d1SMatthew G. Knepley @*/
2316*2192575eSBarry Smith PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscPointExactSolutionFn *sol, void *ctx)
2317d71ae5a4SJacob Faibussowitsch {
2318c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2319c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
232063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23219566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
23229371c9d4SSatish Balay   if (sol) {
23239371c9d4SSatish Balay     PetscValidFunction(sol, 3);
23249371c9d4SSatish Balay     prob->exactSol[f] = sol;
23259371c9d4SSatish Balay   }
23269371c9d4SSatish Balay   if (ctx) {
23279371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
23289371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
23299371c9d4SSatish Balay   }
23303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2331c371a6d1SMatthew G. Knepley }
2332c371a6d1SMatthew G. Knepley 
23335638fd0eSMatthew G. Knepley /*@C
2334f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2335f2cacb80SMatthew G. Knepley 
233620f4b53cSBarry Smith   Not Collective
2337f2cacb80SMatthew G. Knepley 
2338f2cacb80SMatthew G. Knepley   Input Parameters:
2339dce8aebaSBarry Smith + prob - The `PetscDS`
2340f2cacb80SMatthew G. Knepley - f    - The test field number
2341f2cacb80SMatthew G. Knepley 
2342d8d19677SJose E. Roman   Output Parameters:
2343*2192575eSBarry Smith + sol - time derivative of the exact solution for the test field, see `PetscPointExactSolutionFn`
2344*2192575eSBarry Smith - ctx - the exact solution context
2345f2cacb80SMatthew G. Knepley 
2346f2cacb80SMatthew G. Knepley   Level: intermediate
2347f2cacb80SMatthew G. Knepley 
2348*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointExactSolutionFn`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2349f2cacb80SMatthew G. Knepley @*/
2350*2192575eSBarry Smith PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscPointExactSolutionFn **sol, void **ctx)
2351d71ae5a4SJacob Faibussowitsch {
2352f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2353f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
235463a3b9bcSJacob 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);
23559371c9d4SSatish Balay   if (sol) {
23564f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
23579371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
23589371c9d4SSatish Balay   }
23599371c9d4SSatish Balay   if (ctx) {
23604f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
23619371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
23629371c9d4SSatish Balay   }
23633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2364f2cacb80SMatthew G. Knepley }
2365f2cacb80SMatthew G. Knepley 
2366f2cacb80SMatthew G. Knepley /*@C
2367f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2368f2cacb80SMatthew G. Knepley 
236920f4b53cSBarry Smith   Not Collective
2370f2cacb80SMatthew G. Knepley 
2371f2cacb80SMatthew G. Knepley   Input Parameters:
2372dce8aebaSBarry Smith + prob - The `PetscDS`
2373f2cacb80SMatthew G. Knepley . f    - The test field number
2374*2192575eSBarry Smith . sol  - time derivative of the solution function for the test fields, see `PetscPointExactSolutionFn`
2375*2192575eSBarry Smith - ctx  - the solution context or `NULL`
2376f2cacb80SMatthew G. Knepley 
2377f2cacb80SMatthew G. Knepley   Level: intermediate
2378f2cacb80SMatthew G. Knepley 
2379*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointExactSolutionFn`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2380f2cacb80SMatthew G. Knepley @*/
2381*2192575eSBarry Smith PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscPointExactSolutionFn *sol, void *ctx)
2382d71ae5a4SJacob Faibussowitsch {
2383f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2384f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
238563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23869566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
23879371c9d4SSatish Balay   if (sol) {
23889371c9d4SSatish Balay     PetscValidFunction(sol, 3);
23899371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
23909371c9d4SSatish Balay   }
23919371c9d4SSatish Balay   if (ctx) {
23929371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
23939371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
23949371c9d4SSatish Balay   }
23953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2396f2cacb80SMatthew G. Knepley }
2397f2cacb80SMatthew G. Knepley 
2398f2cacb80SMatthew G. Knepley /*@C
2399342bd5aaSMatthew G. Knepley   PetscDSGetLowerBound - Get the pointwise lower bound function for a given field
2400342bd5aaSMatthew G. Knepley 
2401342bd5aaSMatthew G. Knepley   Not Collective
2402342bd5aaSMatthew G. Knepley 
2403342bd5aaSMatthew G. Knepley   Input Parameters:
2404342bd5aaSMatthew G. Knepley + ds - The PetscDS
2405342bd5aaSMatthew G. Knepley - f  - The field number
2406342bd5aaSMatthew G. Knepley 
2407342bd5aaSMatthew G. Knepley   Output Parameters:
2408*2192575eSBarry Smith + lb  - lower bound function for the field, see `PetscPointBoundFn`
2409*2192575eSBarry Smith - ctx - lower bound context that was set with `PetscDSSetLowerBound()`
2410342bd5aaSMatthew G. Knepley 
2411342bd5aaSMatthew G. Knepley   Level: intermediate
2412342bd5aaSMatthew G. Knepley 
2413*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointBoundFn`, `PetscDSSetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2414342bd5aaSMatthew G. Knepley @*/
2415*2192575eSBarry Smith PetscErrorCode PetscDSGetLowerBound(PetscDS ds, PetscInt f, PetscPointBoundFn **lb, void **ctx)
2416342bd5aaSMatthew G. Knepley {
2417342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2418342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2419342bd5aaSMatthew G. Knepley   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);
2420342bd5aaSMatthew G. Knepley   if (lb) {
2421342bd5aaSMatthew G. Knepley     PetscAssertPointer(lb, 3);
2422342bd5aaSMatthew G. Knepley     *lb = ds->lowerBound[f];
2423342bd5aaSMatthew G. Knepley   }
2424342bd5aaSMatthew G. Knepley   if (ctx) {
2425342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2426342bd5aaSMatthew G. Knepley     *ctx = ds->lowerCtx[f];
2427342bd5aaSMatthew G. Knepley   }
2428342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2429342bd5aaSMatthew G. Knepley }
2430342bd5aaSMatthew G. Knepley 
2431342bd5aaSMatthew G. Knepley /*@C
2432342bd5aaSMatthew G. Knepley   PetscDSSetLowerBound - Set the pointwise lower bound function for a given field
2433342bd5aaSMatthew G. Knepley 
2434342bd5aaSMatthew G. Knepley   Not Collective
2435342bd5aaSMatthew G. Knepley 
2436342bd5aaSMatthew G. Knepley   Input Parameters:
2437342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2438342bd5aaSMatthew G. Knepley . f   - The field number
2439*2192575eSBarry Smith . lb  - lower bound function for the test fields, see `PetscPointBoundFn`
2440*2192575eSBarry Smith - ctx - lower bound context or `NULL` which will be passed to `lb`
2441342bd5aaSMatthew G. Knepley 
2442342bd5aaSMatthew G. Knepley   Level: intermediate
2443342bd5aaSMatthew G. Knepley 
2444*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointBoundFn`, `PetscDSGetLowerBound()`, `PetscDSGetUpperBound()`, `PetscDSGetExactSolution()`
2445342bd5aaSMatthew G. Knepley @*/
2446*2192575eSBarry Smith PetscErrorCode PetscDSSetLowerBound(PetscDS ds, PetscInt f, PetscPointBoundFn *lb, void *ctx)
2447342bd5aaSMatthew G. Knepley {
2448342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2449342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2450342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
2451342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
2452342bd5aaSMatthew G. Knepley   if (lb) {
2453342bd5aaSMatthew G. Knepley     PetscValidFunction(lb, 3);
2454342bd5aaSMatthew G. Knepley     ds->lowerBound[f] = lb;
2455342bd5aaSMatthew G. Knepley   }
2456342bd5aaSMatthew G. Knepley   if (ctx) {
2457342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
2458342bd5aaSMatthew G. Knepley     ds->lowerCtx[f] = ctx;
2459342bd5aaSMatthew G. Knepley   }
2460342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2461342bd5aaSMatthew G. Knepley }
2462342bd5aaSMatthew G. Knepley 
2463342bd5aaSMatthew G. Knepley /*@C
2464342bd5aaSMatthew G. Knepley   PetscDSGetUpperBound - Get the pointwise upper bound function for a given field
2465342bd5aaSMatthew G. Knepley 
2466342bd5aaSMatthew G. Knepley   Not Collective
2467342bd5aaSMatthew G. Knepley 
2468342bd5aaSMatthew G. Knepley   Input Parameters:
2469*2192575eSBarry Smith + ds - The `PetscDS`
2470342bd5aaSMatthew G. Knepley - f  - The field number
2471342bd5aaSMatthew G. Knepley 
2472342bd5aaSMatthew G. Knepley   Output Parameters:
2473*2192575eSBarry Smith + ub  - upper bound function for the field, see `PetscPointBoundFn`
2474*2192575eSBarry Smith - ctx - upper bound context that was set with `PetscDSSetUpperBound()`
2475342bd5aaSMatthew G. Knepley 
2476342bd5aaSMatthew G. Knepley   Level: intermediate
2477342bd5aaSMatthew G. Knepley 
2478*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointBoundFn`, `PetscDSSetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
2479342bd5aaSMatthew G. Knepley @*/
2480*2192575eSBarry Smith PetscErrorCode PetscDSGetUpperBound(PetscDS ds, PetscInt f, PetscPointBoundFn **ub, void **ctx)
2481342bd5aaSMatthew G. Knepley {
2482342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2483342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2484342bd5aaSMatthew G. Knepley   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);
2485342bd5aaSMatthew G. Knepley   if (ub) {
2486342bd5aaSMatthew G. Knepley     PetscAssertPointer(ub, 3);
2487342bd5aaSMatthew G. Knepley     *ub = ds->upperBound[f];
2488342bd5aaSMatthew G. Knepley   }
2489342bd5aaSMatthew G. Knepley   if (ctx) {
2490342bd5aaSMatthew G. Knepley     PetscAssertPointer(ctx, 4);
2491342bd5aaSMatthew G. Knepley     *ctx = ds->upperCtx[f];
2492342bd5aaSMatthew G. Knepley   }
2493342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2494342bd5aaSMatthew G. Knepley }
2495342bd5aaSMatthew G. Knepley 
2496342bd5aaSMatthew G. Knepley /*@C
2497342bd5aaSMatthew G. Knepley   PetscDSSetUpperBound - Set the pointwise upper bound function for a given field
2498342bd5aaSMatthew G. Knepley 
2499342bd5aaSMatthew G. Knepley   Not Collective
2500342bd5aaSMatthew G. Knepley 
2501342bd5aaSMatthew G. Knepley   Input Parameters:
2502342bd5aaSMatthew G. Knepley + ds  - The `PetscDS`
2503342bd5aaSMatthew G. Knepley . f   - The field number
2504*2192575eSBarry Smith . ub  - upper bound function for the test fields, see `PetscPointBoundFn`
2505*2192575eSBarry Smith - ctx - context or `NULL` that will be passed to `ub`
2506342bd5aaSMatthew G. Knepley 
2507342bd5aaSMatthew G. Knepley   Level: intermediate
2508342bd5aaSMatthew G. Knepley 
2509*2192575eSBarry Smith .seealso: `PetscDS`, `PetscPointBoundFn`, `PetscDSGetUpperBound()`, `PetscDSGetLowerBound()`, `PetscDSGetExactSolution()`
2510342bd5aaSMatthew G. Knepley @*/
2511*2192575eSBarry Smith PetscErrorCode PetscDSSetUpperBound(PetscDS ds, PetscInt f, PetscPointBoundFn *ub, void *ctx)
2512342bd5aaSMatthew G. Knepley {
2513342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
2514342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2515342bd5aaSMatthew G. Knepley   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
2516342bd5aaSMatthew G. Knepley   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
2517342bd5aaSMatthew G. Knepley   if (ub) {
2518342bd5aaSMatthew G. Knepley     PetscValidFunction(ub, 3);
2519342bd5aaSMatthew G. Knepley     ds->upperBound[f] = ub;
2520342bd5aaSMatthew G. Knepley   }
2521342bd5aaSMatthew G. Knepley   if (ctx) {
2522342bd5aaSMatthew G. Knepley     PetscValidFunction(ctx, 4);
2523342bd5aaSMatthew G. Knepley     ds->upperCtx[f] = ctx;
2524342bd5aaSMatthew G. Knepley   }
2525342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
2526342bd5aaSMatthew G. Knepley }
2527342bd5aaSMatthew G. Knepley 
2528342bd5aaSMatthew G. Knepley /*@C
2529*2192575eSBarry Smith   PetscDSGetConstants - Returns the array of constants passed to point functions from a `PetscDS` object
253097b6e6e8SMatthew G. Knepley 
253120f4b53cSBarry Smith   Not Collective
253297b6e6e8SMatthew G. Knepley 
253397b6e6e8SMatthew G. Knepley   Input Parameter:
2534a102dd69SStefano Zampini . ds - The `PetscDS` object
253597b6e6e8SMatthew G. Knepley 
253697b6e6e8SMatthew G. Knepley   Output Parameters:
2537ce78bad3SBarry Smith + numConstants - The number of constants, or pass in `NULL` if not required
2538ce78bad3SBarry Smith - constants    - The array of constants, `NULL` if there are none
253997b6e6e8SMatthew G. Knepley 
254097b6e6e8SMatthew G. Knepley   Level: intermediate
254197b6e6e8SMatthew G. Knepley 
2542dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
254397b6e6e8SMatthew G. Knepley @*/
2544ce78bad3SBarry Smith PetscErrorCode PetscDSGetConstants(PetscDS ds, PeOp PetscInt *numConstants, PeOp const PetscScalar *constants[])
2545d71ae5a4SJacob Faibussowitsch {
254697b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
2547a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25489371c9d4SSatish Balay   if (numConstants) {
25494f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
2550a102dd69SStefano Zampini     *numConstants = ds->numConstants;
25519371c9d4SSatish Balay   }
25529371c9d4SSatish Balay   if (constants) {
25534f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
2554a102dd69SStefano Zampini     *constants = ds->constants;
25559371c9d4SSatish Balay   }
25563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
255797b6e6e8SMatthew G. Knepley }
255897b6e6e8SMatthew G. Knepley 
25590d3e9b51SMatthew G. Knepley /*@C
2560*2192575eSBarry Smith   PetscDSSetConstants - Set the array of constants passed to point functions from a `PetscDS`
256197b6e6e8SMatthew G. Knepley 
256220f4b53cSBarry Smith   Not Collective
256397b6e6e8SMatthew G. Knepley 
256497b6e6e8SMatthew G. Knepley   Input Parameters:
2565a102dd69SStefano Zampini + ds           - The `PetscDS` object
256697b6e6e8SMatthew G. Knepley . numConstants - The number of constants
2567a3b724e8SBarry Smith - constants    - The array of constants, `NULL` if there are none
256897b6e6e8SMatthew G. Knepley 
256997b6e6e8SMatthew G. Knepley   Level: intermediate
257097b6e6e8SMatthew G. Knepley 
2571dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
257297b6e6e8SMatthew G. Knepley @*/
2573a102dd69SStefano Zampini PetscErrorCode PetscDSSetConstants(PetscDS ds, PetscInt numConstants, PetscScalar constants[])
2574d71ae5a4SJacob Faibussowitsch {
257597b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
2576a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2577a102dd69SStefano Zampini   if (numConstants != ds->numConstants) {
2578a102dd69SStefano Zampini     PetscCall(PetscFree(ds->constants));
2579a102dd69SStefano Zampini     ds->numConstants = numConstants;
2580a102dd69SStefano Zampini     PetscCall(PetscMalloc1(ds->numConstants + ds->numFuncConstants, &ds->constants));
258120be0f5bSMatthew G. Knepley   }
2582a102dd69SStefano Zampini   if (ds->numConstants) {
25834f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
2584a102dd69SStefano Zampini     PetscCall(PetscArraycpy(ds->constants, constants, ds->numConstants));
258597b6e6e8SMatthew G. Knepley   }
25863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
258797b6e6e8SMatthew G. Knepley }
258897b6e6e8SMatthew G. Knepley 
2589a102dd69SStefano Zampini /*@C
2590a102dd69SStefano Zampini   PetscDSSetIntegrationParameters - Set the parameters for a particular integration
2591a102dd69SStefano Zampini 
2592a102dd69SStefano Zampini   Not Collective
2593a102dd69SStefano Zampini 
2594a102dd69SStefano Zampini   Input Parameters:
2595a102dd69SStefano Zampini + ds     - The `PetscDS` object
2596*2192575eSBarry Smith . fieldI - The test field for a given point function, or `PETSC_DETERMINE`
2597*2192575eSBarry Smith - fieldJ - The basis field for a given point function, or `PETSC_DETERMINE`
2598a102dd69SStefano Zampini 
2599a102dd69SStefano Zampini   Level: intermediate
2600a102dd69SStefano Zampini 
2601a102dd69SStefano Zampini .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
2602a102dd69SStefano Zampini @*/
2603a102dd69SStefano Zampini PetscErrorCode PetscDSSetIntegrationParameters(PetscDS ds, PetscInt fieldI, PetscInt fieldJ)
2604a102dd69SStefano Zampini {
2605a102dd69SStefano Zampini   PetscFunctionBegin;
2606a102dd69SStefano Zampini   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2607a102dd69SStefano Zampini   ds->constants[ds->numConstants]     = fieldI;
2608a102dd69SStefano Zampini   ds->constants[ds->numConstants + 1] = fieldJ;
2609a102dd69SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
2610a102dd69SStefano Zampini }
2611a102dd69SStefano Zampini 
261287510d7dSMatthew G. Knepley /*@C
261387510d7dSMatthew G. Knepley   PetscDSSetCellParameters - Set the parameters for a particular cell
261487510d7dSMatthew G. Knepley 
261587510d7dSMatthew G. Knepley   Not Collective
261687510d7dSMatthew G. Knepley 
261787510d7dSMatthew G. Knepley   Input Parameters:
261887510d7dSMatthew G. Knepley + ds     - The `PetscDS` object
261987510d7dSMatthew G. Knepley - volume - The cell volume
262087510d7dSMatthew G. Knepley 
262187510d7dSMatthew G. Knepley   Level: intermediate
262287510d7dSMatthew G. Knepley 
262387510d7dSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSGetConstants()`, `PetscDSCreate()`
262487510d7dSMatthew G. Knepley @*/
262587510d7dSMatthew G. Knepley PetscErrorCode PetscDSSetCellParameters(PetscDS ds, PetscReal volume)
262687510d7dSMatthew G. Knepley {
262787510d7dSMatthew G. Knepley   PetscFunctionBegin;
262887510d7dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
262987510d7dSMatthew G. Knepley   ds->constants[ds->numConstants + 2] = volume;
263087510d7dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
263187510d7dSMatthew G. Knepley }
263287510d7dSMatthew G. Knepley 
26334cd1e086SMatthew G. Knepley /*@
26344cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
26354cd1e086SMatthew G. Knepley 
263620f4b53cSBarry Smith   Not Collective
26374cd1e086SMatthew G. Knepley 
26384cd1e086SMatthew G. Knepley   Input Parameters:
2639dce8aebaSBarry Smith + prob - The `PetscDS` object
26404cd1e086SMatthew G. Knepley - disc - The discretization object
26414cd1e086SMatthew G. Knepley 
26424cd1e086SMatthew G. Knepley   Output Parameter:
26434cd1e086SMatthew G. Knepley . f - The field number
26444cd1e086SMatthew G. Knepley 
26454cd1e086SMatthew G. Knepley   Level: beginner
26464cd1e086SMatthew G. Knepley 
2647dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
26484cd1e086SMatthew G. Knepley @*/
2649d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2650d71ae5a4SJacob Faibussowitsch {
26514cd1e086SMatthew G. Knepley   PetscInt g;
26524cd1e086SMatthew G. Knepley 
26534cd1e086SMatthew G. Knepley   PetscFunctionBegin;
26544cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
26554f572ea9SToby Isaac   PetscAssertPointer(f, 3);
26564cd1e086SMatthew G. Knepley   *f = -1;
26579371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
26589371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
26599371c9d4SSatish Balay   }
266008401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
26614cd1e086SMatthew G. Knepley   *f = g;
26623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26634cd1e086SMatthew G. Knepley }
26644cd1e086SMatthew G. Knepley 
26654cd1e086SMatthew G. Knepley /*@
26664cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
26674cd1e086SMatthew G. Knepley 
266820f4b53cSBarry Smith   Not Collective
26694cd1e086SMatthew G. Knepley 
26704cd1e086SMatthew G. Knepley   Input Parameters:
2671dce8aebaSBarry Smith + prob - The `PetscDS` object
26724cd1e086SMatthew G. Knepley - f    - The field number
26734cd1e086SMatthew G. Knepley 
26744cd1e086SMatthew G. Knepley   Output Parameter:
26754cd1e086SMatthew G. Knepley . size - The size
26764cd1e086SMatthew G. Knepley 
26774cd1e086SMatthew G. Knepley   Level: beginner
26784cd1e086SMatthew G. Knepley 
2679dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
26804cd1e086SMatthew G. Knepley @*/
2681d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2682d71ae5a4SJacob Faibussowitsch {
26834cd1e086SMatthew G. Knepley   PetscFunctionBegin;
26844cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
26854f572ea9SToby Isaac   PetscAssertPointer(size, 3);
268663a3b9bcSJacob 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);
26879566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2688d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
26893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26904cd1e086SMatthew G. Knepley }
26914cd1e086SMatthew G. Knepley 
2692bc4ae4beSMatthew G. Knepley /*@
2693bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2694bc4ae4beSMatthew G. Knepley 
269520f4b53cSBarry Smith   Not Collective
2696bc4ae4beSMatthew G. Knepley 
2697bc4ae4beSMatthew G. Knepley   Input Parameters:
2698dce8aebaSBarry Smith + prob - The `PetscDS` object
2699bc4ae4beSMatthew G. Knepley - f    - The field number
2700bc4ae4beSMatthew G. Knepley 
2701bc4ae4beSMatthew G. Knepley   Output Parameter:
2702bc4ae4beSMatthew G. Knepley . off - The offset
2703bc4ae4beSMatthew G. Knepley 
2704bc4ae4beSMatthew G. Knepley   Level: beginner
2705bc4ae4beSMatthew G. Knepley 
2706dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2707bc4ae4beSMatthew G. Knepley @*/
2708d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2709d71ae5a4SJacob Faibussowitsch {
27104cd1e086SMatthew G. Knepley   PetscInt size, g;
27112764a2aaSMatthew G. Knepley 
27122764a2aaSMatthew G. Knepley   PetscFunctionBegin;
27132764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
27144f572ea9SToby Isaac   PetscAssertPointer(off, 3);
271563a3b9bcSJacob 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);
27162764a2aaSMatthew G. Knepley   *off = 0;
27172764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
27189566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
27194cd1e086SMatthew G. Knepley     *off += size;
27202764a2aaSMatthew G. Knepley   }
27213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27222764a2aaSMatthew G. Knepley }
27232764a2aaSMatthew G. Knepley 
2724bc4ae4beSMatthew G. Knepley /*@
27255fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
27265fedec97SMatthew G. Knepley 
272720f4b53cSBarry Smith   Not Collective
27285fedec97SMatthew G. Knepley 
27295fedec97SMatthew G. Knepley   Input Parameters:
273060225df5SJacob Faibussowitsch + ds - The `PetscDS` object
27315fedec97SMatthew G. Knepley - f  - The field number
27325fedec97SMatthew G. Knepley 
27335fedec97SMatthew G. Knepley   Output Parameter:
27345fedec97SMatthew G. Knepley . off - The offset
27355fedec97SMatthew G. Knepley 
27365fedec97SMatthew G. Knepley   Level: beginner
27375fedec97SMatthew G. Knepley 
2738dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
27395fedec97SMatthew G. Knepley @*/
2740d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2741d71ae5a4SJacob Faibussowitsch {
27425fedec97SMatthew G. Knepley   PetscInt size, g;
27435fedec97SMatthew G. Knepley 
27445fedec97SMatthew G. Knepley   PetscFunctionBegin;
27455fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
27464f572ea9SToby Isaac   PetscAssertPointer(off, 3);
274763a3b9bcSJacob 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);
27485fedec97SMatthew G. Knepley   *off = 0;
27495fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
27505fedec97SMatthew G. Knepley     PetscBool cohesive;
27515fedec97SMatthew G. Knepley 
27529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
27539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
27545fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
27555fedec97SMatthew G. Knepley   }
27563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27575fedec97SMatthew G. Knepley }
27585fedec97SMatthew G. Knepley 
27595fedec97SMatthew G. Knepley /*@
276047e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2761bc4ae4beSMatthew G. Knepley 
276220f4b53cSBarry Smith   Not Collective
2763bc4ae4beSMatthew G. Knepley 
276447e57110SSander Arens   Input Parameter:
2765dce8aebaSBarry Smith . prob - The `PetscDS` object
2766bc4ae4beSMatthew G. Knepley 
2767bc4ae4beSMatthew G. Knepley   Output Parameter:
276847e57110SSander Arens . dimensions - The number of dimensions
2769bc4ae4beSMatthew G. Knepley 
2770bc4ae4beSMatthew G. Knepley   Level: beginner
2771bc4ae4beSMatthew G. Knepley 
2772dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2773bc4ae4beSMatthew G. Knepley @*/
2774d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2775d71ae5a4SJacob Faibussowitsch {
27762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
27772764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
27789566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
27794f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
278047e57110SSander Arens   *dimensions = prob->Nb;
27813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27826ce16762SMatthew G. Knepley }
278347e57110SSander Arens 
278447e57110SSander Arens /*@
278547e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
278647e57110SSander Arens 
278720f4b53cSBarry Smith   Not Collective
278847e57110SSander Arens 
278947e57110SSander Arens   Input Parameter:
2790dce8aebaSBarry Smith . prob - The `PetscDS` object
279147e57110SSander Arens 
279247e57110SSander Arens   Output Parameter:
279347e57110SSander Arens . components - The number of components
279447e57110SSander Arens 
279547e57110SSander Arens   Level: beginner
279647e57110SSander Arens 
2797dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
279847e57110SSander Arens @*/
2799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
2800d71ae5a4SJacob Faibussowitsch {
280147e57110SSander Arens   PetscFunctionBegin;
280247e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28039566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
28044f572ea9SToby Isaac   PetscAssertPointer(components, 2);
280547e57110SSander Arens   *components = prob->Nc;
28063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28076ce16762SMatthew G. Knepley }
28086ce16762SMatthew G. Knepley 
28096ce16762SMatthew G. Knepley /*@
28106ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
28116ce16762SMatthew G. Knepley 
281220f4b53cSBarry Smith   Not Collective
28136ce16762SMatthew G. Knepley 
28146ce16762SMatthew G. Knepley   Input Parameters:
2815dce8aebaSBarry Smith + prob - The `PetscDS` object
28166ce16762SMatthew G. Knepley - f    - The field number
28176ce16762SMatthew G. Knepley 
28186ce16762SMatthew G. Knepley   Output Parameter:
28196ce16762SMatthew G. Knepley . off - The offset
28206ce16762SMatthew G. Knepley 
28216ce16762SMatthew G. Knepley   Level: beginner
28226ce16762SMatthew G. Knepley 
2823dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28246ce16762SMatthew G. Knepley @*/
2825d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
2826d71ae5a4SJacob Faibussowitsch {
28276ce16762SMatthew G. Knepley   PetscFunctionBegin;
28286ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28294f572ea9SToby Isaac   PetscAssertPointer(off, 3);
283063a3b9bcSJacob 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);
28319566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
283247e57110SSander Arens   *off = prob->off[f];
28333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28342764a2aaSMatthew G. Knepley }
28352764a2aaSMatthew G. Knepley 
2836194d53e6SMatthew G. Knepley /*@
2837194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
2838194d53e6SMatthew G. Knepley 
283920f4b53cSBarry Smith   Not Collective
2840194d53e6SMatthew G. Knepley 
2841194d53e6SMatthew G. Knepley   Input Parameter:
2842dce8aebaSBarry Smith . prob - The `PetscDS` object
2843194d53e6SMatthew G. Knepley 
2844194d53e6SMatthew G. Knepley   Output Parameter:
2845194d53e6SMatthew G. Knepley . offsets - The offsets
2846194d53e6SMatthew G. Knepley 
2847194d53e6SMatthew G. Knepley   Level: beginner
2848194d53e6SMatthew G. Knepley 
2849dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2850194d53e6SMatthew G. Knepley @*/
2851d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
2852d71ae5a4SJacob Faibussowitsch {
2853194d53e6SMatthew G. Knepley   PetscFunctionBegin;
2854194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28554f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
28569566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2857194d53e6SMatthew G. Knepley   *offsets = prob->off;
28583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2859194d53e6SMatthew G. Knepley }
2860194d53e6SMatthew G. Knepley 
2861194d53e6SMatthew G. Knepley /*@
2862194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
2863194d53e6SMatthew G. Knepley 
286420f4b53cSBarry Smith   Not Collective
2865194d53e6SMatthew G. Knepley 
2866194d53e6SMatthew G. Knepley   Input Parameter:
2867dce8aebaSBarry Smith . prob - The `PetscDS` object
2868194d53e6SMatthew G. Knepley 
2869194d53e6SMatthew G. Knepley   Output Parameter:
2870194d53e6SMatthew G. Knepley . offsets - The offsets
2871194d53e6SMatthew G. Knepley 
2872194d53e6SMatthew G. Knepley   Level: beginner
2873194d53e6SMatthew G. Knepley 
2874dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2875194d53e6SMatthew G. Knepley @*/
2876d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
2877d71ae5a4SJacob Faibussowitsch {
2878194d53e6SMatthew G. Knepley   PetscFunctionBegin;
2879194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28804f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
28819566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2882194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
28833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2884194d53e6SMatthew G. Knepley }
2885194d53e6SMatthew G. Knepley 
28869ee2af8cSMatthew G. Knepley /*@
28879ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
28889ee2af8cSMatthew G. Knepley 
288920f4b53cSBarry Smith   Not Collective
28909ee2af8cSMatthew G. Knepley 
28919ee2af8cSMatthew G. Knepley   Input Parameters:
2892dce8aebaSBarry Smith + ds - The `PetscDS` object
28939ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
28949ee2af8cSMatthew G. Knepley 
28959ee2af8cSMatthew G. Knepley   Output Parameter:
28969ee2af8cSMatthew G. Knepley . offsets - The offsets
28979ee2af8cSMatthew G. Knepley 
28989ee2af8cSMatthew G. Knepley   Level: beginner
28999ee2af8cSMatthew G. Knepley 
2900dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29019ee2af8cSMatthew G. Knepley @*/
2902d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
2903d71ae5a4SJacob Faibussowitsch {
29049ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
29059ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
29064f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
290728b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
290863a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
29099566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
29109ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
29113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29129ee2af8cSMatthew G. Knepley }
29139ee2af8cSMatthew G. Knepley 
29149ee2af8cSMatthew G. Knepley /*@
29159ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
29169ee2af8cSMatthew G. Knepley 
291720f4b53cSBarry Smith   Not Collective
29189ee2af8cSMatthew G. Knepley 
29199ee2af8cSMatthew G. Knepley   Input Parameters:
2920dce8aebaSBarry Smith + ds - The `PetscDS` object
29219ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
29229ee2af8cSMatthew G. Knepley 
29239ee2af8cSMatthew G. Knepley   Output Parameter:
29249ee2af8cSMatthew G. Knepley . offsets - The offsets
29259ee2af8cSMatthew G. Knepley 
29269ee2af8cSMatthew G. Knepley   Level: beginner
29279ee2af8cSMatthew G. Knepley 
2928dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29299ee2af8cSMatthew G. Knepley @*/
2930d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
2931d71ae5a4SJacob Faibussowitsch {
29329ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
29339ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
29344f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
293528b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
293663a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
29379566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
29389ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
29393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29409ee2af8cSMatthew G. Knepley }
29419ee2af8cSMatthew G. Knepley 
294268c9edb9SMatthew G. Knepley /*@C
294368c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
294468c9edb9SMatthew G. Knepley 
294520f4b53cSBarry Smith   Not Collective
294668c9edb9SMatthew G. Knepley 
294768c9edb9SMatthew G. Knepley   Input Parameter:
2948dce8aebaSBarry Smith . prob - The `PetscDS` object
294968c9edb9SMatthew G. Knepley 
2950ef0bb6c7SMatthew G. Knepley   Output Parameter:
2951ce78bad3SBarry Smith . T - The basis function and derivatives tabulation at quadrature points for each field, see `PetscTabulation` for its details
295268c9edb9SMatthew G. Knepley 
295368c9edb9SMatthew G. Knepley   Level: intermediate
295468c9edb9SMatthew G. Knepley 
2955ce78bad3SBarry Smith   Note:
2956ce78bad3SBarry Smith   The tabulation is only valid so long as the `PetscDS` has not be destroyed. There is no `PetscDSRestoreTabulation()` in C.
2957ce78bad3SBarry Smith 
2958ce78bad3SBarry Smith   Fortran Note:
2959ce78bad3SBarry Smith   Use the declaration
2960ce78bad3SBarry Smith .vb
2961ce78bad3SBarry Smith   PetscTabulation, pointer :: tab(:)
2962ce78bad3SBarry Smith .ve
2963ce78bad3SBarry Smith   and access the values using, for example,
2964ce78bad3SBarry Smith .vb
2965ce78bad3SBarry Smith   tab(i)%ptr%K
2966ce78bad3SBarry Smith   tab(i)%ptr%T(j)%ptr
2967ce78bad3SBarry Smith .ve
2968ce78bad3SBarry Smith   where $ i = 1, 2, ..., Nf $ and $ j = 1, 2, ..., tab(i)%ptr%K+1 $.
2969ce78bad3SBarry Smith 
2970ce78bad3SBarry Smith   Use `PetscDSRestoreTabulation()` to restore the array
2971ce78bad3SBarry Smith 
2972ce78bad3SBarry Smith   Developer Note:
2973ce78bad3SBarry Smith   The Fortran language syntax does not directly support arrays of pointers, the '%ptr' notation allows mimicking their use in Fortran.
2974ce78bad3SBarry Smith 
2975dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
297668c9edb9SMatthew G. Knepley @*/
2977ce78bad3SBarry Smith PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[]) PeNS
2978d71ae5a4SJacob Faibussowitsch {
29792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29802764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29814f572ea9SToby Isaac   PetscAssertPointer(T, 2);
29829566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2983ef0bb6c7SMatthew G. Knepley   *T = prob->T;
29843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29852764a2aaSMatthew G. Knepley }
29862764a2aaSMatthew G. Knepley 
298768c9edb9SMatthew G. Knepley /*@C
29884d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
298968c9edb9SMatthew G. Knepley 
299020f4b53cSBarry Smith   Not Collective
299168c9edb9SMatthew G. Knepley 
299268c9edb9SMatthew G. Knepley   Input Parameter:
2993dce8aebaSBarry Smith . prob - The `PetscDS` object
299468c9edb9SMatthew G. Knepley 
2995ef0bb6c7SMatthew G. Knepley   Output Parameter:
2996ce78bad3SBarry Smith . Tf - The basis function and derivative tabulation on each local face at quadrature points for each field
299768c9edb9SMatthew G. Knepley 
299868c9edb9SMatthew G. Knepley   Level: intermediate
299968c9edb9SMatthew G. Knepley 
3000ce78bad3SBarry Smith   Note:
3001ce78bad3SBarry Smith   The tabulation is only valid so long as the `PetscDS` has not be destroyed. There is no `PetscDSRestoreFaceTabulation()` in C.
3002ce78bad3SBarry Smith 
3003dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
300468c9edb9SMatthew G. Knepley @*/
3005d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3006d71ae5a4SJacob Faibussowitsch {
30072764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30082764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30094f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
30109566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3011ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
30123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30132764a2aaSMatthew G. Knepley }
30142764a2aaSMatthew G. Knepley 
3015ce78bad3SBarry Smith PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar *u[], PetscScalar *u_t[], PetscScalar *u_x[])
3016d71ae5a4SJacob Faibussowitsch {
30172764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30182764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30199566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30209371c9d4SSatish Balay   if (u) {
30214f572ea9SToby Isaac     PetscAssertPointer(u, 2);
30229371c9d4SSatish Balay     *u = prob->u;
30239371c9d4SSatish Balay   }
30249371c9d4SSatish Balay   if (u_t) {
30254f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
30269371c9d4SSatish Balay     *u_t = prob->u_t;
30279371c9d4SSatish Balay   }
30289371c9d4SSatish Balay   if (u_x) {
30294f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
30309371c9d4SSatish Balay     *u_x = prob->u_x;
30319371c9d4SSatish Balay   }
30323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30332764a2aaSMatthew G. Knepley }
30342764a2aaSMatthew G. Knepley 
3035ce78bad3SBarry Smith PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar *f0[], PetscScalar *f1[], PetscScalar *g0[], PetscScalar *g1[], PetscScalar *g2[], PetscScalar *g3[])
3036d71ae5a4SJacob Faibussowitsch {
30372764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30382764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30399566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30409371c9d4SSatish Balay   if (f0) {
30414f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
30429371c9d4SSatish Balay     *f0 = prob->f0;
30439371c9d4SSatish Balay   }
30449371c9d4SSatish Balay   if (f1) {
30454f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
30469371c9d4SSatish Balay     *f1 = prob->f1;
30479371c9d4SSatish Balay   }
30489371c9d4SSatish Balay   if (g0) {
30494f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
30509371c9d4SSatish Balay     *g0 = prob->g0;
30519371c9d4SSatish Balay   }
30529371c9d4SSatish Balay   if (g1) {
30534f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
30549371c9d4SSatish Balay     *g1 = prob->g1;
30559371c9d4SSatish Balay   }
30569371c9d4SSatish Balay   if (g2) {
30574f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
30589371c9d4SSatish Balay     *g2 = prob->g2;
30599371c9d4SSatish Balay   }
30609371c9d4SSatish Balay   if (g3) {
30614f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
30629371c9d4SSatish Balay     *g3 = prob->g3;
30639371c9d4SSatish Balay   }
30643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30652764a2aaSMatthew G. Knepley }
30662764a2aaSMatthew G. Knepley 
3067d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3068d71ae5a4SJacob Faibussowitsch {
30692764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30702764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30719566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30729371c9d4SSatish Balay   if (x) {
30734f572ea9SToby Isaac     PetscAssertPointer(x, 2);
30749371c9d4SSatish Balay     *x = prob->x;
30759371c9d4SSatish Balay   }
30769371c9d4SSatish Balay   if (basisReal) {
30774f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
30789371c9d4SSatish Balay     *basisReal = prob->basisReal;
30799371c9d4SSatish Balay   }
30809371c9d4SSatish Balay   if (basisDerReal) {
30814f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
30829371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
30839371c9d4SSatish Balay   }
30849371c9d4SSatish Balay   if (testReal) {
30854f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
30869371c9d4SSatish Balay     *testReal = prob->testReal;
30879371c9d4SSatish Balay   }
30889371c9d4SSatish Balay   if (testDerReal) {
30894f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
30909371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
30919371c9d4SSatish Balay   }
30923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30932764a2aaSMatthew G. Knepley }
30942764a2aaSMatthew G. Knepley 
309558ebd649SToby Isaac /*@C
3096a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
309758ebd649SToby Isaac 
309820f4b53cSBarry Smith   Collective
3099783e2ec8SMatthew G. Knepley 
310058ebd649SToby Isaac   Input Parameters:
3101*2192575eSBarry Smith + ds       - The `PetscDS` object
3102dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3103*2192575eSBarry Smith . name     - The name for the boundary condition
310445480ffeSMatthew G. Knepley . label    - The label defining constrained points
3105dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
310645480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
310758ebd649SToby Isaac . field    - The field to constrain
310845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
310958ebd649SToby Isaac . comps    - An array of constrained component numbers
311058ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3111b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3112b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
311358ebd649SToby Isaac 
31142fe279fdSBarry Smith   Output Parameter:
311560225df5SJacob Faibussowitsch . bd - The boundary number
311645480ffeSMatthew G. Knepley 
311758ebd649SToby Isaac   Options Database Keys:
311858ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
311958ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
312058ebd649SToby Isaac 
3121dce8aebaSBarry Smith   Level: developer
3122dce8aebaSBarry Smith 
312356cf3b9cSMatthew G. Knepley   Note:
3124a4e35b19SJacob Faibussowitsch   Both `bcFunc` and `bcFunc_t` will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, then the calling sequence is\:
3125b44f4de4SBarry Smith .vb
3126b44f4de4SBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3127b44f4de4SBarry Smith .ve
312856cf3b9cSMatthew G. Knepley 
3129a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3130dce8aebaSBarry Smith .vb
313120f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3132dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3133dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3134dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3135dce8aebaSBarry Smith .ve
3136ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
313756cf3b9cSMatthew G. Knepley . Nf           - the number of fields
313856cf3b9cSMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
313956cf3b9cSMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
314056cf3b9cSMatthew G. Knepley . u            - each field evaluated at the current point
314156cf3b9cSMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
314256cf3b9cSMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
314356cf3b9cSMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
314456cf3b9cSMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
314556cf3b9cSMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
314656cf3b9cSMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
314756cf3b9cSMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
314856cf3b9cSMatthew G. Knepley . t            - current time
314956cf3b9cSMatthew G. Knepley . x            - coordinates of the current point
315056cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
315156cf3b9cSMatthew G. Knepley . constants    - constant parameters
315256cf3b9cSMatthew G. Knepley - bcval        - output values at the current point
315356cf3b9cSMatthew G. Knepley 
3154a4e35b19SJacob Faibussowitsch   Notes:
3155a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3156a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3157a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3158a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3159a4e35b19SJacob Faibussowitsch 
3160dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
316158ebd649SToby Isaac @*/
3162d71ae5a4SJacob 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)
3163d71ae5a4SJacob Faibussowitsch {
316445480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
316545480ffeSMatthew G. Knepley   PetscInt    n    = 0;
316645480ffeSMatthew G. Knepley   const char *lname;
316758ebd649SToby Isaac 
316858ebd649SToby Isaac   PetscFunctionBegin;
316958ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3170783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
31714f572ea9SToby Isaac   PetscAssertPointer(name, 3);
317245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
317345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
317445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
317545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3176dce9da9cSMatthew 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);
3177d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3178d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3179d57bb9dbSMatthew G. Knepley     PetscInt  c;
3180d57bb9dbSMatthew G. Knepley 
31819566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
318263a3b9bcSJacob 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);
3183d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
31841dca8a05SBarry 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);
3185d57bb9dbSMatthew G. Knepley     }
3186d57bb9dbSMatthew G. Knepley   }
31879566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
31889566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
31899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
31909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
31919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
31929566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
31939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
31949566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
31959566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
31969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3197f971fd6bSMatthew G. Knepley   b->type   = type;
319845480ffeSMatthew G. Knepley   b->label  = label;
319945480ffeSMatthew G. Knepley   b->Nv     = Nv;
320058ebd649SToby Isaac   b->field  = field;
320145480ffeSMatthew G. Knepley   b->Nc     = Nc;
320258ebd649SToby Isaac   b->func   = bcFunc;
320356cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
320458ebd649SToby Isaac   b->ctx    = ctx;
320545480ffeSMatthew G. Knepley   b->next   = NULL;
320645480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
320745480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
320845480ffeSMatthew G. Knepley   while (head) {
320945480ffeSMatthew G. Knepley     if (!head->next) {
321045480ffeSMatthew G. Knepley       head->next = b;
321145480ffeSMatthew G. Knepley       head       = b;
321245480ffeSMatthew G. Knepley     }
321345480ffeSMatthew G. Knepley     head = head->next;
321445480ffeSMatthew G. Knepley     ++n;
321545480ffeSMatthew G. Knepley   }
32169371c9d4SSatish Balay   if (bd) {
32174f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
32189371c9d4SSatish Balay     *bd = n;
32199371c9d4SSatish Balay   }
32203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
322145480ffeSMatthew G. Knepley }
322245480ffeSMatthew G. Knepley 
3223a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
322445480ffeSMatthew G. Knepley /*@C
3225a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
322645480ffeSMatthew G. Knepley 
322720f4b53cSBarry Smith   Collective
322845480ffeSMatthew G. Knepley 
322945480ffeSMatthew G. Knepley   Input Parameters:
3230dce8aebaSBarry Smith + ds       - The `PetscDS` object
3231dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3232*2192575eSBarry Smith . name     - The boundary condition name
323346091a0eSPierre Jolivet . lname    - The name of the label defining constrained points
3234dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
323545480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
323645480ffeSMatthew G. Knepley . field    - The field to constrain
323745480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
323845480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
323945480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3240b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3241b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
324245480ffeSMatthew G. Knepley 
32432fe279fdSBarry Smith   Output Parameter:
324460225df5SJacob Faibussowitsch . bd - The boundary number
324545480ffeSMatthew G. Knepley 
324645480ffeSMatthew G. Knepley   Options Database Keys:
324745480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
324845480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
324945480ffeSMatthew G. Knepley 
325020f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3251dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3252dce8aebaSBarry Smith .vb
325320f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3254dce8aebaSBarry Smith .ve
3255dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3256dce8aebaSBarry Smith .vb
325720f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3258dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3259dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3260dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3261dce8aebaSBarry Smith .ve
3262ac9d17c7SMatthew G. Knepley + dim          - the coordinate dimension
326345480ffeSMatthew G. Knepley . Nf           - the number of fields
3264b44f4de4SBarry Smith . uOff         - the offset into `u`[] and `u_t`[] for each field
3265b44f4de4SBarry Smith . uOff_x       - the offset into `u_x`[] for each field
326645480ffeSMatthew G. Knepley . u            - each field evaluated at the current point
326745480ffeSMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
326845480ffeSMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
3269b44f4de4SBarry Smith . aOff         - the offset into `a`[] and `a_t`[] for each auxiliary field
3270b44f4de4SBarry Smith . aOff_x       - the offset into `a_x`[] for each auxiliary field
327145480ffeSMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
327245480ffeSMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
327345480ffeSMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
327445480ffeSMatthew G. Knepley . t            - current time
327545480ffeSMatthew G. Knepley . x            - coordinates of the current point
327645480ffeSMatthew G. Knepley . numConstants - number of constant parameters
327745480ffeSMatthew G. Knepley . constants    - constant parameters
327845480ffeSMatthew G. Knepley - bcval        - output values at the current point
327945480ffeSMatthew G. Knepley 
328045480ffeSMatthew G. Knepley   Level: developer
328145480ffeSMatthew G. Knepley 
3282a4e35b19SJacob Faibussowitsch   Notes:
3283a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3284a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3285a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3286a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3287a4e35b19SJacob Faibussowitsch 
3288dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3289dce8aebaSBarry Smith 
3290dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
329145480ffeSMatthew G. Knepley @*/
3292d71ae5a4SJacob 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)
3293d71ae5a4SJacob Faibussowitsch {
329445480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
329545480ffeSMatthew G. Knepley   PetscInt   n    = 0;
329645480ffeSMatthew G. Knepley 
329745480ffeSMatthew G. Knepley   PetscFunctionBegin;
329845480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
329945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
33004f572ea9SToby Isaac   PetscAssertPointer(name, 3);
33014f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
330245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
330345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
330445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
33059566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33069566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33079566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33099566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33109566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
33119566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
33129566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
33139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
331445480ffeSMatthew G. Knepley   b->type   = type;
331545480ffeSMatthew G. Knepley   b->label  = NULL;
331645480ffeSMatthew G. Knepley   b->Nv     = Nv;
331745480ffeSMatthew G. Knepley   b->field  = field;
331845480ffeSMatthew G. Knepley   b->Nc     = Nc;
331945480ffeSMatthew G. Knepley   b->func   = bcFunc;
332045480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
332145480ffeSMatthew G. Knepley   b->ctx    = ctx;
332245480ffeSMatthew G. Knepley   b->next   = NULL;
332345480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
332445480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
332545480ffeSMatthew G. Knepley   while (head) {
332645480ffeSMatthew G. Knepley     if (!head->next) {
332745480ffeSMatthew G. Knepley       head->next = b;
332845480ffeSMatthew G. Knepley       head       = b;
332945480ffeSMatthew G. Knepley     }
333045480ffeSMatthew G. Knepley     head = head->next;
333145480ffeSMatthew G. Knepley     ++n;
333245480ffeSMatthew G. Knepley   }
33339371c9d4SSatish Balay   if (bd) {
33344f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
33359371c9d4SSatish Balay     *bd = n;
33369371c9d4SSatish Balay   }
33373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
333858ebd649SToby Isaac }
333958ebd649SToby Isaac 
3340b67eacb3SMatthew G. Knepley /*@C
3341a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3342b67eacb3SMatthew G. Knepley 
3343b67eacb3SMatthew G. Knepley   Input Parameters:
3344dce8aebaSBarry Smith + ds       - The `PetscDS` object
3345b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3346dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3347b44f4de4SBarry Smith . name     - The boundary condition name
334845480ffeSMatthew G. Knepley . label    - The label defining constrained points
3349dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
335045480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3351b67eacb3SMatthew G. Knepley . field    - The field to constrain
335245480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3353b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3354b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3355b44f4de4SBarry Smith . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or `NULL`
3356b44f4de4SBarry Smith - ctx      - An optional user context for `bcFunc`
3357b67eacb3SMatthew G. Knepley 
3358b67eacb3SMatthew G. Knepley   Level: developer
3359b67eacb3SMatthew G. Knepley 
3360a4e35b19SJacob Faibussowitsch   Notes:
3361a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3362a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3363a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3364a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3365a4e35b19SJacob Faibussowitsch 
3366dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3367dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3368dce8aebaSBarry Smith 
3369dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3370b67eacb3SMatthew G. Knepley @*/
3371d71ae5a4SJacob 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)
3372d71ae5a4SJacob Faibussowitsch {
3373b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3374b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3375b67eacb3SMatthew G. Knepley 
3376b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3377b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3378b67eacb3SMatthew G. Knepley   while (b) {
3379b67eacb3SMatthew G. Knepley     if (n == bd) break;
3380b67eacb3SMatthew G. Knepley     b = b->next;
3381b67eacb3SMatthew G. Knepley     ++n;
3382b67eacb3SMatthew G. Knepley   }
338363a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3384b67eacb3SMatthew G. Knepley   if (name) {
33859566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
33869566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3387b67eacb3SMatthew G. Knepley   }
3388b67eacb3SMatthew G. Knepley   b->type = type;
338945480ffeSMatthew G. Knepley   if (label) {
339045480ffeSMatthew G. Knepley     const char *name;
339145480ffeSMatthew G. Knepley 
339245480ffeSMatthew G. Knepley     b->label = label;
33939566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
33949566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
33959566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
339645480ffeSMatthew G. Knepley   }
339745480ffeSMatthew G. Knepley   if (Nv >= 0) {
339845480ffeSMatthew G. Knepley     b->Nv = Nv;
33999566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
34009566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
34019566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
340245480ffeSMatthew G. Knepley   }
340345480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
340445480ffeSMatthew G. Knepley   if (Nc >= 0) {
340545480ffeSMatthew G. Knepley     b->Nc = Nc;
34069566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
34079566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
34089566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
340945480ffeSMatthew G. Knepley   }
341045480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
341145480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
341245480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
34133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3414b67eacb3SMatthew G. Knepley }
3415b67eacb3SMatthew G. Knepley 
341658ebd649SToby Isaac /*@
3417*2192575eSBarry Smith   PetscDSGetNumBoundary - Get the number of registered boundary conditions
341858ebd649SToby Isaac 
34192fe279fdSBarry Smith   Input Parameter:
3420dce8aebaSBarry Smith . ds - The `PetscDS` object
342158ebd649SToby Isaac 
34222fe279fdSBarry Smith   Output Parameter:
3423*2192575eSBarry Smith . numBd - The number of boundary conditions
342458ebd649SToby Isaac 
342558ebd649SToby Isaac   Level: intermediate
342658ebd649SToby Isaac 
3427dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
342858ebd649SToby Isaac @*/
3429d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3430d71ae5a4SJacob Faibussowitsch {
343158ebd649SToby Isaac   DSBoundary b = ds->boundary;
343258ebd649SToby Isaac 
343358ebd649SToby Isaac   PetscFunctionBegin;
343458ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
34354f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
343658ebd649SToby Isaac   *numBd = 0;
34379371c9d4SSatish Balay   while (b) {
34389371c9d4SSatish Balay     ++(*numBd);
34399371c9d4SSatish Balay     b = b->next;
34409371c9d4SSatish Balay   }
34413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
344258ebd649SToby Isaac }
344358ebd649SToby Isaac 
344458ebd649SToby Isaac /*@C
3445*2192575eSBarry Smith   PetscDSGetBoundary - Gets a boundary condition from the model
344658ebd649SToby Isaac 
344758ebd649SToby Isaac   Input Parameters:
3448dce8aebaSBarry Smith + ds - The `PetscDS` object
3449*2192575eSBarry Smith - bd - The boundary condition number
345058ebd649SToby Isaac 
345158ebd649SToby Isaac   Output Parameters:
3452dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3453dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3454b44f4de4SBarry Smith . name   - The boundary condition name
345545480ffeSMatthew G. Knepley . label  - The label defining constrained points
3456dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
345745480ffeSMatthew G. Knepley . values - An array of ids for constrained points
345858ebd649SToby Isaac . field  - The field to constrain
345945480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
346058ebd649SToby Isaac . comps  - An array of constrained component numbers
346160225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
346260225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
3463b44f4de4SBarry Smith - ctx    - An optional user context for `bcFunc`
346458ebd649SToby Isaac 
346558ebd649SToby Isaac   Options Database Keys:
346658ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
346758ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
346858ebd649SToby Isaac 
346958ebd649SToby Isaac   Level: developer
347058ebd649SToby Isaac 
3471dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
347258ebd649SToby Isaac @*/
3473d71ae5a4SJacob 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)
3474d71ae5a4SJacob Faibussowitsch {
347558ebd649SToby Isaac   DSBoundary b = ds->boundary;
347658ebd649SToby Isaac   PetscInt   n = 0;
347758ebd649SToby Isaac 
347858ebd649SToby Isaac   PetscFunctionBegin;
347958ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
348058ebd649SToby Isaac   while (b) {
348158ebd649SToby Isaac     if (n == bd) break;
348258ebd649SToby Isaac     b = b->next;
348358ebd649SToby Isaac     ++n;
348458ebd649SToby Isaac   }
348563a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
348645480ffeSMatthew G. Knepley   if (wf) {
34874f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
348845480ffeSMatthew G. Knepley     *wf = b->wf;
348945480ffeSMatthew G. Knepley   }
3490f971fd6bSMatthew G. Knepley   if (type) {
34914f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3492f971fd6bSMatthew G. Knepley     *type = b->type;
349358ebd649SToby Isaac   }
349458ebd649SToby Isaac   if (name) {
34954f572ea9SToby Isaac     PetscAssertPointer(name, 5);
349658ebd649SToby Isaac     *name = b->name;
349758ebd649SToby Isaac   }
349845480ffeSMatthew G. Knepley   if (label) {
34994f572ea9SToby Isaac     PetscAssertPointer(label, 6);
350045480ffeSMatthew G. Knepley     *label = b->label;
350145480ffeSMatthew G. Knepley   }
350245480ffeSMatthew G. Knepley   if (Nv) {
35034f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
350445480ffeSMatthew G. Knepley     *Nv = b->Nv;
350545480ffeSMatthew G. Knepley   }
350645480ffeSMatthew G. Knepley   if (values) {
35074f572ea9SToby Isaac     PetscAssertPointer(values, 8);
350845480ffeSMatthew G. Knepley     *values = b->values;
350958ebd649SToby Isaac   }
351058ebd649SToby Isaac   if (field) {
35114f572ea9SToby Isaac     PetscAssertPointer(field, 9);
351258ebd649SToby Isaac     *field = b->field;
351358ebd649SToby Isaac   }
351445480ffeSMatthew G. Knepley   if (Nc) {
35154f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
351645480ffeSMatthew G. Knepley     *Nc = b->Nc;
351758ebd649SToby Isaac   }
351858ebd649SToby Isaac   if (comps) {
35194f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
352058ebd649SToby Isaac     *comps = b->comps;
352158ebd649SToby Isaac   }
352258ebd649SToby Isaac   if (func) {
35234f572ea9SToby Isaac     PetscAssertPointer(func, 12);
352458ebd649SToby Isaac     *func = b->func;
352558ebd649SToby Isaac   }
352656cf3b9cSMatthew G. Knepley   if (func_t) {
35274f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
352856cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
352956cf3b9cSMatthew G. Knepley   }
353058ebd649SToby Isaac   if (ctx) {
35314f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
353258ebd649SToby Isaac     *ctx = b->ctx;
353358ebd649SToby Isaac   }
35343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
353558ebd649SToby Isaac }
353658ebd649SToby Isaac 
353710af620dSMatthew G. Knepley /*@
353810af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
353910af620dSMatthew G. Knepley 
354010af620dSMatthew G. Knepley   Not Collective
354110af620dSMatthew G. Knepley 
354210af620dSMatthew G. Knepley   Input Parameters:
354310af620dSMatthew G. Knepley + ds - The source `PetscDS` object
354410af620dSMatthew G. Knepley - dm - The `DM` holding labels
354510af620dSMatthew G. Knepley 
354610af620dSMatthew G. Knepley   Level: intermediate
354710af620dSMatthew G. Knepley 
354810af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
354910af620dSMatthew G. Knepley @*/
355010af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
355110af620dSMatthew G. Knepley {
355210af620dSMatthew G. Knepley   DSBoundary b;
355310af620dSMatthew G. Knepley 
355410af620dSMatthew G. Knepley   PetscFunctionBegin;
355510af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
355610af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
355710af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
355810af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
355910af620dSMatthew G. Knepley   }
356010af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
356110af620dSMatthew G. Knepley }
356210af620dSMatthew G. Knepley 
3563d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3564d71ae5a4SJacob Faibussowitsch {
356545480ffeSMatthew G. Knepley   PetscFunctionBegin;
35669566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
35679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
35689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
35699566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
35709566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
357145480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
357245480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
357345480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
35749566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
35759566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
357645480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
357745480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
35789566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
35799566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
358045480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
358145480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
358245480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
35833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
358445480ffeSMatthew G. Knepley }
358545480ffeSMatthew G. Knepley 
35869252d075SMatthew G. Knepley /*@
3587*2192575eSBarry Smith   PetscDSCopyBoundary - Copy all boundary condition objects to the new `PetscDS`
35889252d075SMatthew G. Knepley 
358920f4b53cSBarry Smith   Not Collective
35909252d075SMatthew G. Knepley 
359136951cb5SMatthew G. Knepley   Input Parameters:
3592dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3593dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
3594b44f4de4SBarry Smith - fields    - The selected fields, or `NULL` for all fields
35959252d075SMatthew G. Knepley 
35969252d075SMatthew G. Knepley   Output Parameter:
3597dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
35989252d075SMatthew G. Knepley 
35999252d075SMatthew G. Knepley   Level: intermediate
36009252d075SMatthew G. Knepley 
3601dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
36029252d075SMatthew G. Knepley @*/
3603d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3604d71ae5a4SJacob Faibussowitsch {
360545480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3606dff059c6SToby Isaac 
3607dff059c6SToby Isaac   PetscFunctionBegin;
360836951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
360936951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
36103ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
36119566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
3612f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
361336951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3614dff059c6SToby Isaac     DSBoundary bNew;
361536951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3616dff059c6SToby Isaac 
361736951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
361836951cb5SMatthew G. Knepley       PetscInt f;
361936951cb5SMatthew G. Knepley 
36209371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
36219371c9d4SSatish Balay         if (b->field == fields[f]) break;
362236951cb5SMatthew G. Knepley       if (f == numFields) continue;
362336951cb5SMatthew G. Knepley       fieldNew = f;
362436951cb5SMatthew G. Knepley     }
36259566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
362636951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3627dff059c6SToby Isaac     *lastnext   = bNew;
3628f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
3629dff059c6SToby Isaac   }
36303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3631dff059c6SToby Isaac }
3632dff059c6SToby Isaac 
36336c1eb96dSMatthew G. Knepley /*@
3634dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
363545480ffeSMatthew G. Knepley 
363620f4b53cSBarry Smith   Not Collective
363745480ffeSMatthew G. Knepley 
363845480ffeSMatthew G. Knepley   Input Parameter:
3639dce8aebaSBarry Smith . ds - The `PetscDS` object
364045480ffeSMatthew G. Knepley 
364145480ffeSMatthew G. Knepley   Level: intermediate
364245480ffeSMatthew G. Knepley 
3643dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
364445480ffeSMatthew G. Knepley @*/
3645d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3646d71ae5a4SJacob Faibussowitsch {
364745480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
364845480ffeSMatthew G. Knepley 
364945480ffeSMatthew G. Knepley   PetscFunctionBegin;
365045480ffeSMatthew G. Knepley   while (next) {
365145480ffeSMatthew G. Knepley     DSBoundary b = next;
365245480ffeSMatthew G. Knepley 
365345480ffeSMatthew G. Knepley     next = b->next;
36549566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
36559566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36569566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36579566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36589566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36599566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
366045480ffeSMatthew G. Knepley   }
36613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
366245480ffeSMatthew G. Knepley }
366345480ffeSMatthew G. Knepley 
366445480ffeSMatthew G. Knepley /*@
3665*2192575eSBarry Smith   PetscDSSelectDiscretizations - Copy discretizations to the new `PetscDS` with different field layout
36666c1eb96dSMatthew G. Knepley 
366720f4b53cSBarry Smith   Not Collective
36686c1eb96dSMatthew G. Knepley 
3669d8d19677SJose E. Roman   Input Parameters:
3670dce8aebaSBarry Smith + prob      - The `PetscDS` object
36716c1eb96dSMatthew G. Knepley . numFields - Number of new fields
3672bb4b53efSMatthew G. Knepley . fields    - Old field number for each new field
3673bb4b53efSMatthew G. Knepley . minDegree - Minimum degree for a discretization, or `PETSC_DETERMINE` for no limit
3674bb4b53efSMatthew G. Knepley - maxDegree - Maximum degree for a discretization, or `PETSC_DETERMINE` for no limit
36756c1eb96dSMatthew G. Knepley 
36766c1eb96dSMatthew G. Knepley   Output Parameter:
3677dce8aebaSBarry Smith . newprob - The `PetscDS` copy
36786c1eb96dSMatthew G. Knepley 
36796c1eb96dSMatthew G. Knepley   Level: intermediate
36806c1eb96dSMatthew G. Knepley 
3681dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
36826c1eb96dSMatthew G. Knepley @*/
3683bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscInt minDegree, PetscInt maxDegree, PetscDS newprob)
3684d71ae5a4SJacob Faibussowitsch {
36856c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
36866c1eb96dSMatthew G. Knepley 
36876c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
36886c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
36894f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
3690bb4b53efSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 6);
36919566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
36929566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
369345480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
36946c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
36956c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
36966c1eb96dSMatthew G. Knepley     PetscObject    disc;
3697bb4b53efSMatthew G. Knepley     PetscClassId   id;
36986c1eb96dSMatthew G. Knepley 
36996c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
37009566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
3701bb4b53efSMatthew G. Knepley     PetscCallContinue(PetscObjectGetClassId(disc, &id));
3702bb4b53efSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
3703bb4b53efSMatthew G. Knepley       PetscFE fe;
3704bb4b53efSMatthew G. Knepley 
3705bb4b53efSMatthew G. Knepley       PetscCall(PetscFELimitDegree((PetscFE)disc, minDegree, maxDegree, &fe));
3706bb4b53efSMatthew G. Knepley       PetscCall(PetscDSSetDiscretization(newprob, fn, (PetscObject)fe));
3707bb4b53efSMatthew G. Knepley       PetscCall(PetscFEDestroy(&fe));
3708bb4b53efSMatthew G. Knepley     } else {
37099566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
37106c1eb96dSMatthew G. Knepley     }
3711bb4b53efSMatthew G. Knepley   }
37123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37136c1eb96dSMatthew G. Knepley }
37146c1eb96dSMatthew G. Knepley 
37156c1eb96dSMatthew G. Knepley /*@
3716*2192575eSBarry Smith   PetscDSSelectEquations - Copy pointwise function pointers to the new `PetscDS` with different field layout
37179252d075SMatthew G. Knepley 
371820f4b53cSBarry Smith   Not Collective
37199252d075SMatthew G. Knepley 
3720d8d19677SJose E. Roman   Input Parameters:
3721dce8aebaSBarry Smith + prob      - The `PetscDS` object
37229252d075SMatthew G. Knepley . numFields - Number of new fields
37239252d075SMatthew G. Knepley - fields    - Old field number for each new field
37249252d075SMatthew G. Knepley 
37259252d075SMatthew G. Knepley   Output Parameter:
3726dce8aebaSBarry Smith . newprob - The `PetscDS` copy
37279252d075SMatthew G. Knepley 
37289252d075SMatthew G. Knepley   Level: intermediate
37299252d075SMatthew G. Knepley 
3730dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37319252d075SMatthew G. Knepley @*/
3732d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3733d71ae5a4SJacob Faibussowitsch {
37349252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
37359252d075SMatthew G. Knepley 
37369252d075SMatthew G. Knepley   PetscFunctionBegin;
37379252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
37384f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
37399252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
37409566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
37419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
374263a3b9bcSJacob 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);
37439252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
37449252d075SMatthew G. Knepley     const PetscInt  f = fields ? fields[fn] : fn;
3745*2192575eSBarry Smith     PetscPointFn   *obj;
3746*2192575eSBarry Smith     PetscPointFn   *f0, *f1;
3747*2192575eSBarry Smith     PetscBdPointFn *f0Bd, *f1Bd;
3748*2192575eSBarry Smith     PetscRiemannFn *r;
37499252d075SMatthew G. Knepley 
3750c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
37519566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
37529566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
37539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
37549566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
37559566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
37569566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
37579566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
37589566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
37599252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
37609252d075SMatthew G. Knepley       const PetscInt     g = fields ? fields[gn] : gn;
3761*2192575eSBarry Smith       PetscPointJacFn   *g0, *g1, *g2, *g3;
3762*2192575eSBarry Smith       PetscPointJacFn   *g0p, *g1p, *g2p, *g3p;
3763*2192575eSBarry Smith       PetscBdPointJacFn *g0Bd, *g1Bd, *g2Bd, *g3Bd;
37649252d075SMatthew G. Knepley 
3765c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
37669566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
37679566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
37689566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
37699566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
37709566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
37719566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
37729252d075SMatthew G. Knepley     }
37739252d075SMatthew G. Knepley   }
37743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37759252d075SMatthew G. Knepley }
37769252d075SMatthew G. Knepley 
3777da51fcedSMatthew G. Knepley /*@
3778dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3779da51fcedSMatthew G. Knepley 
378020f4b53cSBarry Smith   Not Collective
3781da51fcedSMatthew G. Knepley 
3782da51fcedSMatthew G. Knepley   Input Parameter:
3783dce8aebaSBarry Smith . prob - The `PetscDS` object
3784da51fcedSMatthew G. Knepley 
3785da51fcedSMatthew G. Knepley   Output Parameter:
3786dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3787da51fcedSMatthew G. Knepley 
3788da51fcedSMatthew G. Knepley   Level: intermediate
3789da51fcedSMatthew G. Knepley 
3790dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3791da51fcedSMatthew G. Knepley @*/
3792d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3793d71ae5a4SJacob Faibussowitsch {
3794b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
37959252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3796da51fcedSMatthew G. Knepley 
3797da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3798da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3799da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
38009566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38019566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
380263a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
38039566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
38049566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
38059566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
38063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38079252d075SMatthew G. Knepley }
380845480ffeSMatthew G. Knepley 
38099252d075SMatthew G. Knepley /*@
3810*2192575eSBarry Smith   PetscDSCopyConstants - Copy all constants set with `PetscDSSetConstants()` to another `PetscDS`
3811da51fcedSMatthew G. Knepley 
381220f4b53cSBarry Smith   Not Collective
38139252d075SMatthew G. Knepley 
38149252d075SMatthew G. Knepley   Input Parameter:
3815dce8aebaSBarry Smith . prob - The `PetscDS` object
38169252d075SMatthew G. Knepley 
38179252d075SMatthew G. Knepley   Output Parameter:
3818dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38199252d075SMatthew G. Knepley 
38209252d075SMatthew G. Knepley   Level: intermediate
38219252d075SMatthew G. Knepley 
3822dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38239252d075SMatthew G. Knepley @*/
3824d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3825d71ae5a4SJacob Faibussowitsch {
38269252d075SMatthew G. Knepley   PetscInt           Nc;
38279252d075SMatthew G. Knepley   const PetscScalar *constants;
38289252d075SMatthew G. Knepley 
38299252d075SMatthew G. Knepley   PetscFunctionBegin;
38309252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
38319252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
38329566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
38339566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
38343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3835da51fcedSMatthew G. Knepley }
3836da51fcedSMatthew G. Knepley 
383745480ffeSMatthew G. Knepley /*@
3838*2192575eSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions set with `PetscDSSetExactSolution()` and `PetscDSSetExactSolutionTimeDerivative()` to another `PetscDS`
383945480ffeSMatthew G. Knepley 
384020f4b53cSBarry Smith   Not Collective
384145480ffeSMatthew G. Knepley 
384245480ffeSMatthew G. Knepley   Input Parameter:
3843dce8aebaSBarry Smith . ds - The `PetscDS` object
384445480ffeSMatthew G. Knepley 
384545480ffeSMatthew G. Knepley   Output Parameter:
3846dce8aebaSBarry Smith . newds - The `PetscDS` copy
384745480ffeSMatthew G. Knepley 
384845480ffeSMatthew G. Knepley   Level: intermediate
384945480ffeSMatthew G. Knepley 
3850342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyBounds()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
385145480ffeSMatthew G. Knepley @*/
3852d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
3853d71ae5a4SJacob Faibussowitsch {
38548434afd1SBarry Smith   PetscSimplePointFn *sol;
385545480ffeSMatthew G. Knepley   void               *ctx;
385645480ffeSMatthew G. Knepley   PetscInt            Nf, f;
385745480ffeSMatthew G. Knepley 
385845480ffeSMatthew G. Knepley   PetscFunctionBegin;
385945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
386045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
38619566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
386245480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
38639566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
38649566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
38659566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
38669566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
386745480ffeSMatthew G. Knepley   }
38683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
386945480ffeSMatthew G. Knepley }
387045480ffeSMatthew G. Knepley 
3871342bd5aaSMatthew G. Knepley /*@
3872*2192575eSBarry Smith   PetscDSCopyBounds - Copy lower and upper solution bounds set with `PetscDSSetLowerBound()` and `PetscDSSetLowerBound()` to another `PetscDS`
3873342bd5aaSMatthew G. Knepley 
3874342bd5aaSMatthew G. Knepley   Not Collective
3875342bd5aaSMatthew G. Knepley 
3876342bd5aaSMatthew G. Knepley   Input Parameter:
3877342bd5aaSMatthew G. Knepley . ds - The `PetscDS` object
3878342bd5aaSMatthew G. Knepley 
3879342bd5aaSMatthew G. Knepley   Output Parameter:
3880342bd5aaSMatthew G. Knepley . newds - The `PetscDS` copy
3881342bd5aaSMatthew G. Knepley 
3882342bd5aaSMatthew G. Knepley   Level: intermediate
3883342bd5aaSMatthew G. Knepley 
3884342bd5aaSMatthew G. Knepley .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSCopyExactSolutions()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3885342bd5aaSMatthew G. Knepley @*/
3886342bd5aaSMatthew G. Knepley PetscErrorCode PetscDSCopyBounds(PetscDS ds, PetscDS newds)
3887342bd5aaSMatthew G. Knepley {
3888342bd5aaSMatthew G. Knepley   PetscSimplePointFn *bound;
3889342bd5aaSMatthew G. Knepley   void               *ctx;
3890342bd5aaSMatthew G. Knepley   PetscInt            Nf, f;
3891342bd5aaSMatthew G. Knepley 
3892342bd5aaSMatthew G. Knepley   PetscFunctionBegin;
3893342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3894342bd5aaSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
3895342bd5aaSMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
3896342bd5aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
3897342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetLowerBound(ds, f, &bound, &ctx));
3898342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetLowerBound(newds, f, bound, ctx));
3899342bd5aaSMatthew G. Knepley     PetscCall(PetscDSGetUpperBound(ds, f, &bound, &ctx));
3900342bd5aaSMatthew G. Knepley     PetscCall(PetscDSSetUpperBound(newds, f, bound, ctx));
3901342bd5aaSMatthew G. Knepley   }
3902342bd5aaSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
3903342bd5aaSMatthew G. Knepley }
3904342bd5aaSMatthew G. Knepley 
3905bb4b53efSMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, PetscInt minDegree, PetscInt maxDegree, DM dmNew, PetscDS dsNew)
390607218a29SMatthew G. Knepley {
390707218a29SMatthew G. Knepley   DSBoundary b;
390807218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
390907218a29SMatthew G. Knepley   PetscBool  isCohesive;
391007218a29SMatthew G. Knepley   void      *ctx;
391107218a29SMatthew G. Knepley 
391207218a29SMatthew G. Knepley   PetscFunctionBegin;
391307218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
391407218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
3915342bd5aaSMatthew G. Knepley   PetscCall(PetscDSCopyBounds(ds, dsNew));
3916bb4b53efSMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, minDegree, maxDegree, dsNew));
391707218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
391807218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
391907218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
392007218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
392107218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
392207218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
392307218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
392407218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
392507218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
392607218a29SMatthew G. Knepley   }
392707218a29SMatthew G. Knepley   if (Nf) {
392807218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
392907218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
393007218a29SMatthew G. Knepley   }
393107218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
393207218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
393307218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
393407218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
393507218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
393607218a29SMatthew G. Knepley   }
393707218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
393807218a29SMatthew G. Knepley }
393907218a29SMatthew G. Knepley 
3940d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
3941d71ae5a4SJacob Faibussowitsch {
3942df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
3943b1353e8eSMatthew G. Knepley 
3944b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
3945b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39464f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
39479371c9d4SSatish Balay   if (height == 0) {
39489371c9d4SSatish Balay     *subprob = prob;
39493ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
39509371c9d4SSatish Balay   }
39519566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39529566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
395363a3b9bcSJacob 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);
39549566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
3955df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
3956b1353e8eSMatthew G. Knepley     PetscInt cdim;
3957b1353e8eSMatthew G. Knepley 
39589566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
39599566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
39609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
3961b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
3962b1353e8eSMatthew G. Knepley       PetscFE      subfe;
3963b1353e8eSMatthew G. Knepley       PetscObject  obj;
3964b1353e8eSMatthew G. Knepley       PetscClassId id;
3965b1353e8eSMatthew G. Knepley 
39669566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
39679566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
39689566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
396963a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
39709566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
3971b1353e8eSMatthew G. Knepley     }
3972b1353e8eSMatthew G. Knepley   }
3973df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
39743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3975b1353e8eSMatthew G. Knepley }
3976b1353e8eSMatthew G. Knepley 
39774366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
39784366bac7SMatthew G. Knepley {
39794366bac7SMatthew G. Knepley   IS              permIS;
39804366bac7SMatthew G. Knepley   PetscQuadrature quad;
39814366bac7SMatthew G. Knepley   DMPolytopeType  ct;
39824366bac7SMatthew G. Knepley   const PetscInt *perm;
39834366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
39844366bac7SMatthew G. Knepley 
39854366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
39864366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
39874366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
39884366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
39894366bac7SMatthew G. Knepley   PetscCheck(q >= 0 && q < Nq, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Quadrature point %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", q, Nq);
399085036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
39914366bac7SMatthew G. Knepley   PetscCheck(ornt >= -Na && ornt < Na, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Orientation %" PetscInt_FMT " of %s is not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", ornt, DMPolytopeTypes[ct], -Na, Na);
39924366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
39934366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
39944366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
39954366bac7SMatthew G. Knepley   *qperm = perm[q];
39964366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
39974366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
39984366bac7SMatthew G. Knepley }
39994366bac7SMatthew G. Knepley 
4000d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4001d71ae5a4SJacob Faibussowitsch {
4002c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4003c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4004c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4005c7bd5f0bSMatthew G. Knepley 
4006c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4007c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
40084f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4009665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
40109566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
401163a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
40129566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4013665f567fSMatthew G. Knepley   if (obj) {
40149566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4015665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4016665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4017665f567fSMatthew G. Knepley   }
40183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4019c7bd5f0bSMatthew G. Knepley }
4020c7bd5f0bSMatthew G. Knepley 
4021d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4022d71ae5a4SJacob Faibussowitsch {
40232764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40249566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
40253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40262764a2aaSMatthew G. Knepley }
40272764a2aaSMatthew G. Knepley 
4028d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4029d71ae5a4SJacob Faibussowitsch {
40302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40316528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
40326528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
40336528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
40346528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
40353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40362764a2aaSMatthew G. Knepley }
40372764a2aaSMatthew G. Knepley 
40382764a2aaSMatthew G. Knepley /*MC
40392764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
40402764a2aaSMatthew G. Knepley 
40412764a2aaSMatthew G. Knepley   Level: intermediate
40422764a2aaSMatthew G. Knepley 
4043db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
40442764a2aaSMatthew G. Knepley M*/
40452764a2aaSMatthew G. Knepley 
4046d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4047d71ae5a4SJacob Faibussowitsch {
40482764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
40492764a2aaSMatthew G. Knepley 
40502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40516528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
40524dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
40536528b96dSMatthew G. Knepley   ds->data = b;
40542764a2aaSMatthew G. Knepley 
40559566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
40563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40572764a2aaSMatthew G. Knepley }
4058